Loading...
Loading...
### Terraform Version ```shell Terraform v1.9.5 on darwin_amd64 + provider registry.terraform.io/hashicorp/archive v2.6.0 + provider registry.terraform.io/hashicorp/aws v5.79.0 + provider registry.terraform.io/hashicorp/null v3.2.3 + provider registry.terraform.io/hashicorp/random v3.6.3 + provider registry.terraform.io/sumologic/sumologic v2.10.0 + provider registry.terraform.io/terraform-providers/acme v2.12.0 Your version of Terraform is out of date! The latest version is 1.9.8. You can update by downloading from https://www.terraform.io/downloads.html ``` ### Terraform Configuration Files Service Discovery code: ```terraform resource "aws_service_discovery_private_dns_namespace" "this" { description = var.config.description name = var.config.domain_name tags = var.tags vpc = var.config.vpc_id } # resource "aws_service_discovery_service" "this" { # description = var.config.description # name = "namespaces" #var.config.domain_name # tags = var.tags # dns_config { # namespace_id = aws_service_discovery_private_dns_namespace.this.id # dns_records { # ttl = 10 # type = var.config.dns_record_type # } # routing_policy = var.config.dns_routing_policy # } # health_check_custom_config { # failure_threshold = 1 # } # } ``` ECS service code: ```terraform resource "aws_ecs_task_definition" "amid" { for_each = local.required_services family = "${each.key}-${local.tenant_client_env}" network_mode = each.value.register_with_namespace ? "bridge" : null #241126 - default is "bridge", but can't be null for CloudMap ServiceConnect requires_compatibilities = [] tags = var.tags #TODO: Want to shift this to a template and pass the variables to it; it should be possible to have a single #TODO: common template to cover all services, with feature blocks for optional items. #NOTES: # "name": "${each.key}-${local.tenant_client_env}" = The name which appears in the ECS Services # "containerPort": ${each.value.container_port} = The port the service runs on inside the container # "hostPort": = The ephemeral port the container surfaces on the host instance (0 = auto-assign) # "portMappings": = A name assigned to a hostPort:containerPort combo, used by CloudMap (use "main" for the main port) container_definitions = <<-DEF [ { "name": "${each.key}-${local.tenant_client_env}", "image": "${local.repos[each.key]}:${each.value.image_tag}", "cpu": ${each.value.service_cpu}, "memoryReservation": ${each.value.service_memory}, "essential": true, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "${aws_cloudwatch_log_group.amid[each.key].name}", "awslogs-region": "${data.aws_region.current.name}", "awslogs-stream-prefix": "ecs" } }, ${each.value.entrypoint != null ? format("\"entrypoint\": %s,", jsonencode(each.value.entrypoint)) : ""} ${each.value.command != null ? format("\"command\": %s,", jsonencode(each.value.command)) : ""} "portMappings": [ { "containerPort": ${each.value.container_port}, "hostPort": 0, ${each.value.register_with_namespace ? format("\"name\": \"%s\",", "main") : ""} "protocol": "tcp" } ], "environment": ${jsonencode(local.services_ecs_env[each.key])}, "mountPoints": [], "systemControls": [], "volumesFrom": [] } ] DEF lifecycle { create_before_destroy = true } } data "aws_ecs_task_definition" "amid" { for_each = local.required_services task_definition = aws_ecs_task_definition.amid[each.key].family } resource "aws_ecs_service" "amid" { for_each = local.required_services cluster = var.ecs_info.ecs_cluster_name deployment_minimum_healthy_percent = each.value.alb_healthy_percent != 100 ? each.value.alb_healthy_percent : null desired_count = each.value.desired_tasks health_check_grace_period_seconds = each.value.is_alb_attach ? each.value.service_health_check_grace_period_seconds : null name = "${each.key}-${local.tenant_client_env}" tags = var.tags task_definition = "${aws_ecs_task_definition.amid[each.key].family}:${max( aws_ecs_task_definition.amid[each.key].revision, data.aws_ecs_task_definition.amid[each.key].revision, )}" capacity_provider_strategy { base = 1 capacity_provider = var.ecs_info.ecs_cluster_name weight = 100 } dynamic "load_balancer" { for_each = each.value.is_alb_attach ? { alb = "alb" } : {} content { container_name = "${each.key}-${local.tenant_client_env}" container_port = each.value.container_port target_group_arn = var.alb_info.alb_target_group_arns[each.key] } } dynamic "service_connect_configuration" { for_each = each.value.register_with_namespace ? { sc = var.network_info.cloudmap_namespace_name } : {} content { enabled = true namespace = var.network_info.cloudmap_namespace_name service { client_alias { dns_name = "${each.key}.${var.network_info.dns_internal_domain}" port = each.value.container_port } discovery_name = "${each.key}-${local.tenant_client_env}" #This is the name which will appear in the Namespace's Services port_name = "main" #NB. See "portMappings" in the Task Definition } } } # dynamic "service_registries" { # for_each = each.value.register_with_namespace ? { sc = var.network_info.cloudmap_registry_name } : {} # content { # container_name = "${each.key}-${local.tenant_client_env}" #NB. Same as "name" used in Task Definition # container_port = each.value.container_port #NB. Same as "containerPort" used in Task Definition # registry_arn = var.network_info.cloudmap_registry_arn # } # } lifecycle { create_before_destroy = true ignore_changes = [name] } } ``` ### Debug Output none ### Expected Behavior Am expecting the ECS Service to register in the CloudMap Namespace as Discoverable by "**API Calls and DNS Queries**". ### Actual Behavior The ECS Service registers as "**API Calls Only**". ### Steps to Reproduce 1. terraform init 2. terraform plan 3. terraform apply 4. View in AWS Console ### Additional Context I've also tried registering with a service registry (the commented blocks in the above code) and a pair of SRV & A-records are created per ECS Service. However, the SRV DNS records created are missing the leading "." so we just end up with a number of unidentifiable "." records. The SRV records include the "container_port" and the name of an associated A-record which gives the ECS Host's (EC2) IP, but the A-record's name is just a resource identifier. ### References https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service#service_registries https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/service_discovery_service
Click on a version to see all relevant bugs
Terraform Integration
Learn more about where this data comes from
Bug Scrub Advisor
Streamline upgrades with automated vendor bug scrubs
BugZero Enterprise
Wish you caught this bug sooner? Get proactive today.