• Stars
    star
    116
  • Rank 296,060 (Top 6 %)
  • Language HCL
  • License
    BSD 3-Clause "New...
  • Created almost 6 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Creates an ECS Service.

Terraform module that creates an ECS service with the following features

  • Runs an ECS service with or without an AWS load balancer.
  • Stream logs to a CloudWatch log group encrypted with a KMS key.
  • Associate multiple target groups with Network Load Balancers (NLB) and Application Load Balancers (ALB).
  • Supports running ECS tasks on EC2 instances or Fargate.

Default container definition (hello world app)

We create an initial task definition using the golang:alpine image as a way to validate the initial infrastructure is working: visiting the site shows a simple Go hello world page listening on two configurable ports. This is meant to get a proof of concept instance up and running and to help with testing.

If you want to customize the listener ports for the hello world app, you can modify the hello_world_container_ports variable.

In production usage, we expect deployment tooling to manage the container definitions going forward, not Terraform.

Usage

ECS service associated with an Application Load Balancer (ALB)

module "app_ecs_service" {
  source = "trussworks/ecs-service/aws"

  name        = "app"
  environment = "prod"

  ecs_cluster                   = aws_ecs_cluster.mycluster
  ecs_vpc_id                    = module.vpc.vpc_id
  ecs_subnet_ids                = module.vpc.private_subnets
  kms_key_id                    = aws_kms_key.main.arn
  tasks_desired_count           = 2

  associate_alb      = true
  alb_security_group = module.security_group.id
  lb_target_groups =
  [
    {
      container_port              = 8443
      container_health_check_port = 8443
      lb_target_group_arn         = module.alb.arn
    }
  ]
}

ECS Service associated with a Network Load Balancer(NLB)

module "app_ecs_service" {
  source = "trussworks/ecs-service/aws"

  name        = "app"
  environment = "prod"

  ecs_cluster                   = aws_ecs_cluster.mycluster
  ecs_vpc_id                    = module.vpc.vpc_id
  ecs_subnet_ids                = module.vpc.private_subnets
  kms_key_id                    = aws_kms_key.main.arn
  tasks_desired_count           = 2

  associate_nlb          = true
  nlb_subnet_cidr_blocks = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]

  lb_target_groups =
  [
    {
      container_port              = 8443
      container_health_check_port = 8080
      lb_target_group_arn         = module.nlb.arn
    }
  ]
}

ECS Service without any AWS load balancer

module "app_ecs_service" {
  source = "trussworks/ecs-service/aws"

  name        = "app"
  environment = "prod"

  ecs_cluster                   = aws_ecs_cluster.mycluster
  ecs_vpc_id                    = module.vpc.vpc_id
  ecs_subnet_ids                = module.vpc.private_subnets
  kms_key_id                    = aws_kms_key.main.arn
}

Requirements

Name Version
terraform >= 1.0
aws >= 3.34

Providers

Name Version
aws >= 3.34

Modules

No modules.

Resources

Name Type
aws_cloudwatch_log_group.main resource
aws_cloudwatch_metric_alarm.alarm_cpu resource
aws_cloudwatch_metric_alarm.alarm_mem resource
aws_ecs_service.main resource
aws_ecs_task_definition.main resource
aws_iam_policy.task_role_ecs_exec resource
aws_iam_role.task_execution_role resource
aws_iam_role.task_role resource
aws_iam_role_policy.instance_role_policy resource
aws_iam_role_policy.task_execution_role_policy resource
aws_iam_role_policy_attachment.task_role_ecs_exec resource
aws_security_group.ecs_sg resource
aws_security_group_rule.app_ecs_allow_health_check_from_alb resource
aws_security_group_rule.app_ecs_allow_health_check_from_nlb resource
aws_security_group_rule.app_ecs_allow_https_from_alb resource
aws_security_group_rule.app_ecs_allow_outbound resource
aws_security_group_rule.app_ecs_allow_tcp_from_nlb resource
aws_ecs_task_definition.main data source
aws_iam_policy_document.ecs_assume_role_policy data source
aws_iam_policy_document.instance_role_policy_doc data source
aws_iam_policy_document.task_execution_role_policy_doc data source
aws_iam_policy_document.task_role_ecs_exec data source
aws_region.current data source

Inputs

Name Description Type Default Required
additional_security_group_ids In addition to the security group created for the service, a list of security groups the ECS service should also be added to. list(string) [] no
alb_security_group Application Load Balancer (ALB) security group ID to allow traffic from. string "" no
assign_public_ip Whether this instance should be accessible from the public internet. Default is false. bool false no
associate_alb Whether to associate an Application Load Balancer (ALB) with the ECS service. bool false no
associate_nlb Whether to associate a Network Load Balancer (NLB) with the ECS service. bool false no
cloudwatch_alarm_actions The list of actions to take for cloudwatch alarms list(string) [] no
cloudwatch_alarm_cpu_enable Enable the CPU Utilization CloudWatch metric alarm bool true no
cloudwatch_alarm_cpu_threshold The CPU Utilization threshold for the CloudWatch metric alarm number 80 no
cloudwatch_alarm_mem_enable Enable the Memory Utilization CloudWatch metric alarm bool true no
cloudwatch_alarm_mem_threshold The Memory Utilization threshold for the CloudWatch metric alarm number 80 no
cloudwatch_alarm_name Generic name used for CPU and Memory Cloudwatch Alarms string "" no
container_definitions Container definitions provided as valid JSON document. Default uses golang:alpine running a simple hello world. string "" no
container_image The image of the container. string "golang:alpine" no
container_volumes Volumes that containers in your task may use. list( object({ name = string }) ) [] no
ec2_create_task_execution_role Set to true to create ecs task execution role to ECS EC2 Tasks. bool false no
ecr_repo_arns The ARNs of the ECR repos. By default, allows all repositories. list(string) [ "*" ] no
ecs_cluster ECS cluster object for this task. object({ arn = string name = string }) n/a yes
ecs_exec_enable Enable the ability to execute commands on the containers via Amazon ECS Exec bool false no
ecs_instance_role The name of the ECS instance role. string "" no
ecs_subnet_ids Subnet IDs for the ECS tasks. list(string) n/a yes
ecs_use_fargate Whether to use Fargate for the task definition. bool false no
ecs_vpc_id VPC ID to be used by ECS. string n/a yes
environment Environment tag, e.g prod. string n/a yes
fargate_platform_version The platform version on which to run your service. Only applicable when using Fargate launch type. string "LATEST" no
fargate_task_cpu Number of cpu units used in initial task definition. Default is minimum. number 256 no
fargate_task_memory Amount (in MiB) of memory used in initial task definition. Default is minimum. number 512 no
health_check_grace_period_seconds Grace period within which failed health checks will be ignored at container start. Only applies to services with an attached loadbalancer. number null no
hello_world_container_ports List of ports for the hello world container app to listen on. The app currently supports listening on two ports. list(number) [ 8080, 8081 ] no
kms_key_id KMS customer managed key (CMK) ARN for encrypting application logs. string n/a yes
lb_target_groups List of load balancer target group objects containing the lb_target_group_arn, container_port and container_health_check_port. The container_port is the port on which the container will receive traffic. The container_health_check_port is an additional port on which the container can receive a health check. The lb_target_group_arn is either Application Load Balancer (ALB) or Network Load Balancer (NLB) target group ARN tasks will register with. list( object({ container_port = number container_health_check_port = number lb_target_group_arn = string } ) ) [] no
logs_cloudwatch_group CloudWatch log group to create and use. Default: /ecs/{name}-{environment} string "" no
logs_cloudwatch_retention Number of days you want to retain log events in the log group. number 90 no
manage_ecs_security_group Enable creation and management of the ECS security group and rules bool true no
name The service name. string n/a yes
nlb_subnet_cidr_blocks List of Network Load Balancer (NLB) CIDR blocks to allow traffic from. list(string) [] no
service_registries List of service registry objects as per https://www.terraform.io/docs/providers/aws/r/ecs_service.html#service_registries-1. List can only have a single object until hashicorp/terraform-provider-aws#9573 is resolved. list(object({ registry_arn = string container_name = string container_port = number port = number })) [] no
target_container_name Name of the container the Load Balancer should target. Default: {name}-{environment} string "" no
tasks_desired_count The number of instances of a task definition. number 1 no
tasks_maximum_percent Upper limit on the number of running tasks. number 200 no
tasks_minimum_healthy_percent Lower limit on the number of running tasks. number 100 no

Outputs

Name Description
awslogs_group Name of the CloudWatch Logs log group containers should use.
awslogs_group_arn ARN of the CloudWatch Logs log group containers should use.
ecs_security_group_id Security Group ID assigned to the ECS tasks.
ecs_service_id ARN of the ECS service.
task_definition_arn Full ARN of the Task Definition (including both family and revision).
task_definition_family The family of the Task Definition.
task_execution_role The role object of the task execution role that the Amazon ECS container agent and the Docker daemon can assume.
task_execution_role_arn The ARN of the task execution role that the Amazon ECS container agent and the Docker daemon can assume.
task_execution_role_name The name of the task execution role that the Amazon ECS container agent and the Docker daemon can assume.
task_role The IAM role object assumed by Amazon ECS container tasks.
task_role_arn The ARN of the IAM role assumed by Amazon ECS container tasks.
task_role_name The name of the IAM role assumed by Amazon ECS container tasks.

Upgrade Path

5.x.x to 6.0.0

In versions 5.x.x and prior, the following resources existed as arrays (toggled by a count meta-argument). With 6.0.0, each pair has been merged into a single resource.

  • aws_cloudwatch_metric_alarm.alarm_cpu[0] xor aws_cloudwatch_metric_alarm.alarm_cpu_no_lb[0] -> aws_cloudwatch_metric_alarm.alarm_cpu
  • aws_cloudwatch_metric_alarm.alarm_mem[0] xor aws_cloudwatch_metric_alarm.alarm_mem_no_lb[0] -> aws_cloudwatch_metric_alarm.alarm_mem
  • aws_ecs_service.main[0] xor aws_ecs_service.main_no_lb[0] -> aws_ecs_service.main

To upgrade to 6.0.0, you will need to perform a terraform state mv for any affected resources to avoid destruction and recreation. Alternatively, you can let Terraform delete/recreate the deployed resources.

For example, if you are using this module and naming it example, you could run one or more of the commands as appropriate given your environment:

# Example alarm_cpu state mv commands (pick the relevant one for your environment):
terraform state mv 'module.example.aws_cloudwatch_metric_alarm.alarm_cpu[0]' 'module.example.aws_cloudwatch_metric_alarm.alarm_cpu'
terraform state mv 'module.example.aws_cloudwatch_metric_alarm.alarm_cpu_no_lb[0]' 'module.example.aws_cloudwatch_metric_alarm.alarm_cpu'

# Example alarm_mem state mv commands (pick the relevant one for your environment):
terraform state mv 'module.example.aws_cloudwatch_metric_alarm.alarm_mem[0]' 'module.example.aws_cloudwatch_metric_alarm.alarm_mem'
terraform state mv 'module.example.aws_cloudwatch_metric_alarm.alarm_mem_no_lb[0]' 'module.example.aws_cloudwatch_metric_alarm.alarm_mem'

# Example main state mv commands (pick the relevant one for your environment):
terraform state mv 'module.example.aws_ecs_service.main[0]' 'module.example.aws_ecs_service.main'
terraform state mv 'module.example.aws_ecs_service.main_no_lb[0]' 'module.example.aws_ecs_service.main'

5.x.x to 5.1.1

With 5.1.1, the hashicorp/aws provider must be a minimum version of 3.0. It no longer has a maximum version. Therefore any code calling this will need to accomodate for that minimum version change.

4.0.0 to 5.0.0

Prior to 5.x, the hashicorp/aws provider required the use of version 2.70. 5.x changes the hashicorp/aws provider so that it can be greater than or equal to 2.70, but must be less than 4.0. Therefore any code calling this will need to accomodate for that version change.

3.x.x to 4.0.0

3.x.x uses Terraform 0.12.x and 4.0.0 uses Terraform 0.13.x, so this requires upgrading any code that uses this module to Terraform 0.13.x.

2.x.x to 3.0.0

In 3.0.0 the module added support for multiple load balancer target groups. To support this change, container_port, container_health_check_port and lb_target_group are being replaced with lb_target_groups.

Without a load balancer

If you are using this module without an ALB or NLB then you can remove any references to container_port, container_health_check_port and lb_target_group if you were doing so.

Using with ALB or NLB target groups

If you are using an NLB or NLB target groups with this module then you will need replace the values of container_port, container_health_check_port and lb_target_group with

Below is an example of how the module would be instantiated prior to version 3.0.0:

module "app_ecs_service" {
  source = "trussworks/ecs-service/aws"
  ...
  container_port                  = 8443
  container_health_check_port     = 8080
  lb_target_group_arn             = module.alb.arn
  ...
}

In 3.0.0 the same example will look like the following

module "app_ecs_service" {
  source = "trussworks/ecs-service/aws"
  ...
  lb_target_groups =
  [
    {
      container_port                  = 8443
      container_health_check_port     = 8080
      lb_target_group_arn             = module.alb.arn
    }
  ]
  ...
}

2.0.0 to 2.1.0

In 2.1.0 KMS log encryption is required by default. This requires that you create and attach a new AWS KMS key ARN. As an example here is how to set that up (please review on your own):

data "aws_iam_policy_document" "cloudwatch_logs_allow_kms" {
  statement {
    sid    = "Enable IAM User Permissions"
    effect = "Allow"

    principals {
      type = "AWS"
      identifiers = [
        "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root",
      ]
    }

    actions = [
      "kms:*",
    ]
    resources = ["*"]
  }

  statement {
    sid    = "Allow logs KMS access"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["logs.us-west-2.amazonaws.com"]
    }

    actions = [
      "kms:Encrypt*",
      "kms:Decrypt*",
      "kms:ReEncrypt*",
      "kms:GenerateDataKey*",
      "kms:Describe*"
    ]
    resources = ["*"]
  }
}

resource "aws_kms_key" "main" {
  description         = "Key for ECS log encryption"
  enable_key_rotation = true

  policy = data.aws_iam_policy_document.cloudwatch_logs_allow_kms.json
}

NOTE: Best practice is to use a separate KMS key per ECS Service. Do not re-use KMS keys if it can be avoided.

1.15.0 to 2.0.0

v2.0.0 of this module is built against Terraform v0.12. In addition to requiring this upgrade, the v1.15.0 version of the module took the name of the ECS cluster as a parameter; v2.0.0 takes the actual object of the ECS cluster as a parameter instead. You will need to update previous instances of this module with the altered parameter.

Developer Setup

Install dependencies (macOS)

brew install pre-commit go terraform terraform-docs

More Repositories

1

terraform-aws-config

Enables AWS Config and adds managed config rules with good defaults.
HCL
226
star
2

terraform-layout-example

Example of a Truss Terraform project
HCL
175
star
3

react-uswds

USWDS 3.0 components built in React
TypeScript
167
star
4

Engineering-Playbook

Repository of documentation on how we do Software Engineering at TrussWorks.
JavaScript
134
star
5

terraform-aws-wafv2

Creates a WAF using AWS WAFv2 and AWS Managed Rule Sets
HCL
101
star
6

terraform-aws-bootstrap

🐓 🥚 Terraform for your Terraform remote state configuration
HCL
82
star
7

terraform-aws-s3-private-bucket

Creates a private, encrypted, versioned S3 bucket with good defaults.
HCL
76
star
8

terraform-aws-logs

Creates and configures an S3 bucket for storing AWS logs.
HCL
73
star
9

terraform-aws-waf

Configures an AWS Web Application Firewall.
HCL
61
star
10

terraform-aws-ses-domain

Configures a domain hosted on Route53 to work with AWS Simple Email Service (SES).
HCL
58
star
11

terraform-aws-ecs-cluster

Creates an ECS cluster backed by an Auto Scaling Group
HCL
58
star
12

terraform-aws-ou-scp

Combines AWS Organizations Service Control Policies (SCP)
HCL
50
star
13

distributed-playbook

A playbook about how we work together as a distributed team.
49
star
14

terraform-aws-cloudtrail

Creates and configures AWS CloudTrail
HCL
45
star
15

terraform-aws-s3-anti-virus

Creates and configures Anti-Virus Scanning of S3 Buckets.
HCL
38
star
16

terraform-module-template

Template repo with Terraform module basics
Makefile
23
star
17

terraform-aws-guardduty-notifications

Enables AWS GuardDuty and sends findings to an SNS topic.
HCL
22
star
18

truss-aws-tools

Assortment of AWS Lambda functions and CLI based tools for working with AWS.
Go
18
star
19

terraform-aws-cloudtrail-alarms

Provides CIS Benchmark-compliant Cloudwatch alarms for Cloudtrail events.
HCL
18
star
20

formik-to-react-hook-form-migration-guide

A guide for migrating projects to from Formik to React Hook Form
15
star
21

terraform-aws-destroy-default-vpc

Default VPC resource management for AWS Accounts
HCL
14
star
22

truss-interview

Truss software engineering interview
13
star
23

TPDWeakProxy

An NSProxy object for turning strong references into weak references.
Objective-C
12
star
24

terraform-aws-nlb-containers

Creates a Network Load Balancer (NLB) for serving an ECS backed service.
HCL
12
star
25

terraform-aws-mfa

Enforces MFA on an AWS account
HCL
11
star
26

terraform-aws-iam-sleuth

Lambda-based auditing tool for AWS Access keys
Python
10
star
27

setup-new-aws-user

Creates an MFA token and new access keys for an AWS user.
Go
10
star
28

terraform-aws-org-scp

Enables AWS Organizations Service Control Policies (SCP) with good defaults
HCL
10
star
29

terraform-aws-health-notifications

Health Notifications
HCL
9
star
30

accessibility

a11y resources and guild work
7
star
31

terraform-aws-saml-cognito

Creates AWS Cognito resources for using SAML authentication
HCL
6
star
32

pre-commit-hooks

Common pre-commit hooks
Shell
6
star
33

terraform-aws-rds-snapshot-cleaner

RDS Snapshot Cleaner
HCL
5
star
34

terraform-aws-lambda-ecs-manager

Creates a Lambda function to manage ECS services in Fargate
Python
5
star
35

terraform-aws-trusted-advisor-refresh

Trusted Advisor Refresh
HCL
5
star
36

terraform-aws-s3-file-uploads

Creates infrastructure needed to handle AWS S3 file uploads
HCL
5
star
37

dockling

Exercises for learning about docker
Go
5
star
38

terraform-aws-config-notifications

Config Notifications
HCL
5
star
39

terraform-aws-acm-cert

Creates a TLS certificate using AWS ACM for domains hosted on Route53.
HCL
5
star
40

terraform-aws-sftp

Configures an AWS SFTP Server (aka AWS Transfer Server)
HCL
5
star
41

terraform-aws-iam-ecr-ci

Creates an IAM user/group for CI to use to push images to ECR
HCL
4
star
42

trussels-guide

SCSS
4
star
43

terraform-aws-iam-user-group

Creates an IAM group with users where the group is only allowed to assume roles defined.
HCL
4
star
44

terraform-aws-route53-query-logs

Configures query logging on an existing Route53 hosted zones.
HCL
4
star
45

terraform-aws-route53-health-check

Route53 Health Check
HCL
4
star
46

terraform-aws-alb-web-containers

Creates an ALB for serving a web app.
HCL
4
star
47

terraform-aws-ecr-repo

Provides a basic ECR repository configuration for a single container image.
HCL
3
star
48

terraform-aws-rds-notifications

RDS Notifications
HCL
3
star
49

unemployment-insurance-modernization-demo

A sample repository for UI modernization sample code
TypeScript
3
star
50

terraform-aws-root-login-notifications

Root Login Notifications
HCL
3
star
51

shared-actions

Home of shared github actions
3
star
52

terraform-aws-sftp-user

SFTP User for AWS Transfer Server
HCL
3
star
53

health-checker

Website Health Check
Go
3
star
54

research-design-playbook

Research and Design Playbook https://trussworks.github.io/research-design-playbook/
SCSS
3
star
55

ecr-scan

Go
3
star
56

terraform-aws-lambda

Terraform module for creating AWS Lambda jobs with appropriate log configurations.
HCL
3
star
57

logindotgov-oidc-py

OpenID Connect (OIDC) Relying Party client in Python for login.gov.
Python
3
star
58

hello-infra-draft

Experimenting with a "Hello, World" infrastructure story
HCL
2
star
59

tls-checker

Website TLS Version Check
Go
2
star
60

TPDMapsApp

An interface to external mapping applications on iOS.
Objective-C
2
star
61

docker-nuker

A docker image to nuke an AWS account and its contents via AWS-Nuke.
Dockerfile
2
star
62

terraform-aws-sso-group

Creates AWS IAM Identity Center resources
HCL
2
star
63

find-guardduty-user

Easily identify IAM users that have triggered GuardDuty findings.
Go
2
star
64

lambda-dependabot

lambda function to rerun failed dependabot runs
Python
2
star
65

Learning-Resources

A selection of resources that Trussels have found useful for sharing mental state and aspirations
2
star
66

terraform-aws-lambda-packerjanitor

Terraform module for deploying a lambda job to clean up abandoned Packer resources
HCL
2
star
67

terraform-aws-rds-cloudwatch-logs

RDS Cloudwatch Logs
HCL
2
star
68

terraform-aws-lambda-amiclean

Terraform module for deploying AWS resources needed for amicleaner lambda
HCL
2
star
69

infra-exercise-circleci

A repo for CircleCI related exercises by InfraSec
Go
2
star
70

terraform-aws-cloudtrail-event-notifications

CloudTrail Event Notifications
HCL
2
star
71

terraform-aws-iam-cross-acct-dest

Creates an IAM role to allow cross account assumption from specified source role.
HCL
2
star
72

terraform-aws-vpc-flow-logs

Configures VPC flow logs for the given VPC.
HCL
1
star
73

terraform-aws-lambda-ecr-scan

Terraform module for deploying a lambda to parse ECR scan findings
HCL
1
star
74

go-sample-api

A sample API using Go
Go
1
star
75

golang-cli-template

Template repo with golang CLI basics
Go
1
star
76

terraform-aws-iam-cross-acct-src

Creates an IAM role to allow cross account assumption to specified destination role.
HCL
1
star
77

terraform-aws-opensearch

A module that spins up an OpenSearch cluster.
HCL
1
star
78

prereqs

A tool to check your project prerequisites so your engineers don't have to.
Shell
1
star
79

terraform-github-repo

Manage Github repos with Terraform with good defaults
HCL
1
star
80

Truss-PQVP

Truss's entry for the CA PQVP DS-AD
JavaScript
1
star
81

sesh

Open Source Session Management for Golang
Go
1
star
82

linters

Open source custom Truss linters that can be shared across projects.
1
star
83

terraform-aws-iam-keys-check

IAM Keys Check
HCL
1
star
84

terraform-aws-slack-pivotal-tracker-bot

[DEPRECATED] Terraform module for deploying slack-pivotal-tracker-bot to AWS Lambda
HCL
1
star
85

terraform-aws-nlb-tg-to-alb

Sets up a Lambda function to update an NLB's target group to point at an ALB's IPs.
Python
1
star
86

affinity-groups-slackbot

We made this slackbot to allow folks to opt into private affinity groups (read: private channels) within a Slack workspace without having to out themselves or forcing a public point of contact for the group to out themselves.
Python
1
star
87

ecs-service-logs

ecs-service-logs is used to filter JSON-formatted log lines in CloudWatch
Go
1
star
88

terraform-aws-acm-cert-akamai-dns

Creates a TLS certificate using AWS ACM for domains hosted on Akamai.
HCL
1
star
89

ecs-scaleup

This repository provides a github action which can provision a self-hosted github runner via AWS ECS/Fargate
JavaScript
1
star