Files
acdl/modules/l1/ecs-service
Jon Chery cec34abc22 fix(P04 W1): ecs-service execution_role_arn + task_role_arn wiring (live apply gap)
The live terraform apply (P4) uncovered a P2 module-completeness gap: the
ecs-service L1 aws_ecs_task_definition was missing execution_role_arn +
task_role_arn, and the microservice L2 composition did not wire
roles.outputs.role_arn to the service. Fargate requires an execution role
for ECR image pull. Fixed: interface.json + variables.tf + main.tf +
composition.json wires. The iam-role assume-policy trusts ecs-tasks +
the inline policy grants ECR pull + CW logs.

A second live gap surfaced once the task definition applied: the ALB
aws_lb had no security group (AWS rejects an ALB with an empty SG list).
The platform VPC only outputs an ECS SG; the composition now wires
platform_vpc.outputs.ecs_security_group_id to alb.inputs.security_group
(the ECS SG opens port 80 to 0.0.0.0/0 — acceptable for an internet-facing
ALB + dev pilot per D-020). No iam-role module changes were needed — its
locals.tf already trusts ecs-tasks.amazonaws.com and grants ECR pull +
CloudWatch logs by default.

Live apply now succeeds: Apply complete! Resources: 0 added, 1 changed, 0
destroyed (task def + ECS service created on the first re-apply; ALB SG
updated in-place on the second). Full suite: 844 passed.

---ci---
project: acdl
phase: 4
milestone: v1.26
status: execute
wave: W1
---
2026-08-19 03:01:47 +00:00
..

ecs-service — ECS Fargate service (task definition + service)

Module kind: primitive | Version: 1.0.0

An ECS Fargate service with its task definition. Runs a container image on Fargate, optionally behind an ALB target group. This is a multi-resource module: it creates a task definition and a service that runs it.

Resources

Resource Type Purpose
task_definition aws_ecs_task_definition Fargate task definition with container image, CPU, memory, port, env
service aws_ecs_service Fargate service running the task definition in a cluster + subnets

Inputs

Name Type Required Default Description
image string yes ECR image URL for the task container
port number yes Container port the service listens on
cpu number no 256 Task CPU units (Fargate)
memory number no 512 Task memory in MiB (Fargate)
env string no Environment variables as a JSON map string
cluster_arn arn yes ECS cluster ARN (from ecs-cluster)
subnets string yes Comma-separated subnet ids (from vpc)
security_group string yes Security group id for the service ENIs
lb_target_group_arn arn no Optional ALB target group ARN (from alb)
region string yes AWS region the service is created in

Outputs

Name Type Description
service_arn arn The ECS service ARN
task_def_arn arn The ECS task definition ARN

Usage

{
  "id": "service",
  "type": "aws:ecs:task_definition",
  "module": "ecs-service@1.0.0",
  "inputs": {
    "image": "581513795199.dkr.ecr.us-east-1.amazonaws.com/acdl-microservice:latest",
    "port": 8080,
    "cpu": 256,
    "memory": 512,
    "cluster_arn": "ref:cluster.cluster_arn",
    "subnets": "ref:vpc.subnet_ids",
    "security_group": "ref:roles.role_arn",
    "region": "us-east-1"
  }
}

The image, port, and env inputs are compiled into a container_definitions JSON block by the adapter. The service is placed in the cluster with the given subnets and security group, and optionally wired to the ALB target group if lb_target_group_arn is provided.

Compliance extension points

  • CloudWatch Logs — add logConfiguration to the container definition with a log group + retention policy (SOX, SOC2 CC7.2, DORA ICT incident logging).
  • Task execution role separation — add a separate aws_iam_role for execution vs. the task role (SOC2 CC6.3 segregation of duties at runtime).
  • Secrets injection — add secrets block referencing AWS Secrets Manager / SSM Parameter Store with KMS encryption (SOC2 CC6.1.
  • Execute command — add enable_execute_command with KMS encryption for session audit (SOC2 CC7.2).
  • Deployment circuit breaker — add deployment_circuit_breaker block for resilience (SOC2 CC9.1, DORA operational resilience).
  • Health check — add a health_check block to the target group (currently missing despite the contract schema having a healthcheck field).

Examples

Validated example contracts are in examples/. The platform-test pipeline validates them against schemas/contract.schema.json.

Simple

A minimal deployment:

examples/simple.yml

environment: dev
id: svc
infrastructure:
  ecs-service:
    inputs:
      image: public.ecr.aws/docker/library/nginx:latest
      name: my-service
      port: 80
      region: us-east-1
    version: 1.0.0
name: ecs-service

Complex

A production deployment with optional inputs:

examples/complex.yml

environment: dev
id: svc
infrastructure:
  ecs-service:
    inputs:
      env:
        ENVIRONMENT: production
        LOG_LEVEL: info
      image: public.ecr.aws/docker/library/nginx:latest
      name: my-production-service
      port: 8080
      region: us-east-1
    version: 1.0.0
name: ecs-service

Versioning

1.0.0 — interface MAJOR, behavior MINOR, lifecycle PATCH. MAJOR bumps require a new registry entry (immutable publication); old entries enter a 12-month deprecation window.