Ecs service worker
Bridge Network Mode and Service Connect
This module supports both awsvpc and bridge network modes for ECS worker tasks. Bridge mode is useful when running multiple services on a single EC2 instance to avoid ENI limits.
Network Mode Variables
| Variable | Description | Default |
|---|---|---|
network_mode |
Docker network mode (awsvpc or bridge) |
awsvpc |
enable_service_connect |
Enable ECS Service Connect for service discovery | false |
service_connect_namespace_arn |
ARN of the Cloud Map namespace for Service Connect | null |
Bridge Mode Configuration
When using bridge mode: - Port mappings automatically use dynamic host ports (hostPort = 0) - Service Connect is required for inter-service communication - Subnet and security group configurations are not applied to tasks (they use the EC2 host's network)
Example: Bridge Mode with Service Connect
module "my_worker" {
source = "./modules/ecs_service_worker"
service_name = "my-worker"
cluster_name = module.ecs_cluster.cluster_name
# Bridge mode configuration
network_mode = "bridge"
enable_service_connect = true
service_connect_namespace_arn = module.ecs_cluster.namespace_arn
# EC2 capacity provider
capacity_provider_strategy = {
ec2 = {
capacity_provider = module.ecs_cluster.ec2_capacity_provider_name
weight = 100
}
}
# Other required variables...
container_image = "my-worker-image:latest"
subnet_ids = var.private_subnet_ids
security_group_ids = [var.security_group_id]
env = var.environment
}
Service Connect Benefits
ECS Service Connect provides: - Transparent service-to-service communication via Envoy proxy sidecars - Same service URLs work in both Fargate (awsvpc) and EC2 (bridge) modes - No application code changes required when switching between modes - Built-in load balancing and health checking for service mesh
Modules
| Name | Source | Version |
|---|---|---|
| ecs_service | terraform-aws-modules/ecs/aws//modules/service | 6.2.1 |
Inputs
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| additional_container_definitions | Additional container definitions to add to the task definition | map(object({ |
{} |
no |
| auto_discover_secrets_from_additional_containers | Automatically discover and grant task execution role access to secrets used in additional_container_definitions | bool |
true |
no |
| autoscaling_max_capacity | The maximum number of tasks to run | number |
10 |
no |
| autoscaling_min_capacity | The minimum number of tasks to run | number |
1 |
no |
| autoscaling_policies | Map of autoscaling policies to create for the service | any |
{ |
no |
| capacity_provider_strategy | Cluster-level strategy enforcement | map(object({ |
null |
no |
| cluster_name | The name of the ECS cluster | string |
n/a | yes |
| command | The command to run in the container | list(string) |
[] |
no |
| container_cpu | The number of CPU units to reserve for the container | number |
256 |
no |
| container_health_check | Health check configuration for the container | object({ |
null |
no |
| container_image | The container image to use | string |
n/a | yes |
| container_memory | The amount of memory to reserve for the container | number |
256 |
no |
| container_runtime_user | The user to run the container as (set in container definition). | string |
null |
no |
| cpu_architecture | The CPU architecture of the container | string |
"ARM64" |
no |
| create | Whether to create the ECS service | bool |
true |
no |
| dd_agent_apm_enabled | Whether to enable Datadog APM (Application Performance Monitoring) for distributed tracing. Only applies when dd_enabled is true. | bool |
true |
no |
| dd_agent_container_monitoring_enabled | Whether to enable Datadog container-level monitoring (CPU, memory, network metrics). Only applies when dd_enabled is true. | bool |
true |
no |
| dd_agent_metrics_enabled | Whether to enable Datadog metrics collection via DogStatsD. Only applies when dd_enabled is true. | bool |
true |
no |
| dd_api_key_parameter_name | The name of the Parameter Store parameter containing the Datadog API key | string |
"/datadog/DD_API_KEY" |
no |
| dd_apm_enabled | DEPRECATED: Use dd_agent_apm_enabled instead. Kept for backward compatibility. | bool |
true |
no |
| dd_apm_ignore_resources_string | Datadog APM ignore resources string, e.g. 'GET /healthcheck | string |
"" |
no |
| dd_enabled | Master switch for Datadog monitoring. When true, enables all monitoring features (logs, APM, metrics, container monitoring) unless explicitly disabled via granular flags. When false, all monitoring is disabled regardless of granular flag settings. | bool |
false |
no |
| dd_fluentbit_base_config | Base Fluent Bit configuration file path. Defaults to built-in parse-json.conf | string |
"/fluent-bit/configs/parse-json.conf" |
no |
| dd_fluentbit_enable_ecs_log_metadata | Enable ECS log metadata in Fluent Bit. Only applies when using custom Fluent Bit config. | bool |
true |
no |
| dd_fluentbit_s3_config | S3 ARN for custom Fluent Bit configuration file (e.g., arn:aws:s3:::bucket-name/path/to/fluentbit.conf). When provided, uses init-image and downloads config from S3 before starting Fluent Bit | string |
null |
no |
| dd_log_level | The log level for the Datadog agent | string |
"INFO" |
no |
| dd_logs_enabled | Whether to enable Datadog log forwarding via Fluent Bit. Only applies when dd_enabled is true. | bool |
true |
no |
| dd_site | The Datadog site to send data to | string |
"datadoghq.eu" |
no |
| dd_tags | Map of tags to apply to the Datadog agent | map(string) |
{} |
no |
| dependencies | List of dependencies for the ECS primary container | list(object({ |
[] |
no |
| deployment_maximum_percent | Upper limit (as a percentage of the service's desired_count) of the number of running tasks that can be running in a service during a deployment |
number |
200 |
no |
| deployment_minimum_healthy_percent | Lower limit (as a percentage of the service's desired_count) of the number of running tasks that must remain healthy during a deployment |
number |
66 |
no |
| desired_count | The desired number of tasks to run | number |
null |
no |
| enable_autoscaling | Whether to enable autoscaling for the ECS service | bool |
true |
no |
| enable_deployment_rollback | Whether to enable deployment rollback | bool |
true |
no |
| enable_execute_command | Whether to enable execute command for the ECS service | bool |
true |
no |
| enable_service_connect | Enable ECS Service Connect for service discovery (required for bridge mode inter-service communication) | bool |
false |
no |
| env | The environment the service is running in | string |
n/a | yes |
| environment_files | List of S3 ARNs for environment files to load into the container | list(object({ |
[] |
no |
| environment_variables | Map of environment variables to set in the container | map(string) |
{} |
no |
| ephemeral_storage | The amount of ephemeral storage to allocate for the task. This parameter is used to expand the total amount of ephemeral storage available, beyond the default amount, for tasks hosted on AWS Fargate | object({ |
null |
no |
| ignore_task_definition_changes | Whether to ignore changes to the task definition | bool |
false |
no |
| launch_type | Optional ECS launch type | string |
"FARGATE" |
no |
| mount_points | List of mount points to attach to the container | list(object({ |
[] |
no |
| network_mode | Docker network mode for the task (awsvpc or bridge). Bridge mode allows more tasks per EC2 instance but requires Service Connect for service discovery. | string |
"awsvpc" |
no |
| parameter_store_secret_names | Map of Parameter Store secret names to attach to the ECS service | map(string) |
{} |
no |
| secretsmanager_secret_names | Map of Secrets Manager secret names to attach to the ECS service | map(string) |
{} |
no |
| security_group_egress_rules | Security group egress rules to add to the security group created | map(object({ |
{} |
no |
| security_group_ids | The security groups to attach to the ECS service | list(string) |
n/a | yes |
| security_group_ingress_rules | Security group ingress rules to add to the security group created | map(object({ |
{} |
no |
| service_connect_namespace_arn | ARN of the Cloud Map namespace for Service Connect (required when enable_service_connect is true) | string |
null |
no |
| service_connect_namespace_name | Name of the Cloud Map namespace for Service Connect DNS resolution (e.g., 'genai-namespace'). Used to construct full DNS names like 'service.namespace'. | string |
null |
no |
| service_discovery_id | The ID of the service discovery namespace | string |
"" |
no |
| service_name | The name of the ECS service | string |
n/a | yes |
| service_port | The port the service listens on (required for Service Connect to expose the service to other containers) | number |
null |
no |
| subnet_ids | The subnets to place the ECS service | list(string) |
n/a | yes |
| task_exec_additional_secret_arns | Additional Secrets Manager secret ARNs to grant task execution role access to (in addition to those in secretsmanager_secret_names) | list(string) |
[] |
no |
| task_exec_additional_ssm_param_arns | Additional SSM Parameter Store ARNs to grant task execution role access to (in addition to those in parameter_store_secret_names) | list(string) |
[] |
no |
| volume | Object of volumes to attach to the container | any |
{} |
no |
Outputs
| Name | Description |
|---|---|
| tasks_execution_iam_role_arn | The IAM execution role ARN for the ECS tasks |
| tasks_execution_iam_role_name | The IAM execution role name for the ECS tasks |
| tasks_iam_role_arn | The IAM execution role ARN for the ECS tasks. Use this to attache policies for other AWS services, e.g. access to S3 bucket. |
| tasks_iam_role_name | The IAM execution role name for the ECS tasks. Use this to attache policies for other AWS services, e.g. access to S3 bucket. |
IAM Permissions for Secrets
The module creates IAM policies with permissions ONLY for the secrets you use. No wildcards, no broad permissions.
1. Basic secrets (main container)
module "ecs_service_worker" {
source = "./modules/ecs_service_worker"
secretsmanager_secret_names = {
"DATABASE_PASSWORD" = aws_secretsmanager_secret.db_password.name
"API_KEY" = aws_secretsmanager_secret.api_key.name
}
parameter_store_secret_names = {
"REDIS_URL" = aws_ssm_parameter.redis_url.name
}
}
The module creates IAM permissions for these secrets automatically.
2. Automatic discovery (additional containers)
additional_container_definitions = {
datadog = {
image = "datadog/agent:latest"
secrets = [
{ name = "DD_API_KEY", valueFrom = "arn:aws:secretsmanager:us-east-1:123456789012:secret:datadog-key" }
]
}
}
The module finds secrets in additional_container_definitions automatically. IAM permissions are added for them.
To disable: auto_discover_secrets_from_additional_containers = false
3. Manual mode (advanced)
task_exec_additional_secret_arns = [
"arn:aws:secretsmanager:us-east-1:123456789012:secret:shared-secret"
]
task_exec_additional_ssm_param_arns = [
"arn:aws:ssm:us-east-1:123456789012:parameter/shared-param"
]
Use this when you need secrets that are not in the container definitions.