Skip to content

infrahouse/terraform-aws-ecs

Repository files navigation

terraform-aws-ecs

The module creates an Elastic Container Service and runs one docker image in it.

ECS.drawio.png

A user is expected to create a VPC, subnets (See the service network module if you need to do it), and a Route53 zone.

The module uses the infrahouse/website-pod/aws module to create a load balancer, autoscaling group, and update DNS.

Usage

Basically, you need to pass the docker image and subnets where to place a load balancer and autoscaling group.

The module will create an SSL certificate and a DNS record. If the dns_names is ["www"] and the zone is "domain.com", the module will create a record "www.domain.com". You can specify more than one DNS name, then the module will create DNS records for all of them and the certificate will list them as aliases. You can also specify an empty name - dns_names = ["", "www"] - if you want a popular setup https://domain.com + https://www.domain.com/.

For usage see how the module is used in the using tests in test_data/test_module.

module "httpd" {
  source  = "infrahouse/ecs/aws"
  version = "4.2.0"
  providers = {
    aws     = aws
    aws.dns = aws
  }
  load_balancer_subnets         = module.service-network.subnet_public_ids
  asg_subnets                   = module.service-network.subnet_private_ids
  dns_names                     = ["foo-ecs"]
  docker_image                  = "httpd"
  container_port                = 80
  service_name                  = var.service_name
  ssh_key_name                  = aws_key_pair.test.key_name
  zone_id                       = data.aws_route53_zone.cicd.zone_id
  internet_gateway_id           = module.service-network.internet_gateway_id
}

Mount EFS volume

The module can attach one or more EFS volumes to a container.

To do that, create the EFS volume with a mount point:

resource "aws_efs_file_system" "my-volume" {
  creation_token = "my-volume"
  tags = {
    Name = "my-volume"
  }
}

resource "aws_efs_mount_target" "my-volume" {
  for_each       = toset(var.subnet_private_ids)
  file_system_id = aws_efs_file_system.my-volume.id
  subnet_id      = each.key
}

Pass the volumes to the ECS module:

module "httpd" {
  source  = "infrahouse/ecs/aws"
  version = "4.2.0"
  providers = {
    aws     = aws
    aws.dns = aws
  }
...
  task_volumes = {
    "my-volume" : {
      file_system_id : aws_efs_file_system.my-volume.id
      container_path : "/mnt/"
    }
}

Requirements

Name Version
terraform ~> 1.5
aws ~> 5.56
cloudinit ~> 2.3

Providers

Name Version
aws ~> 5.56
cloudinit ~> 2.3

Modules

Name Source Version
pod registry.infrahouse.com/infrahouse/website-pod/aws 4.6.0
tcp-pod registry.infrahouse.com/infrahouse/tcp-pod/aws 0.1.2

Resources

Name Type
aws_appautoscaling_policy.ecs_policy resource
aws_appautoscaling_target.ecs_target resource
aws_cloudwatch_log_group.ecs resource
aws_ecs_capacity_provider.ecs resource
aws_ecs_cluster.ecs resource
aws_ecs_cluster_capacity_providers.ecs resource
aws_ecs_service.cloudwatch_agent_service resource
aws_ecs_service.ecs resource
aws_ecs_task_definition.cloudwatch_agent resource
aws_ecs_task_definition.ecs resource
aws_iam_policy.ecs_task_execution_logs_policy resource
aws_iam_role.cloudwatch_agent_task_role resource
aws_iam_role.ecs_task_execution_role resource
aws_iam_role_policy_attachment.cloudwatch_policy_attachment resource
aws_iam_role_policy_attachment.ecs_task_execution_policy resource
aws_iam_role_policy_attachment.ecs_task_execution_role_logs_policy resource
aws_iam_role_policy_attachment.ecs_task_execution_role_policy resource
aws_ami.ecs data source
aws_caller_identity.current data source
aws_ec2_instance_type.ecs data source
aws_iam_policy.ecs-task-execution-role-policy data source
aws_iam_policy_document.assume_role_policy data source
aws_iam_policy_document.ecs_cloudwatch_logs_policy data source
aws_iam_policy_document.instance_policy data source
aws_key_pair.ssh_key_pair data source
aws_region.current data source
aws_route53_zone.this data source
aws_subnet.selected data source
cloudinit_config.ecs data source

Inputs

Name Description Type Default Required
access_log_force_destroy Destroy S3 bucket with access logs even if non-empty bool false no
ami_id Image for host EC2 instances. If not specified, the latest Amazon image will be used. string null no
asg_health_check_grace_period ASG will wait up to this number of seconds for instance to become healthy number 300 no
asg_instance_type EC2 instances type string "t3.micro" no
asg_max_size Maximum number of instances in ASG. number 10 no
asg_min_size Minimum number of instances in ASG. number 2 no
asg_subnets Auto Scaling Group Subnets. list(string) n/a yes
assume_dns If True, create DNS records provided by var.dns_a_records. bool true no
autoscaling_metric Metric to base autoscaling on. Can be ECSServiceAverageCPUUtilization, ECSServiceAverageMemoryUtilization, ALBRequestCountPerTarget string "ECSServiceAverageCPUUtilization" no
autoscaling_target Target value for autoscaling_metric. number null no
autoscaling_target_cpu_usage If autoscaling_metric is ECSServiceAverageCPUUtilization, how much CPU an ECS service aims to use. number 80 no
cloudwatch_agent_config_path Path to cloudwatch agent config on host fs string "" no
cloudwatch_agent_container_resources Resourcces for cloudwatch agent container
object({
cpu = number
memory = number
})
{
"cpu": 128,
"memory": 256
}
no
cloudwatch_agent_image Cloudwatch agent image string "amazon/cloudwatch-agent:1.300037.1b602" no
cloudwatch_log_group CloudWatch log group to create and use. Default: /ecs/{name}-{environment} string null no
cloudwatch_log_group_retention Number of days you want to retain log events in the log group. number 90 no
container_command If specified, use this list of strings as a docker command. list(string) null no
container_cpu Number of CPU units that a container is going to use. number 200 no
container_healthcheck_command A shell command that a container runs to check if it's healthy. Exit code 0 means healthy, non-zero - unhealthy. string `"curl -f http://localhost/
container_memory Amount of RAM in megabytes the container is going to use. number 128 no
container_port TCP port that a container serves client requests on. number 8080 no
dns_names List of hostnames the module will create in var.zone_id. list(string) n/a yes
dockerSecurityOptions A list of strings to provide custom configuration for multiple security systems. Supported prefixes are 'label:', 'apparmor:', and 'credentialspec:' or you can specify 'no-new-privileges' list(string) null no
docker_image A container image that will run the service. string n/a yes
enable_cloudwatch_agent Add cloudwatch agent service to ECS cluster with DAEMON type bool false no
enable_cloudwatch_logs Enable Cloudwatch logs. If enabled, log driver will be awslogs. bool false no
enable_container_insights Enable container insights feature on ECS cluster. bool false no
environment Name of environment. string "development" no
extra_files Additional files to create on a host EC2 instance.
list(object({
content = string
path = string
permissions = string
}))
[] no
healthcheck_interval Number of seconds between checks number 10 no
healthcheck_path Path on the webserver that the elb will check to determine whether the instance is healthy or not. string "/index.html" no
healthcheck_response_code_matcher Range of http return codes that can match string "200-299" no
healthcheck_timeout Healthcheck timeout number 5 no
idle_timeout The time in seconds that the connection is allowed to be idle. number 60 no
internet_gateway_id Internet gateway id. Usually created by 'infrahouse/service-network/aws' string null no
lb_type Load balancer type. ALB or NLB string "alb" no
load_balancer_subnets Load Balancer Subnets. list(string) n/a yes
managed_draining Enables or disables a graceful shutdown of instances without disturbing workloads. bool true no
managed_termination_protection Enables or disables container-aware termination of instances in the auto scaling group when scale-in happens. bool true no
on_demand_base_capacity If specified, the ASG will request spot instances and this will be the minimal number of on-demand instances. number null no
root_volume_size Root volume size in EC2 instance in Gigabytes number 30 no
service_health_check_grace_period_seconds Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 2147483647. number null no
service_name Service name. string n/a yes
ssh_cidr_block CIDR range that is allowed to SSH into the backend instances string null no
ssh_key_name ssh key name installed in ECS host instances. string n/a yes
task_desired_count Number of containers the ECS service will maintain. number 1 no
task_efs_volumes Map name->{file_system_id, container_path} of EFS volumes defined in task and available for containers to mount.
map(
object(
{
file_system_id : string
container_path : string
}
)
)
{} no
task_environment_variables Environment variables passed down to a task.
list(
object(
{
name : string
value : string
}
)
)
[] no
task_ipc_mode The IPC resource namespace to use for the containers in the task. See https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_TaskDefinition.html string null no
task_local_volumes Map name->{host_path, container_path} of local volumes defined in task and available for containers to mount.
map(
object(
{
host_path : string
container_path : string
}
)
)
{} no
task_max_count Highest number of tasks to run number 10 no
task_min_count Lowest number of tasks to run number 1 no
task_role_arn Task Role ARN. The role will be assumed by a container. string null no
task_secrets Secrets to pass to a container. A name will be the environment variable. valueFrom is a secret ARN.
list(
object(
{
name : string
valueFrom : string
}
)
)
[] no
users A list of maps with user definitions according to the cloud-init format any null no
zone_id Zone where DNS records will be created for the service and certificate validation. string n/a yes

Outputs

Name Description
asg_arn Autoscaling group ARN created for the ECS service.
asg_name Autoscaling group name created for the ECS service.
dns_hostnames DNS hostnames where the ECS service is available.
load_balancer_dns_name Load balancer DNS name.
service_arn ECS service ARN.
task_execution_role_arn Task execution role is a role that ECS agent gets.
task_execution_role_name Task execution role is a role that ECS agent gets.