Create and manage AWS ECS application in a clean abstracted way.
This module is actively maintained and is covered by multiple end-to-end tests to prevent regressions.
This module is feature-rich, with sane defaults. Some of the features are:
- Web application (ALB + ACM + R53)
- Worker application to Fargate and Worker application to EC2 (no ALB)
- TCP application (no ALB)
- Environment variables (SSM parameters)
- ECR repo Management
- Standardized naming convention for all resources
- Deployment via Terraform & via external tool (ecs-deploy or ize)
- Datadog integration
- Autoscale (scheduled or target-based)
- ECS Launch Type (EC2 or Fargate)
- EIP assignment
- Resource configuration (CPU/MEM)
- EFS (mount and/or share management)
- GPU-based instance
- Multiple ECS network modes
- Root block device configuration (size, type)
- Automatic Nginx Proxy for Web Applications
- Firelens / Datadog log driver
- ECS Exec (console into the container)
- tmpfs configuration
This is a minimal example which demostrates simplicity of the module:
module "api" {
source = "registry.terraform.io/hazelops/ecs-app/aws"
version = "~>2.0.0"
name = "api"
env = "prod"
ecs_cluster_name = "prod-cluster"
vpc_id = "vpc-00000000000000000"
public_subnets = ["subnet-00000000000000000", "subnet-11111111111111111", "subnet-22222222222222222"]
private_subnets = ["subnet-33333333333333333", "subnet-44444444444444444", "subnet-55555555555555555"]
security_groups = ["sg-00000000000000000"]
root_domain_name = "example.com"
zone_id = "Z00000000000000000000"
environment = {
API_KEY = "00000000000000000000000000000000"
JWT_TOKEN = "99999999999999999999999999999999"
}
}
See examples for more usage options.
Name | Version |
---|---|
terraform | >= 1.1 |
Name | Version |
---|---|
aws | 5.47.0 |
template | 2.2.0 |
Name | Source | Version |
---|---|---|
alb | registry.terraform.io/terraform-aws-modules/alb/aws | ~> 7.0 |
autoscaling | terraform-aws-modules/autoscaling/aws | ~> 6.0 |
datadog | registry.terraform.io/hazelops/ecs-datadog-agent/aws | ~> 3.3 |
ecr | registry.terraform.io/hazelops/ecr/aws | ~> 1.1 |
efs | registry.terraform.io/cloudposse/efs/aws | ~> 0.36 |
nginx | registry.terraform.io/hazelops/ecs-nginx-proxy/aws | ~> 1.0 |
route_53_health_check | registry.terraform.io/hazelops/route53-healthcheck/aws | ~> 1.0 |
service | ./modules/ecs-service | n/a |
Name | Type |
---|---|
aws_eip.autoscaling | resource |
aws_iam_role_policy.ec2_auto_eip | resource |
aws_route53_record.alb | resource |
aws_route53_record.ec2 | resource |
aws_caller_identity.current | data source |
aws_iam_instance_profile.this | data source |
aws_region.current | data source |
template_file.asg_ecs_ec2_user_data | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
additional_container_definition_parameters | Additional parameters passed straight to the container definition, eg. tmpfs config | any |
{} |
no |
alb_access_logs_enabled | If true, ALB access logs will be written to S3 | bool |
false |
no |
alb_access_logs_s3bucket_name | S3 bucket name for ALB access logs | string |
"" |
no |
alb_deregistration_delay | The amount of time, in seconds, for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused | number |
5 |
no |
alb_health_check_healthy_threshold | The number of consecutive health checks successes required before considering an unhealthy target healthy | number |
3 |
no |
alb_health_check_interval | The approximate amount of time, in seconds, between health checks of an individual target | number |
30 |
no |
alb_health_check_path | ALB health check path | string |
"/health" |
no |
alb_health_check_timeout | The amount of time, in seconds, during which no response means a failed health check | number |
6 |
no |
alb_health_check_unhealthy_threshold | The number of consecutive health check failures required before considering the target unhealthy | number |
3 |
no |
alb_health_check_valid_response_codes | The HTTP codes to use when checking for a successful response from a target. You can specify multiple values (for example, "200,202") or a range of values (for example, "200-299"). | string |
"200-399" |
no |
alb_idle_timeout | The time in seconds that the connection is allowed to be idle. | number |
60 |
no |
alb_security_groups | Security groups to assign to ALB | list(any) |
[] |
no |
app_secrets | List of SSM ParameterStore secret parameters - by default, /$var.env/$var.name/* | list(any) |
[] |
no |
app_type | ECS application type. Valid values: web (with ALB), worker (without ALB). | string |
"web" |
no |
assign_public_ip | ECS service network configuration - assign public IP | bool |
false |
no |
autoscale_enabled | ECS Autoscaling enabled | bool |
false |
no |
autoscale_scheduled_down | List of Cron-like expressions for scheduled ecs autoscale DOWN | list(string) |
[] |
no |
autoscale_scheduled_timezone | Time Zone for the scheduled event | string |
"UTC" |
no |
autoscale_scheduled_up | List of Cron-like expressions for scheduled ecs autoscale UP | list(string) |
[] |
no |
autoscale_target_value_cpu | ECS Service Average CPU Utilization threshold. Integer value for percentage - IE 80 | number |
50 |
no |
autoscale_target_value_memory | ECS Service Average Memory Utilization threshold. Integer value for percentage. IE 60 | number |
50 |
no |
autoscaling_health_check_type | ECS 'EC2' or 'ELB' health check type | string |
"EC2" |
no |
autoscaling_max_size | Maximum number of running ECS tasks during scheduled-up-autoscaling action | number |
2 |
no |
autoscaling_min_size | Minimum number of running ECS tasks during scheduled-up-autoscaling action | number |
2 |
no |
aws_service_discovery_private_dns_namespace | Amazon ECS Service Discovery private DNS namespace | string |
"" |
no |
cloudwatch_schedule_expressions | List of Cron-like Cloudwatch Event Rule schedule expressions (UTC time zone) | list(any) |
[] |
no |
cpu | Fargate CPU value (https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | number |
256 |
no |
cpu_architecture | When you register a task definition, you specify the CPU architecture. The valid values are X86_64 and ARM64 | string |
"X86_64" |
no |
create_iam_instance_profile | Determines whether an IAM instance profile is created or to use an existing IAM instance profile | bool |
true |
no |
create_schedule | Determines whether to create autoscaling group schedule or not | bool |
false |
no |
datadog_enabled | Datadog agent is enabled | bool |
false |
no |
datadog_jmx_enabled | Enables / Disables jmx monitor via the datadog agent | bool |
false |
no |
deployment_minimum_healthy_percent | Lower limit on the number of running tasks | number |
100 |
no |
desired_capacity | Desired number (capacity) of running ECS tasks | number |
1 |
no |
docker_container_command | Docker container command | list(string) |
[] |
no |
docker_container_entrypoint | Docker container entrypoint | list(string) |
[] |
no |
docker_container_port | Docker container port | number |
3000 |
no |
docker_host_port | Docker host port. 0 means Auto-assign. | number |
0 |
no |
docker_image_name | Docker image name | string |
"" |
no |
docker_image_tag | Docker image tag | string |
"latest" |
no |
docker_labels | Labels to be added to the docker. Used for auto-configuration, for instance of JMX discovery | map(any) |
null |
no |
docker_registry | ECR or any other docker registry | string |
"docker.io" |
no |
domain_names | Domain names for AWS Route53 A records | list(any) |
[] |
no |
ec2_eip_count | Count of EIPs to create | number |
0 |
no |
ec2_eip_dns_enabled | Whether to manage DNS records to be attached to the EIP | bool |
false |
no |
ec2_eip_enabled | Enable EC2 ASG Auto Assign EIP mode | bool |
false |
no |
ec2_service_group | Service group name, e.g. app, service name etc. | string |
"app" |
no |
ecr_force_delete | If true, will delete the ECR repository even if it contains images on destroy | bool |
false |
no |
ecr_repo_create | Creation of a ECR repo | bool |
false |
no |
ecr_repo_name | ECR repository name | string |
"" |
no |
ecs_cluster_arn | ECS cluster arn. Should be specified to avoid data query by cluster name | string |
"" |
no |
ecs_cluster_name | ECS cluster name | string |
n/a | yes |
ecs_exec_custom_prompt_enabled | Enable Custom shell prompt on ECS Exec | bool |
false |
no |
ecs_exec_enabled | Turns on the Amazon ECS Exec for the task | bool |
true |
no |
ecs_exec_prompt_string | Shell prompt that contains ENV and APP_NAME is enabled | string |
`"\e[1;35m★\e[0m $ENV-$APP_NAME:$(wget -qO- $ECS_CONTAINER_METADATA_URI_V4 | sed -n 's/."com.amazonaws.ecs.task-definition-version":"\([^\"]\).*/\1/p') \e[1;36m★\e[0m $(wget -qO- $ECS_CONTAINER_METADATA_URI_V4 |
ecs_launch_type | ECS launch type: FARGATE or EC2 | string |
"FARGATE" |
no |
ecs_network_mode | Corresponds to networkMode in an ECS task definition. Supported values are none, bridge, host, or awsvpc | string |
"awsvpc" |
no |
ecs_platform_version | The platform version on which to run your service. Only applicable when using Fargate launch type | string |
"LATEST" |
no |
ecs_service_deployed | This service resource doesn't have task definition lifecycle policy, so terraform is used to deploy it (instead of ecs cli or ize) | bool |
false |
no |
ecs_service_discovery_enabled | ECS service can optionally be configured to use Amazon ECS Service Discovery | bool |
false |
no |
ecs_service_name | The ECS service name | string |
"" |
no |
ecs_task_health_check_command | Command to check for the health of the container | string |
"" |
no |
ecs_volumes_from | The VolumeFrom property specifies details on a data volume from another container in the same task definition | list(any) |
[] |
no |
efs_enabled | Whether to enable EFS mount for ECS task | bool |
false |
no |
efs_file_system_id | EFS file system ID | string |
"" |
no |
efs_mount_point | EFS mount point in the container | string |
"/mnt/efs" |
no |
efs_root_directory | EFS root directory | string |
"/" |
no |
efs_share_create | Whether to create EFS share or not | bool |
false |
no |
env | Target environment name of the infrastructure | string |
n/a | yes |
environment | Map of parameters to be set in SSM and then exposed into a Task Definition as environment variables. | map(string) |
n/a | yes |
firelens_ecs_log_enabled | AWS Firelens ECS logs enabled (used by FluentBit, Datadog, etc) | bool |
false |
no |
global_secrets | List of SSM ParameterStore global secrets - by default, /$var.env/global/* | list(any) |
[] |
no |
gpu | GPU-enabled container instances | number |
0 |
no |
http_port | Port that is used for HTTP protocol | number |
80 |
no |
https_enabled | Whether enable https or not (still needs tls_cert_arn) | bool |
true |
no |
iam_instance_profile | IAM Instance Profile | string |
null |
no |
iam_role_policy_statement | ECS Service IAM Role policy statement | list(any) |
[] |
no |
image_id | EC2 AMI id | string |
null |
no |
instance_type | EC2 instance type for ECS | string |
"t3.small" |
no |
key_name | EC2 key name | string |
null |
no |
max_size | Maximum number of running ECS tasks | number |
1 |
no |
memory | Fargate Memory value (https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | number |
512 |
no |
memory_reservation | The soft limit (in MiB) of memory to reserve for the container | number |
256 |
no |
min_size | Minimum number of running ECS tasks | number |
1 |
no |
name | ECS app name including all required namespaces | string |
n/a | yes |
operating_system_family | Platform to be used with ECS. The valid values for Amazon ECS tasks hosted on Fargate are LINUX, WINDOWS_SERVER_2019_FULL, and WINDOWS_SERVER_2019_CORE. The valid values for Amazon ECS tasks hosted on EC2 are LINUX, WINDOWS_SERVER_2022_CORE, WINDOWS_SERVER_2022_FULL, WINDOWS_SERVER_2019_FULL, and WINDOWS_SERVER_2019_CORE, WINDOWS_SERVER_2016_FULL, WINDOWS_SERVER_2004_CORE, and WINDOWS_SERVER_20H2_CORE. | string |
"LINUX" |
no |
port_mappings | List of ports to open from a service | any |
[] |
no |
private_subnets | VPC Private subnets to place ECS resources | list(any) |
[] |
no |
proxy_docker_container_command | Proxy docker container CMD | list(string) |
[ |
no |
proxy_docker_entrypoint | Proxy docker container entrypoint | list(string) |
[ |
no |
proxy_docker_image_name | Nginx proxy docker image name | string |
"nginx" |
no |
public | It's publicity accessible application | bool |
true |
no |
public_ecs_service | It's publicity accessible service | bool |
false |
no |
public_subnets | VPC Public subnets to place ECS resources | list(any) |
[] |
no |
resource_requirements | The ResourceRequirement property specifies the type and amount of a resource to assign to a container. The only supported resource is a GPU | list(any) |
[] |
no |
root_block_device_size | EBS root block device size in GB | number |
"50" |
no |
root_block_device_type | EBS root block device type | string |
"gp2" |
no |
root_domain_name | Domain name of AWS Route53 Zone | string |
"" |
no |
route53_health_check_enabled | AWS Route53 health check is enabled | bool |
false |
no |
schedules | Map of autoscaling group schedule to create | map(any) |
{} |
no |
security_groups | Security groups to assign to ECS Fargate task/ECS EC2 | list(any) |
[] |
no |
shared_memory_size | Size of the /dev/shm shared memory in MB | number |
0 |
no |
sidecar_container_definitions | Sidecar container definitions for ECS task | any |
[] |
no |
sns_service_subscription_endpoint | You can use different endpoints, such as email, Pagerduty, Slack, etc. | string |
"[email protected]" |
no |
sns_service_subscription_endpoint_protocol | See valid protocols here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription#protocol-support | string |
"email" |
no |
ssm_global_secret_path | AWS SSM root path to global environment secrets like /dev/global | string |
null |
no |
ssm_secret_path | AWS SSM root path to environment secrets of an app like /dev/app1 | string |
null |
no |
tls_cert_arn | TLS certificate ARN | string |
null |
no |
tmpfs_container_path | Path where tmpfs shm would be mounted | string |
"/tmp/" |
no |
tmpfs_enabled | TMPFS support for non-Fargate deployments | bool |
false |
no |
tmpfs_mount_options | Options for the mount of the ram disk. noatime by default to speed up access | list(string) |
[ |
no |
tmpfs_size | Size of the tmpfs in MB | number |
1024 |
no |
volumes | Amazon data volumes for ECS Task (efs/FSx/Docker volume/Bind mounts) | list(any) |
[] |
no |
vpc_id | AWS VPC ID | string |
n/a | yes |
web_proxy_docker_container_port | Proxy docker container port | number |
80 |
no |
web_proxy_docker_image_tag | Nginx proxy docker image tag | string |
"1.19.2-alpine" |
no |
web_proxy_enabled | Nginx proxy enabled | bool |
false |
no |
zone_id | AWS Route53 Zone ID | string |
"" |
no |
Name | Description |
---|---|
alb_arn | ARN of the ALB (if ALB is created) |
alb_dns_name | Name of the ALB DNS record (if ALB is created) |
alb_dns_zone | Zone ID of the ALB DNS record (if ALB is created) |
cloudwatch_event_rule_id | ID of the Cloudwatch event rule for ECS Scheduled Task |
cloudwatch_log_group | n/a |
ec2_dns_name | Public DNS name of the EC2 instance (if EC2 is used) |
efs_mount_target | DNS name of the EFS mount target (if EFS is created) |
eips | List of EIPs associated with the EC2 instances (if EC2 is used) |
public_ip | Public IP of the EC2 instance (if EC2 is used) |
r53_lb_dns_name | DNS name of the record that is attached to the ALB (if app type is web or tcp-ap) |
this_target_group_arn | n/a |
this_task_definition_arn | n/a |