Skip to content

Commit

Permalink
feat: Add managed_storage_configuration block to aws_ecs_cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
acwwat committed Jun 12, 2024
1 parent 5dc00d1 commit ecbc4ff
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .changelog/37932.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_ecs_cluster: Add `configuration.managed_storage_configuration` argument
```
62 changes: 62 additions & 0 deletions internal/service/ecs/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,23 @@ func ResourceCluster() *schema.Resource {
},
},
},
"managed_storage_configuration": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"fargate_ephemeral_storage_kms_key_id": {
Type: schema.TypeString,
Optional: true,
},
names.AttrKMSKeyID: {
Type: schema.TypeString,
Optional: true,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -526,6 +543,11 @@ func flattenClusterConfiguration(apiObject *ecs.ClusterConfiguration) []interfac
if apiObject.ExecuteCommandConfiguration != nil {
tfMap["execute_command_configuration"] = flattenClusterConfigurationExecuteCommandConfiguration(apiObject.ExecuteCommandConfiguration)
}

if apiObject.ManagedStorageConfiguration != nil {
tfMap["managed_storage_configuration"] = flattenClusterConfigurationManagedStorageConfiguration(apiObject.ManagedStorageConfiguration)
}

return []interface{}{tfMap}
}

Expand Down Expand Up @@ -576,6 +598,24 @@ func flattenClusterConfigurationExecuteCommandConfigurationLogConfiguration(apiO
return []interface{}{tfMap}
}

func flattenClusterConfigurationManagedStorageConfiguration(apiObject *ecs.ManagedStorageConfiguration) []interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if apiObject.FargateEphemeralStorageKmsKeyId != nil {
tfMap["fargate_ephemeral_storage_kms_key_id"] = aws.StringValue(apiObject.FargateEphemeralStorageKmsKeyId)
}

if apiObject.KmsKeyId != nil {
tfMap[names.AttrKMSKeyID] = aws.StringValue(apiObject.KmsKeyId)
}

return []interface{}{tfMap}
}

func expandClusterConfiguration(nc []interface{}) *ecs.ClusterConfiguration {
if len(nc) == 0 || nc[0] == nil {
return &ecs.ClusterConfiguration{}
Expand All @@ -587,6 +627,10 @@ func expandClusterConfiguration(nc []interface{}) *ecs.ClusterConfiguration {
config.ExecuteCommandConfiguration = expandClusterConfigurationExecuteCommandConfiguration(v)
}

if v, ok := raw["managed_storage_configuration"].([]interface{}); ok && len(v) > 0 {
config.ManagedStorageConfiguration = expandClusterConfigurationManagedStorageConfiguration(v)
}

return config
}

Expand Down Expand Up @@ -642,3 +686,21 @@ func expandClusterConfigurationExecuteCommandLogConfiguration(nc []interface{})

return config
}

func expandClusterConfigurationManagedStorageConfiguration(nc []interface{}) *ecs.ManagedStorageConfiguration {
if len(nc) == 0 || nc[0] == nil {
return &ecs.ManagedStorageConfiguration{}
}
raw := nc[0].(map[string]interface{})

config := &ecs.ManagedStorageConfiguration{}
if v, ok := raw["fargate_ephemeral_storage_kms_key_id"].(string); ok && v != "" {
config.FargateEphemeralStorageKmsKeyId = aws.String(v)
}

if v, ok := raw[names.AttrKMSKeyID].(string); ok && v != "" {
config.KmsKeyId = aws.String(v)
}

return config
}
139 changes: 139 additions & 0 deletions internal/service/ecs/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,54 @@ func TestAccECSCluster_configuration(t *testing.T) {
})
}

func TestAccECSCluster_managedStorageConfiguration(t *testing.T) {
ctx := acctest.Context(t)
var cluster1 ecs.Cluster
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_ecs_cluster.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.ECSServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckClusterDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccClusterConfig_managedStorageConfiguration(rName, "aws_kms_key.test.arn", "null"),
Check: resource.ComposeTestCheckFunc(
testAccCheckClusterExists(ctx, resourceName, &cluster1),
resource.TestCheckResourceAttr(resourceName, "configuration.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "configuration.0.managed_storage_configuration.#", acctest.Ct1),
resource.TestCheckResourceAttrPair(resourceName, "configuration.0.managed_storage_configuration.0.fargate_ephemeral_storage_kms_key_id", "aws_kms_key.test", names.AttrARN),
resource.TestCheckResourceAttr(resourceName, "configuration.0.managed_storage_configuration.0.kms_key_id", ""),
),
},
{
ResourceName: resourceName,
ImportStateId: rName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccClusterConfig_managedStorageConfiguration(rName, "null", "aws_kms_key.test.arn"),
Check: resource.ComposeTestCheckFunc(
testAccCheckClusterExists(ctx, resourceName, &cluster1),
resource.TestCheckResourceAttr(resourceName, "configuration.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "configuration.0.managed_storage_configuration.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "configuration.0.managed_storage_configuration.0.fargate_ephemeral_storage_kms_key_id", ""),
resource.TestCheckResourceAttrPair(resourceName, "configuration.0.managed_storage_configuration.0.kms_key_id", "aws_kms_key.test", names.AttrARN),
),
},
{
ResourceName: resourceName,
ImportStateId: rName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckClusterDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).ECSConn(ctx)
Expand Down Expand Up @@ -408,3 +456,94 @@ resource "aws_ecs_cluster" "test" {
}
`, rName, enable)
}

func testAccClusterConfig_managedStorageConfiguration(rName, fargateEphemeralStorageKmsKeyId, kmsKeyId string) string {
return fmt.Sprintf(`
data "aws_caller_identity" "current" {}
resource "aws_kms_key" "test" {
description = %[1]q
deletion_window_in_days = 7
}
resource "aws_kms_key_policy" "test" {
key_id = aws_kms_key.test.id
policy = jsonencode({
Id = "ECSClusterFargatePolicy"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
"AWS" : "*"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow generate data key access for Fargate tasks."
Effect = "Allow"
Principal = {
Service = "fargate.amazonaws.com"
}
Action = [
"kms:GenerateDataKeyWithoutPlaintext"
]
Condition = {
StringEquals = {
"kms:EncryptionContext:aws:ecs:clusterAccount" = [
data.aws_caller_identity.current.account_id
]
"kms:EncryptionContext:aws:ecs:clusterName" = [
%[1]q
]
}
}
Resource = "*"
},
{
Sid = "Allow grant creation permission for Fargate tasks."
Effect = "Allow"
Principal = {
Service = "fargate.amazonaws.com"
}
Action = [
"kms:CreateGrant"
]
Condition = {
StringEquals = {
"kms:EncryptionContext:aws:ecs:clusterAccount" = [
data.aws_caller_identity.current.account_id
]
"kms:EncryptionContext:aws:ecs:clusterName" = [
%[1]q
]
}
"ForAllValues:StringEquals" = {
"kms:GrantOperations" = [
"Decrypt"
]
}
}
Resource = "*"
}
]
Version = "2012-10-17"
})
}
resource "aws_ecs_cluster" "test" {
name = %[1]q
configuration {
managed_storage_configuration {
fargate_ephemeral_storage_kms_key_id = %[2]s
kms_key_id = %[3]s
}
}
depends_on = [
aws_kms_key_policy.test
]
}
`, rName, fargateEphemeralStorageKmsKeyId, kmsKeyId)
}
Loading

0 comments on commit ecbc4ff

Please sign in to comment.