Auto Scaling Group
Overview
This service contains code to deploy Auto Scaling Groups on AWS.
ASG architecture
Features
- Load balancer (ELB) integration
- Listener Rules
- Health checks
- Zero-downtime rolling deployment
- Route53 record
Learn
note
This repo is a part of the Gruntwork Service Catalog, a collection of reusable, battle-tested, production ready infrastructure code. If you’ve never used the Service Catalog before, make sure to read How to use the Gruntwork Service Catalog!
Under the hood, this is all implemented using Terraform modules from the Gruntwork terraform-aws-asg repo. If you are a subscriber and don’t have access to this repo, email support@gruntwork.io.
- ASG Documentation: Amazon’s docs for ASG that cover core concepts such as launch templates, launch configuration and auto scaling groups.
- User Data
Deploy
Non-production deployment (quick start for learning)
If you just want to try this repo out for experimenting and learning, check out the following resources:
- examples/for-learning-and-testing folder: The
examples/for-learning-and-testing
folder contains standalone sample code optimized for learning, experimenting, and testing (but not direct production usage).
Production deployment
If you want to deploy this repo in production, check out the following resources:
- examples/for-production folder: The
examples/for-production
folder contains sample code optimized for direct usage in production. This is code from the Gruntwork Reference Architecture, and it shows you how we build an end-to-end, integrated tech stack on top of the Gruntwork Service Catalog.
Reference
- Inputs
- Outputs
Required
ami
string(required)The ID of the AMI to run on each instance in the ASG. The AMI needs to have ec2-baseline
installed, since by default it will run start_ec2_baseline
on the User Data.
ami_filters
object(required)Properties on the AMI that can be used to lookup a prebuilt AMI for use with the Bastion Host. You can build the AMI using the Packer template bastion-host.json. Only used if var.ami is null. One of var.ami or ami_filters
is required. Set to null if passing the ami ID directly.
object({
# List of owners to limit the search. Set to null if you do not wish to limit the search by AMI owners.
owners = list(string)
# Name/Value pairs to filter the AMI off of. There are several valid keys, for a full reference, check out the
# documentation for describe-images in the AWS CLI reference
# (https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html).
filters = list(object({
name = string
values = list(string)
}))
})
instance_type
string(required)The type of instance to run in the ASG (e.g. t3.medium)
max_size
number(required)The maximum number of EC2 Instances to run in this ASG
min_elb_capacity
number(required)Wait for this number of EC2 Instances to show up healthy in the load balancer on creation.
min_size
number(required)The minimum number of EC2 Instances to run in this ASG
name
string(required)The name for the ASG and all other resources created by these templates.
subnet_ids
list(required)The list of IDs of the subnets in which to deploy ASG. The list must only contain subnets in vpc_id
.
list(string)
vpc_id
string(required)The ID of the VPC in which to deploy the Auto Scaling Group
Optional
alarm_sns_topic_arns_us_east_1
list(optional)A list of SNS topic ARNs to notify when the health check changes to ALARM, OK, or INSUFFICIENT_DATA state. Note: these SNS topics MUST be in us-east-1! This is because Route 53 only sends CloudWatch metrics to us-east-1, so we must create the alarm in that region, and therefore, can only notify SNS topics in that region.
list(string)
[]
alarms_sns_topic_arn
list(optional)The ARNs of SNS topics where CloudWatch alarms (e.g., for CPU, memory, and disk space usage) should send notifications. Also used for the alarms if the Jenkins backup job fails.
list(string)
[]
allow_inbound_from_cidr_blocks
list(optional)allow_inbound_from_security_group_ids
list(optional)allow_ssh_from_cidr_blocks
list(optional)The CIDR blocks from which to allow SSH access
list(string)
[]
allow_ssh_security_group_ids
list(optional)The security group IDs from which to allow SSH access
list(string)
[]
cloud_init_parts
map(optional)Cloud init scripts to run on the ASG instances during boot. See the part blocks in https://www.terraform.io/docs/providers/template/d/cloudinit_config.html for syntax
map(object({
filename = string
content_type = string
content = string
}))
{}
cloudwatch_log_group_kms_key_id
string(optional)The ID (ARN, alias ARN, AWS ID) of a customer managed KMS Key to use for encrypting log data.
null
cloudwatch_log_group_retention_in_days
number(optional)The number of days to retain log events in the log group. Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group#retention_in_days for all the valid values. When null, the log events are retained forever.
null
cloudwatch_log_group_tags
map(optional)Tags to apply on the CloudWatch Log Group, encoded as a map where the keys are tag keys and values are tag values.
map(string)
null
create_route53_entry
bool(optional)Set to true to create a DNS A record in Route 53 for this service.
false
custom_tags
list(optional)A list of custom tags to apply to the EC2 Instances in this ASG. Each item in this list should be a map with the parameters key, value, and propagate_at_launch.
list(object({
key = string
value = string
propagate_at_launch = bool
}))
[]
default_forward_target_group_arns
list(optional)The ARN of the Target Group to which to route traffic.
list(any)
[]
default_user
string(optional)The default OS user for the service AMI. For example, for AWS Ubuntu AMIs, the default OS user is 'ubuntu'.
ubuntu
desired_capacity
number(optional)The desired number of EC2 Instances to run in the ASG initially. Note that auto scaling policies may change this value. If you're using auto scaling policies to dynamically resize the cluster, you should actually leave this value as null.
null
domain_name
string(optional)The domain name to register in hosted_zone_id
(e.g. foo.example.com). Only used if create_route53_entry
is true.
null
enable_cloudwatch_alarms
bool(optional)Set to true to enable several basic CloudWatch alarms around CPU usage, memory usage, and disk space usage. If set to true, make sure to specify SNS topics to send notifications to using alarms_sns_topic_arn
.
true
enable_cloudwatch_log_aggregation
bool(optional)Set to true to add AIM permissions to send logs to CloudWatch. This is useful in combination with https://github.com/gruntwork-io/terraform-aws-monitoring/tree/master/modules/logs/cloudwatch-log-aggregation-scripts to do log aggregation in CloudWatch.
true
enable_cloudwatch_metrics
bool(optional)Set to true to add IAM permissions to send custom metrics to CloudWatch. This is useful in combination with https://github.com/gruntwork-io/terraform-aws-monitoring/tree/master/modules/agents/cloudwatch-agent to get memory and disk metrics in CloudWatch for your Auto Scaling Group
true
enable_fail2ban
bool(optional)Enable fail2ban to block brute force log in attempts. Defaults to true
true
enable_ip_lockdown
bool(optional)Enable ip-lockdown to block access to the instance metadata. Defaults to true
true
enable_route53_health_check
bool(optional)If set to true, use Route 53 to perform health checks on domain_name
.
false
enabled_metrics
list(optional)A list of metrics the ASG should enable for monitoring all instances in a group. The allowed values are GroupMinSize, GroupMaxSize, GroupDesiredCapacity, GroupInServiceInstances, GroupPendingInstances, GroupStandbyInstances, GroupTerminatingInstances, GroupTotalInstances.
list(string)
[]
external_account_ssh_grunt_role_arn
string(optional)Since our IAM users are defined in a separate AWS account, this variable is used to specify the ARN of an IAM role that allows ssh-grunt to retrieve IAM group and public SSH key info from that account.
""
fixed_response_listener_rules
map(optional)Listener rules for a fixed-response action. See comments below for information about the parameters.
map(any)
{}
forward_listener_rules
any(optional)Listener rules for a forward action that distributes requests among one or more target groups. By default, sends traffic to the target groups created for the ports in server_ports
. See comments below for information about the parameters.
{}
health_check_grace_period
number(optional)Time, in seconds, after an EC2 Instance comes into service before checking health.
300
hosted_zone_id
string(optional)The ID of the Route 53 Hosted Zone in which to create a DNS A record for the Auto Scaling Group. Optional if create_route53_entry = false.
null
iam_policy
map(optional)An object defining the policy to attach to iam_role_name
if the IAM role is going to be created. Accepts a map of objects, where the map keys are sids for IAM policy statements, and the object fields are the resources, actions, and the effect ('Allow' or 'Deny') of the statement. Ignored if iam_role_arn
is provided. Leave as null if you do not wish to use IAM role with Service Accounts.
map(object({
resources = list(string)
actions = list(string)
effect = string
}))
null
key_pair_name
string(optional)The name of a Key Pair that can be used to SSH to the EC2 Instances in the ASG. Set to null if you don't want to enable Key Pair auth.
null
lb_hosted_zone_id
string(optional)The ID of the Route 53 Hosted Zone in which to create a DNS A record for the Auto Scaling Group. Optional if create_route53_entry = false.
null
listener_arns
map(optional)A map of all the listeners on the load balancer. The keys should be the port numbers and the values should be the ARN of the listener for that port.
map(string)
{}
listener_ports
list(optional)The ports the ALB listens on for requests
list(number)
[]
load_balancers
list(optional)A list of Elastic Load Balancer (ELB) names to associate with this ASG. If you're using the Application Load Balancer (ALB), see target_group_arns
.
list(string)
[]
metadata_users
list(optional)List of users on the ASG EC2 instances that should be permitted access to the EC2 metadata.
list(string)
[]
original_lb_dns_name
string(optional)The DNS name that was assigned by AWS to the load balancer upon creation
null
redirect_listener_rules
map(optional)Listener rules for a redirect action. See comments below for information about the parameters.
map(any)
{}
route53_health_check_provider_external_id
string(optional)The optional external_id to be used in the us-east-1 provider block defined in the route53-health-check-alarms module. This module configures its own AWS provider to ensure resources are created in us-east-1.
null
route53_health_check_provider_profile
string(optional)The optional AWS profile to be used in the us-east-1 provider block defined in the route53-health-check-alarms module. This module configures its own AWS provider to ensure resources are created in us-east-1.
null
route53_health_check_provider_role_arn
string(optional)The optional role_arn to be used in the us-east-1 provider block defined in the route53-health-check-alarms module. This module configures its own AWS provider to ensure resources are created in us-east-1.
null
route53_health_check_provider_session_name
string(optional)The optional session_name to be used in the us-east-1 provider block defined in the route53-health-check-alarms module. This module configures its own AWS provider to ensure resources are created in us-east-1.
null
route53_health_check_provider_shared_credentials_file
string(optional)The optional path to a credentials file used in the us-east-1 provider block defined in the route53-health-check-alarms module. This module configures its own AWS provider to ensure resources are created in us-east-1.
null
secrets_access
list(optional)A list of ARNs of Secrets Manager secrets that the task should have permissions to read. The IAM role for the task will be granted secretsmanager:GetSecretValue
for each secret in the list. The ARN can be either the complete ARN, including the randomly generated suffix, or the ARN without the suffix. If the latter, the module will look up the full ARN automatically. This is helpful in cases where you don't yet know the randomly generated suffix because the rest of the ARN is a predictable value.
list(string)
[]
server_ports
any(optional)The ports the EC2 instances listen on for requests. A Target Group will be created for each port and any rules specified in forward_rules
will forward traffic to these Target Groups.
{}
should_create_cloudwatch_log_group
bool(optional)When true, precreate the CloudWatch Log Group to use for log aggregation from the EC2 instances. This is useful if you wish to customize the CloudWatch Log Group with various settings such as retention periods and KMS encryption. When false, the CloudWatch agent will automatically create a basic log group to use.
true
ssh_grunt_iam_group
string(optional)If you are using ssh-grunt, this is the name of the IAM group from which users will be allowed to SSH to the instances. To omit this variable, set it to an empty string (do NOT use null, or Terraform will complain).
ssh-grunt-sudo-users
ssh_grunt_iam_group_sudo
string(optional)If you are using ssh-grunt, this is the name of the IAM group from which users will be allowed to SSH to the instances with sudo permissions. To omit this variable, set it to an empty string (do NOT use null, or Terraform will complain).
ssh-grunt-sudo-users
ssh_port
string(optional)The port at which SSH will be allowed from allow_ssh_from_cidr_blocks
and allow_ssh_security_group_ids
22
tag_asg_id_key
string(optional)The key for the tag that will be used to associate a unique identifier with this ASG. This identifier will persist between redeploys of the ASG, even though the underlying ASG is being deleted and replaced with a different one.
AsgId
termination_policies
list(optional)A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are OldestInstance, NewestInstance, OldestLaunchConfiguration, ClosestToNextInstanceHour, Default.
list(string)
[]
use_elb_health_checks
bool(optional)Whether or not ELB or ALB health checks should be enabled. If set to true, the load_balancers or target_groups_arns variable should be set depending on the load balancer type you are using. Useful for testing connectivity before health check endpoints are available.
true
use_managed_iam_policies
bool(optional)When true, all IAM policies will be managed as dedicated policies rather than inline policies attached to the IAM roles. Dedicated managed policies are friendlier to automated policy checkers, which may scan a single resource for findings. As such, it is important to avoid inline policies when targeting compliance with various security standards.
true
wait_for_capacity_timeout
string(optional)A maximum duration that Terraform should wait for the EC2 Instances to be healthy before timing out.
10m
The name of the auto scaling group.
A unique ID common to all ASGs used for get_desired_capacity on new deploys.
The Fully Qualified Domain Name built using the zone domain and name.
The ID of the launch configuration used for the ASG.
The name of the launch configuration used for the ASG.
The ARNs of the rules of type fixed-response. The key is the same key of the rule from the fixed_response_rules
variable.
The ARNs of the rules of type forward. The key is the same key of the rule from the forward_rules
variable.
The ARNs of the rules of type redirect. The key is the same key of the rule from the redirect_rules
variable.
The ID of the Security Group that belongs to the ASG.