AWS ECS Terraform module
Terraform module which creates ECS (Elastic Container Service) resources on AWS.
Available Features
- ECS cluster w/ Fargate or EC2 Auto Scaling capacity providers
- ECS Service w/ task definition, task set, and container definition support
- Separate sub-modules or integrated module for ECS cluster and service
For more details see the design doc
Usage
This project supports creating resources through individual sub-modules, or through a single module that creates both the cluster and service resources. See the respective sub-module directory for more details and example usage.
Integrated Cluster w/ Services
module "ecs" {
source = "terraform-aws-modules/ecs/aws"
cluster_name = "ecs-integrated"
cluster_configuration = {
execute_command_configuration = {
logging = "OVERRIDE"
log_configuration = {
cloud_watch_log_group_name = "/aws/ecs/aws-ec2"
}
}
}
# Cluster capacity providers
cluster_capacity_providers = ["FARGATE", "FARGATE_SPOT"]
default_capacity_provider_strategy = {
FARGATE = {
weight = 50
base = 20
}
FARGATE_SPOT = {
weight = 50
}
}
services = {
ecsdemo-frontend = {
cpu = 1024
memory = 4096
# Container definition(s)
container_definitions = {
fluent-bit = {
cpu = 512
memory = 1024
essential = true
image = "906394416424.dkr.ecr.us-west-2.amazonaws.com/aws-for-fluent-bit:stable"
firelensConfiguration = {
type = "fluentbit"
}
memoryReservation = 50
}
ecs-sample = {
cpu = 512
memory = 1024
essential = true
image = "public.ecr.aws/aws-containers/ecsdemo-frontend:776fd50"
portMappings = [
{
name = "ecs-sample"
containerPort = 80
protocol = "tcp"
}
]
# Example image used requires access to write to root filesystem
readonlyRootFilesystem = false
dependsOn = [{
containerName = "fluent-bit"
condition = "START"
}]
enable_cloudwatch_logging = false
logConfiguration = {
logDriver = "awsfirelens"
options = {
Name = "firehose"
region = "eu-west-1"
delivery_stream = "my-stream"
log-driver-buffer-limit = "2097152"
}
}
memoryReservation = 100
}
}
service_connect_configuration = {
namespace = "example"
service = [{
client_alias = {
port = 80
dns_name = "ecs-sample"
}
port_name = "ecs-sample"
discovery_name = "ecs-sample"
}]
}
load_balancer = {
service = {
target_group_arn = "arn:aws:elasticloadbalancing:eu-west-1:1234567890:targetgroup/bluegreentarget1/209a844cd01825a4"
container_name = "ecs-sample"
container_port = 80
}
}
subnet_ids = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"]
security_group_ingress_rules = {
alb_3000 = {
description = "Service port"
from_port = local.container_port
ip_protocol = "tcp"
referenced_security_group_id = "sg-12345678"
}
}
security_group_egress_rules = {
all = {
ip_protocol = "-1"
cidr_ipv4 = "0.0.0.0/0"
}
}
}
}
tags = {
Environment = "Development"
Project = "Example"
}
}
Known limitations (Terraform/OpenTofu, not this module)
A few requests come up again and again and cannot be implemented by this
module, or by any module: Terraform requires lifecycle arguments to be
literal values inside the resource block.
hashicorp/terraform#18367
has been open since 2018,
#22544 since 2019, and
opentofu/opentofu#1329 is
the same request for OpenTofu.
- Terraform reverts the task definition my pipeline just deployed - Native
options: have the pipeline update the Terraform configuration instead of the
ECS API, or fork and add
ignore_changes = [task_definition]. - ECS service desired_count keeps resetting - Native options: leave
desired_countout of the configuration, or fork and addignore_changes = [desired_count].
Compliance.tf serves this module with
these rules applied at download time, on top of whatever your organization
already has enabled there. Inputs and outputs do not change; the source line
does. Drop the version argument and pin the release you use by adding
&version= and that release number to the URL. To get started, register a free
compliance.tf account and configure an access token:
source = "https://registry.compliance.tf/terraform-aws-modules/ecs/aws?add_rules=lifecycle_ignore_deployed_artifacts,lifecycle_ignore_scaling_changes"
The full workaround for each item above, and the exact diff each rule makes, are in the compliance.tf docs for this module. To preview a diff without an account, open this module in the Rules Playground.
Disclosure: written by this module's maintainer, who also builds compliance.tf.
Examples
- ECS cluster w/ integrated service(s)
- ECS container definition
- ECS cluster w/ EC2 Autoscaling capacity provider
- ECS express service
- ECS cluster w/ Fargate capacity provider
- ECS cluster w/ ECS managed instances capacity provider
Authors
Module is maintained by Anton Babenko with help from these awesome contributors.
License
Apache-2.0 Licensed. See LICENSE.