diff --git a/README.md b/README.md index 8e20fbc0..4137e047 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ No resources. | [create\_task\_exec\_policy](#input\_create\_task\_exec\_policy) | Determines whether the ECS task definition IAM policy should be created. This includes permissions included in AmazonECSTaskExecutionRolePolicy as well as access to secrets and SSM parameters | `bool` | `true` | no | | [default\_capacity\_provider\_use\_fargate](#input\_default\_capacity\_provider\_use\_fargate) | Determines whether to use Fargate or autoscaling for default capacity provider strategy | `bool` | `true` | no | | [fargate\_capacity\_providers](#input\_fargate\_capacity\_providers) | Map of Fargate capacity provider definitions to use for the cluster | `any` | `{}` | no | +| [managed\_storage\_configuration](#input\_managed\_storage\_configuration) | Configuration for the managed storage | `any` | `{}` | no | | [services](#input\_services) | Map of service definitions to create | `any` | `{}` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | | [task\_exec\_iam\_role\_description](#input\_task\_exec\_iam\_role\_description) | Description of the role | `string` | `null` | no | diff --git a/examples/fargate/README.md b/examples/fargate/README.md index 49d4697d..39a5ad5c 100644 --- a/examples/fargate/README.md +++ b/examples/fargate/README.md @@ -43,12 +43,14 @@ Note that this example may create resources which will incur monetary charges on | [ecs\_cluster](#module\_ecs\_cluster) | ../../modules/cluster | n/a | | [ecs\_service](#module\_ecs\_service) | ../../modules/service | n/a | | [ecs\_task\_definition](#module\_ecs\_task\_definition) | ../../modules/service | n/a | +| [tls\_role](#module\_tls\_role) | terraform-aws-modules/iam/aws//modules/iam-assumable-role | 5.41.0 | | [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | ## Resources | Name | Type | |------|------| +| [aws_acmpca_certificate_authority.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acmpca_certificate_authority) | resource | | [aws_service_discovery_http_namespace.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/service_discovery_http_namespace) | resource | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | | [aws_ssm_parameter.fluentbit](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source | diff --git a/examples/fargate/main.tf b/examples/fargate/main.tf index 7cae2e0c..69a6d2e5 100644 --- a/examples/fargate/main.tf +++ b/examples/fargate/main.tf @@ -140,6 +140,13 @@ module "ecs_service" { } port_name = local.container_name discovery_name = local.container_name + + tls = { + role_arn = module.tls_role.iam_role_arn + issuer_cert_authority = { + aws_pca_authority_arn = aws_acmpca_certificate_authority.this.arn + } + } } } @@ -331,3 +338,44 @@ module "vpc" { tags = local.tags } + +module "tls_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role" + version = "5.41.0" + + create_role = true + + role_name = "ServiceRoleForECSConnectTLS" + role_description = "ECS service role to access Private CA for TLS Service Connect" + role_requires_mfa = false + + custom_role_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity"] + + trusted_role_services = ["ecs.amazonaws.com", "ecs-tasks.amazonaws.com"] + + tags = local.tags +} + +resource "aws_acmpca_certificate_authority" "this" { + enabled = true + + usage_mode = "SHORT_LIVED_CERTIFICATE" + type = "ROOT" + + certificate_authority_configuration { + key_algorithm = "EC_secp384r1" + signing_algorithm = "SHA512WITHECDSA" + + subject { + common_name = "example.com" + } + } + + revocation_configuration { + ocsp_configuration { + enabled = false + } + } + + tags = local.tags +} diff --git a/main.tf b/main.tf index 5e380de7..98e23fc9 100644 --- a/main.tf +++ b/main.tf @@ -12,7 +12,7 @@ module "cluster" { cluster_configuration = var.cluster_configuration cluster_settings = var.cluster_settings cluster_service_connect_defaults = var.cluster_service_connect_defaults - + managed_storage_configuration = var.managed_storage_configuration # Cluster Cloudwatch log group create_cloudwatch_log_group = var.create_cloudwatch_log_group cloudwatch_log_group_name = var.cloudwatch_log_group_name diff --git a/modules/cluster/README.md b/modules/cluster/README.md index 282943b5..5d575fba 100644 --- a/modules/cluster/README.md +++ b/modules/cluster/README.md @@ -181,6 +181,7 @@ No modules. | [create\_task\_exec\_policy](#input\_create\_task\_exec\_policy) | Determines whether the ECS task definition IAM policy should be created. This includes permissions included in AmazonECSTaskExecutionRolePolicy as well as access to secrets and SSM parameters | `bool` | `true` | no | | [default\_capacity\_provider\_use\_fargate](#input\_default\_capacity\_provider\_use\_fargate) | Determines whether to use Fargate or autoscaling for default capacity provider strategy | `bool` | `true` | no | | [fargate\_capacity\_providers](#input\_fargate\_capacity\_providers) | Map of Fargate capacity provider definitions to use for the cluster | `any` | `{}` | no | +| [managed\_storage\_configuration](#input\_managed\_storage\_configuration) | Configuration for the managed storage | `any` | `{}` | no | | [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no | | [task\_exec\_iam\_role\_description](#input\_task\_exec\_iam\_role\_description) | Description of the role | `string` | `null` | no | | [task\_exec\_iam\_role\_name](#input\_task\_exec\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no | diff --git a/modules/cluster/main.tf b/modules/cluster/main.tf index cecf7e44..4146e2e4 100644 --- a/modules/cluster/main.tf +++ b/modules/cluster/main.tf @@ -40,6 +40,15 @@ resource "aws_ecs_cluster" "this" { } } } + + dynamic "managed_storage_configuration" { + for_each = try([var.managed_storage_configuration], []) + + content { + fargate_ephemeral_storage_kms_key_id = try(managed_storage_configuration.value.fargate_ephemeral_storage_kms_key_id, null) + kms_key_id = try(managed_storage_configuration.value.kms_key_id, null) + } + } } } @@ -67,6 +76,15 @@ resource "aws_ecs_cluster" "this" { } } } + + dynamic "managed_storage_configuration" { + for_each = try([var.managed_storage_configuration], []) + + content { + fargate_ephemeral_storage_kms_key_id = try(managed_storage_configuration.value.fargate_ephemeral_storage_kms_key_id, null) + kms_key_id = try(managed_storage_configuration.value.kms_key_id, null) + } + } } } diff --git a/modules/cluster/variables.tf b/modules/cluster/variables.tf index 6629743c..5526e2f6 100644 --- a/modules/cluster/variables.tf +++ b/modules/cluster/variables.tf @@ -43,6 +43,12 @@ variable "cluster_service_connect_defaults" { default = {} } +variable "managed_storage_configuration" { + description = "Configuration for the managed storage" + type = any + default = {} +} + ################################################################################ # CloudWatch Log Group ################################################################################ diff --git a/modules/service/main.tf b/modules/service/main.tf index b7ecef9e..a6e0d298 100644 --- a/modules/service/main.tf +++ b/modules/service/main.tf @@ -168,6 +168,18 @@ resource "aws_ecs_service" "this" { } } + dynamic "tls" { + for_each = try([service.value.tls], []) + + content { + kms_key = try(tls.value.kms_key, null) + role_arn = try(tls.value.role_arn, null) + issuer_cert_authority { + aws_pca_authority_arn = try(tls.value.issuer_cert_authority.aws_pca_authority_arn, null) + } + } + } + discovery_name = try(service.value.discovery_name, null) ingress_port_override = try(service.value.ingress_port_override, null) port_name = service.value.port_name @@ -356,6 +368,18 @@ resource "aws_ecs_service" "ignore_task_definition" { } } + dynamic "tls" { + for_each = try([service.value.tls], []) + + content { + kms_key = try(tls.value.kms_key, null) + role_arn = try(tls.value.role_arn, null) + issuer_cert_authority { + aws_pca_authority_arn = try(tls.value.issuer_cert_authority.aws_pca_authority_arn, null) + } + } + } + discovery_name = try(service.value.discovery_name, null) ingress_port_override = try(service.value.ingress_port_override, null) port_name = service.value.port_name diff --git a/variables.tf b/variables.tf index b624a302..5b6424ea 100644 --- a/variables.tf +++ b/variables.tf @@ -49,6 +49,12 @@ variable "cluster_tags" { default = {} } +variable "managed_storage_configuration" { + description = "Configuration for the managed storage" + type = any + default = {} +} + ################################################################################ # CloudWatch Log Group ################################################################################ diff --git a/wrappers/cluster/main.tf b/wrappers/cluster/main.tf index 91f929d7..c986d874 100644 --- a/wrappers/cluster/main.tf +++ b/wrappers/cluster/main.tf @@ -23,6 +23,7 @@ module "wrapper" { create_task_exec_policy = try(each.value.create_task_exec_policy, var.defaults.create_task_exec_policy, true) default_capacity_provider_use_fargate = try(each.value.default_capacity_provider_use_fargate, var.defaults.default_capacity_provider_use_fargate, true) fargate_capacity_providers = try(each.value.fargate_capacity_providers, var.defaults.fargate_capacity_providers, {}) + managed_storage_configuration = try(each.value.managed_storage_configuration, var.defaults.managed_storage_configuration, {}) tags = try(each.value.tags, var.defaults.tags, {}) task_exec_iam_role_description = try(each.value.task_exec_iam_role_description, var.defaults.task_exec_iam_role_description, null) task_exec_iam_role_name = try(each.value.task_exec_iam_role_name, var.defaults.task_exec_iam_role_name, null) diff --git a/wrappers/main.tf b/wrappers/main.tf index 5aca8372..bc80fb93 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -24,6 +24,7 @@ module "wrapper" { create_task_exec_policy = try(each.value.create_task_exec_policy, var.defaults.create_task_exec_policy, true) default_capacity_provider_use_fargate = try(each.value.default_capacity_provider_use_fargate, var.defaults.default_capacity_provider_use_fargate, true) fargate_capacity_providers = try(each.value.fargate_capacity_providers, var.defaults.fargate_capacity_providers, {}) + managed_storage_configuration = try(each.value.managed_storage_configuration, var.defaults.managed_storage_configuration, {}) services = try(each.value.services, var.defaults.services, {}) tags = try(each.value.tags, var.defaults.tags, {}) task_exec_iam_role_description = try(each.value.task_exec_iam_role_description, var.defaults.task_exec_iam_role_description, null)