This module is an opinionated implementation of a Fargate service with an application load balancer, serving HTTP requests. This is useful for creating an API or web service. It contains autoscaling off CPU load, health checking, alerting for when the service isn't healthy, and neatly tags everything along the way. Security groups are wired up with principal of least privilege access to resources.
It fronts all traffic with HTTPS on port 443, forwarding to the configured container_ports
(default is 80.) This module outputs the ALB DNS name, which can be used to create a CNAME record in Route 53. Port 80 serves a permanent redirect to 443.
For creating a Fargate service without a built-in application load balancer, see the terraform-aws-fargate-service module. This is also useful when deploying an application behind a Network Load Balancer.
Example deployable applications can be found in the examples/ directory.
This module creates security groups (ie firewalls) for communicating with both the load balancer, and the service over the network. By default, it allows all traffic originating from the container (in other words, all egress
traffic is allowed), and inbound traffic from the load balancer to the container on port 80 (or whatever container_ports
is set to.) However, if you would like to communicate inbound to the load balancer from another service, you must create an aws_security_group_rule
resource referencing the load balancer's security group. The module-created security group is available as the output lb_sg_id
.
Additionally, this module creates an IAM role for the Fargate service to authorize access to AWS resources. By default, these services get no permissions. To add permissions to an AWS resource, create an aws_iam_policy
resource and attach the policy to the role using an aws_iam_role_policy_attachment
resource. The module-created IAM role name is available as the output task_role_name
from the module.
If you get an error like below,
Error: InvalidParameterException: The container module-test-staging does not exist in the task definition.
status code: 400, request id: a1c206cc-c593-455c-8ac2-b198956e9447 "module-test-staging"
on .terraform/modules/web.fargate_service/main.tf line 28, in resource "aws_ecs_service" "service":
28: resource "aws_ecs_service" "service" {
This is due to this module making some assumptions about the name of the container to connect networking for the load balancer. The default is set to ${var.name}-${var.environment}
when deploying a task definition using Mixmax's tooling. However, you can override this behavior. Find the name
value in your task definition's container definition, and set the container_name_override
parameter to this module for overriding the name used.
Manually with terraform-docs
, something like this:
terraform-docs md document . >> README.md
# and then edit out the old stuff
No requirements.
The following providers are used by this module:
- aws
The following input variables are required:
Description: The environment to deploy into. Some valid values are production, staging, engineering.
Type: string
Description: A list of subnet IDs to use for instantiating the load balancer.
Type: list(string)
Description: The name of the application to launch
Type: string
Description: The name of the service this application is associated with, ie 'send' if the application is 'send-worker'
Type: string
Description: A list of subnet IDs to use for instantiating the Fargate service. Tasks will be deployed into these subnets.
Type: list(string)
Description: The ARNs of Amazon Certificate Manager certificates to use with the HTTPS listener on the load balancer. You must provide at least one.
Type: list(string)
The following input variables are optional (have default values):
Description: This parameter is a list of the SNS topic ARNs. This is used to send alarm notifications. This is REQUIRED for production deployments!
Type: list(string)
Default: []
Description: The capacity provider (supported by the configured cluster) to use to provision tasks for the service
Type:
list(object({
capacity_provider = string
base = number
weight = number
}))
Default: []
Description: The number of times a metric must exceed thresholds before an alarm triggers. For example, if period
is set to 60 seconds, and this is set to 2, a given threshold must have been exceeded twice over 120 seconds.
Type: number
Default: 1
Description: The container name is used for networking the target group to the container instances; set this field to override the container name
Type: string
Default: ""
Description: A list of ports the container listens on. Most Mixmax Docker images 'EXPOSE' port 8080.
Type: list(number)
Default:
[
8080
]
Description: The CPU percentage to be considered 'high' for autoscaling purposes.
Type: number
Default: 70
Description: The CPU percentage to be considered 'low' for autoscaling purposes. This was set to a 'safe' value to prevent scaling down when it's not a good idea, but please adjust this higher for your app if possible.
Type: number
Default: 30
Description: Whether CPU-based autoscaling should be turned on or off
Type: bool
Default: true
Description: A mapping of custom tags to add to the generated resources.
Type: map(string)
Default: {}
Description: The upper limit (as a percentage of the service's desiredCount) of the number of running tasks that can be running in a service during a deployment.
Type: number
Default: 200
Description: Extra load balancer configurations; used when you want one ECS service fronted by multiple load balancers.
Type: list(object({ target_group_arn = string, container_name = string, container_port = number }))
Default: []
Description: This parameter allows you to set to the Fargate service name explicitly. This is useful in cases where you need something other than the default {var.name}-{var.environment} naming convention
Type: string
Default: ""
Description: The load balancer health check grace period in seconds. This defines how long ECS will ignore failing load balancer chcecks on newly instantiated tasks.
Type: number
Default: 90
Description: The path the LB will GET to determine if a host is healthy. For example, /health-check or /status. This health check should only validate that the app itself is online, not necessarily that any downstream dependent services are also online.
Type: string
Default: "/health/elb"
Description: The count of 5xx responses per second from the configured load balancer that should trigger alarms
Type: number
Default: 25
Description: The connection idle timeout value for the created load balancer
Type: number
Default: 60
Description: Whether the service is public or internal only.
Type: bool
Default: false
Description: A list of strings of CIDRs to allow inbound to the load balancer
Type: list(string)
Default: []
Description: A list of strings of Security Group IDs to allow inbound to the load balancer.
Type: list(string)
Default: []
Description: The bucket used to store LB logs
Type: string
Default: null
Description: This variable defines if new requests are routed round_robin or least_outstanding_requests
Type: string
Default: "least_outstanding_requests"
Description: The maximum capacity for a scaling Fargate service.
Type: number
Default: 8
Description: The minimum capacity for a scaling Fargate service.
Type: number
Default: 2
Description: Whether to set the public security group rule allowing all access. This is only used on public load balancers and is useful to set to 'false' if you want to create an internet-facing load balancer that only accepts traffic from certain sources, ie Github -> Jenkins but nothing else over the public internet.
Type: bool
Default: true
Description: The task definition family:revision or full ARN to deploy on first run to the Fargate service. If you are deploying software with Jenkins, you can ignore this; this is used with task definitions that are managed in Terraform. If unset, the first run will use an Nginx 'hello-world' task def. Terraform will not update the task definition in the service if this value has changed.
Type: string
Default: ""
Description: This parameter defines the number of seconds during which a newly registered Fargate task receives an increasing share of the traffic to the target group, giving it time to 'warm up'. This variable is incompatible with the load balancer least_outstanding_requests
routing algorithm.
Type: number
Default: 0
The following outputs are exported:
Description: The ARN of the created ALB
Description: The DNS name of the created ALB. Used to create a CNAME in your local zone to point to the created load balancer.
Description: The ARN of the HTTPS ALB listener
Description: The name of the CloudWatch log group
Description: The ARN suffix of the application load balancer. Useful for Cloudwatch alarms
Description: The ID of the Security Group attached to the LB
Description: The ARN of the IAM Role created for the Fargate service
Description: The name of the IAM Role created for the Fargate service
Description: The ID of the Security Group attached to the ECS tasks
Description: The ARN of the target group in the application load balancer.
Description: The ARN suffixes of the target group in the application load balancer. Useful for Cloudwatch alarms
Description: The Zone ID that the ALB resides in. Useful for creating Route53 records with failover behaviour.