This module provides a set of composable Terraform sub-modules for provisioning Amazon ECS infrastructure. Understanding how the pieces fit together will help you choose the right module structure for your use case.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/terraform-aws-modules/terraform-aws-ecs/llms.txt
Use this file to discover all available pages before exploring further.
Module structure
Root module
Combines the cluster and service sub-modules into a single integrated entrypoint. One
module block provisions a cluster and any number of services together.Cluster sub-module
Creates an ECS cluster, capacity providers, CloudWatch log group, task execution IAM role, and — for ECS Managed Instances — the infrastructure IAM role, node IAM role, and security group.
Service sub-module
Creates one ECS service, its task definition, container definitions, autoscaling resources, security group, service IAM role, task execution IAM role (optionally), and tasks IAM role.
Container definition sub-module
A building block invoked internally by the service sub-module for each container entry. Produces the JSON-encoded container definition and optionally manages the CloudWatch log group.
Express service sub-module
Creates an
aws_ecs_express_gateway_service — a simplified, fully-managed ECS service type with built-in autoscaling. Use this when you want a minimal configuration surface without managing task definitions directly.Construct hierarchy
Amazon ECS resources follow a strict parent-child hierarchy. The module mirrors this hierarchy exactly:| Level | AWS construct | Module that creates it |
|---|---|---|
| 1 | ECS Cluster | cluster sub-module |
| 2 | ECS Service | service sub-module |
| 3 | Task Definition / Task Set | service sub-module |
| 4 | Container Definition (1–10 per task) | container-definition sub-module |
- A cluster may contain one or more services.
- A service manages one task definition or task set (this module assumes one per service).
- A task wraps one to ten container definitions. Think of a task as a Kubernetes pod and the task definition as a pod spec.
Root module vs. separate sub-modules
- Root module (integrated)
- Separate sub-modules
Use the root module when you want to manage the cluster and all of its services in a single Terraform configuration. The root module accepts a Best for: Single-team clusters where one Terraform workspace owns the cluster and all services.
services map and iterates over it with for_each, passing the cluster ARN and the cluster-level task execution role ARN to each service automatically.Capacity provider types
The cluster sub-module supports four capacity provider types. You cannot mix Fargate-based providers with EC2-based providers on the same cluster.| Type | How compute is provisioned | Key tradeoff |
|---|---|---|
| FARGATE | AWS manages serverless compute | Predictable pricing; no EC2 management |
| FARGATE_SPOT | Spot capacity for Fargate | Up to 70% cheaper; tasks can be interrupted |
| EC2 Auto Scaling Group | You supply an ASG (e.g., via terraform-aws-autoscaling); ECS manages scaling via managed scaling | Full EC2 control; you own the AMI and instance lifecycle |
| ECS Managed Instances | ECS provisions and manages EC2 instances via a fleet API; uses managed_instances_provider block | Fully managed EC2 nodes; requires infrastructure and node IAM roles |
Resources created by each module
Cluster sub-module
Cluster sub-module
| Resource | Terraform resource type | Condition |
|---|---|---|
| ECS cluster | aws_ecs_cluster | Always |
| Cluster capacity providers | aws_ecs_cluster_capacity_providers | Always |
| EC2 / Managed Instances capacity provider | aws_ecs_capacity_provider | When capacity_providers is set |
| CloudWatch log group | aws_cloudwatch_log_group | create_cloudwatch_log_group = true |
| Task execution IAM role | aws_iam_role (task_exec) | create_task_exec_iam_role = true |
| Task execution IAM policy | aws_iam_policy (task_exec) | create_task_exec_policy = true |
| Infrastructure IAM role | aws_iam_role (infrastructure) | Managed Instances enabled |
| Infrastructure IAM policy | aws_iam_policy (infrastructure) | Managed Instances enabled |
| Node IAM role | aws_iam_role (node) | Managed Instances enabled |
| Node IAM policy | aws_iam_policy (node) | Managed Instances enabled |
| Node instance profile | aws_iam_instance_profile | Managed Instances enabled |
| Security group (for managed nodes) | aws_security_group | Managed Instances enabled |
| Security group rules | aws_vpc_security_group_ingress_rule / aws_vpc_security_group_egress_rule | Managed Instances enabled |
Service sub-module
Service sub-module
| Resource | Terraform resource type | Condition |
|---|---|---|
| ECS service | aws_ecs_service (this or ignore_task_definition) | create_service = true |
| ECS task definition | aws_ecs_task_definition | create_task_definition = true |
| ECS task set | aws_ecs_task_set | External deployment controller |
| Container definitions (via sub-module) | module.container_definition | One per entry in container_definitions |
| Task execution IAM role | aws_iam_role (task_exec) | create_task_exec_iam_role = true |
| Task execution IAM policy | aws_iam_policy (task_exec) | create_task_exec_policy = true |
| Tasks IAM role | aws_iam_role (tasks) | create_tasks_iam_role = true |
| Tasks IAM policy | aws_iam_policy (tasks) | Statements or ECS Exec enabled |
| Service IAM role | aws_iam_role (service) | Non-awsvpc mode with load balancer |
| Service IAM policy | aws_iam_policy (service) | Non-awsvpc mode with load balancer |
| Autoscaling target | aws_appautoscaling_target | enable_autoscaling = true |
| Autoscaling policies | aws_appautoscaling_policy | enable_autoscaling = true |
| Autoscaling scheduled actions | aws_appautoscaling_scheduled_action | When configured |
| Security group (for tasks) | aws_security_group | create_security_group = true |
| Security group rules | aws_vpc_security_group_ingress_rule / aws_vpc_security_group_egress_rule | When configured |
Container definition sub-module
Container definition sub-module
| Resource | Terraform resource type | Condition |
|---|---|---|
| CloudWatch log group | aws_cloudwatch_log_group | create_cloudwatch_log_group = true and enable_cloudwatch_logging = true |
container_definition local — a map that is JSON-encoded by the service sub-module and passed to aws_ecs_task_definition.container_definitions.Express service sub-module
Express service sub-module
| Resource | Terraform resource type | Condition |
|---|---|---|
| Express gateway service | aws_ecs_express_gateway_service | Always |
| Execution IAM role | aws_iam_role (execution) | create_execution_iam_role = true |
| Infrastructure IAM role | aws_iam_role (infrastructure) | create_infrastructure_iam_role = true |
| Security group | aws_security_group | create_security_group = true |
| Security group rules | aws_vpc_security_group_ingress_rule / aws_vpc_security_group_egress_rule | When configured |

