Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation #3

Merged
merged 9 commits into from
Sep 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@

# .tfvars files
*.tfvars

**/.idea
**/*.iml

**/.build-harness
**/build-harness
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
addons:
apt:
packages:
- git
- make
- curl

install:
- make init

script:
- make terraform/install
- make terraform/get-plugins
- make terraform/get-modules
- make terraform/lint
- make terraform/validate
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2018 Cloud Posse, LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SHELL := /bin/bash

# List of targets the `readme` target should call before generating the readme
export README_DEPS ?= docs/targets.md docs/terraform.md

-include $(shell curl -sSL -o .build-harness "https://git.io/build-harness"; echo .build-harness)

## Lint terraform code
lint:
$(SELF) terraform/install terraform/get-modules terraform/get-plugins terraform/lint terraform/validate
316 changes: 314 additions & 2 deletions README.md

Large diffs are not rendered by default.

112 changes: 112 additions & 0 deletions README.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
#
# This is the canonical configuration for the `README.md`
# Run `make readme` to rebuild the `README.md`
#

# Name of this project
name: terraform-aws-ec2-autoscale-group

# Logo for this project
#logo: docs/logo.png

# License of this project
license: "APACHE2"

# Canonical GitHub repo
github_repo: cloudposse/terraform-aws-ec2-autoscale-group

# Badges to display
badges:
- name: "Build Status"
image: "https://travis-ci.org/cloudposse/terraform-aws-ec2-autoscale-group.svg?branch=master"
url: "https://travis-ci.org/cloudposse/terraform-aws-ec2-autoscale-group"
- name: "Latest Release"
image: "https://img.shields.io/github/release/cloudposse/terraform-aws-ec2-autoscale-group.svg"
url: "https://github.com/cloudposse/terraform-aws-ec2-autoscale-group/releases/latest"
- name: "Slack Community"
image: "https://slack.cloudposse.com/badge.svg"
url: "https://slack.cloudposse.com"

related:
- name: "terraform-aws-ec2-instance"
description: "Terraform module for providing a general purpose EC2 instance"
url: "https://github.com/cloudposse/terraform-aws-ec2-instance"
- name: "terraform-aws-ec2-bastion-server"
description: "Terraform module to define a generic bastion host with parameterized user data"
url: "https://github.com/cloudposse/terraform-aws-ec2-bastion-server"
- name: "terraform-aws-ec2-admin-server"
description: "Terraform module for providing an EC2 instance capable of running admin tasks"
url: "https://github.com/cloudposse/terraform-aws-ec2-admin-server"
- name: "terraform-aws-ec2-instance-group"
description: "Terraform module for provisioning multiple general purpose EC2 hosts for stateful applications"
url: "https://github.com/cloudposse/terraform-aws-ec2-instance-group"
- name: "terraform-aws-ec2-ami-snapshot"
description: "Terraform module to easily generate AMI snapshots to create replica instances"
url: "https://github.com/cloudposse/terraform-aws-ec2-ami-snapshot"

# Short description of this project
description: |-
Terraform module to provision [Auto Scaling Group](https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html) and [Launch Template](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html) on AWS.

The module also creates AutoScaling Policies and CloudWatch Metric Alarms to monitor CPU utilization on the EC2 instances and scale the number of instance in the AutoScaling Group up or down.
If you don't want to use the provided functionality, or want to provide your own policies, disable it by setting the variable `autoscaling_policies_enabled` to `"false"`.

# How to use this project
usage: |-

```hcl
locals {
userdata = <<USERDATA
#!/bin/bash
cat <<"__EOF__" > /home/ec2-user/.ssh/config
Host *
StrictHostKeyChecking no
__EOF__
chmod 600 /home/ec2-user/.ssh/config
chown ec2-user:ec2-user /home/ec2-user/.ssh/config
USERDATA
}

module "autoscale_group" {
source = "git::https://github.com/cloudposse/terraform-aws-ec2-autoscale-group.git?ref=master"

namespace = "eg"
stage = "dev"
name = "test"

image_id = "ami-08cab282f9979fc7a"
instance_type = "t2.small"
security_group_ids = ["sg-xxxxxxxx"]
subnet_ids = ["subnet-xxxxxxxx", "subnet-yyyyyyyy", "subnet-zzzzzzzz"]
health_check_type = "EC2"
min_size = 2
max_size = 3
wait_for_capacity_timeout = "5m"
associate_public_ip_address = true
user_data_base64 = "${base64encode(local.userdata)}"

tags = {
Tier = "1"
KubernetesCluster = "us-west-2.testing.cloudposse.co"
}

# Auto-scaling policies and CloudWatch metric alarms
autoscaling_policies_enabled = "true"
cpu_utilization_high_threshold_percent = "70"
cpu_utilization_low_threshold_percent = "20"
}
```

include:
- "docs/targets.md"
- "docs/terraform.md"

# Contributors to this project
contributors:
- name: "Erik Osterman"
github: "osterman"
- name: "Andriy Knysh"
github: "aknysh"
- name: "Igor Rodionov"
github: "goruha"
63 changes: 63 additions & 0 deletions autoscaling.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ec2-metricscollected.html

locals {
autoscaling_enabled = "${var.enabled == "true" && var.autoscaling_policies_enabled == "true" ? true : false}"
}

resource "aws_autoscaling_policy" "scale_up" {
count = "${local.autoscaling_enabled ? 1 : 0}"
name = "${module.label.id}${var.delimiter}scale${var.delimiter}up"
scaling_adjustment = "${var.scale_up_scaling_adjustment}"
adjustment_type = "${var.scale_up_adjustment_type}"
policy_type = "${var.scale_up_policy_type}"
cooldown = "${var.scale_up_cooldown_seconds}"
autoscaling_group_name = "${join("", aws_autoscaling_group.default.*.name)}"
}

resource "aws_autoscaling_policy" "scale_down" {
count = "${local.autoscaling_enabled ? 1 : 0}"
name = "${module.label.id}${var.delimiter}scale${var.delimiter}down"
scaling_adjustment = "${var.scale_down_scaling_adjustment}"
adjustment_type = "${var.scale_down_adjustment_type}"
policy_type = "${var.scale_down_policy_type}"
cooldown = "${var.scale_down_cooldown_seconds}"
autoscaling_group_name = "${join("", aws_autoscaling_group.default.*.name)}"
}

resource "aws_cloudwatch_metric_alarm" "cpu_high" {
count = "${local.autoscaling_enabled ? 1 : 0}"
alarm_name = "${module.label.id}${var.delimiter}cpu${var.delimiter}utilization${var.delimiter}high"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "${var.cpu_utilization_high_evaluation_periods}"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "${var.cpu_utilization_high_period_seconds}"
statistic = "${var.cpu_utilization_high_statistic}"
threshold = "${var.cpu_utilization_high_threshold_percent}"

dimensions {
AutoScalingGroupName = "${join("", aws_autoscaling_group.default.*.name)}"
}

alarm_description = "Scale up if CPU utilization is above ${var.cpu_utilization_high_threshold_percent} for ${var.cpu_utilization_high_period_seconds} seconds"
alarm_actions = ["${join("", aws_autoscaling_policy.scale_up.*.arn)}"]
}

resource "aws_cloudwatch_metric_alarm" "cpu_low" {
count = "${local.autoscaling_enabled ? 1 : 0}"
alarm_name = "${module.label.id}${var.delimiter}cpu${var.delimiter}utilization${var.delimiter}low"
comparison_operator = "LessThanOrEqualToThreshold"
evaluation_periods = "${var.cpu_utilization_low_evaluation_periods}"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "${var.cpu_utilization_low_period_seconds}"
statistic = "${var.cpu_utilization_low_statistic}"
threshold = "${var.cpu_utilization_low_threshold_percent}"

dimensions {
AutoScalingGroupName = "${join("", aws_autoscaling_group.default.*.name)}"
}

alarm_description = "Scale down if the CPU utilization is below ${var.cpu_utilization_low_threshold_percent} for ${var.cpu_utilization_low_period_seconds} seconds"
alarm_actions = ["${join("", aws_autoscaling_policy.scale_down.*.arn)}"]
}
10 changes: 10 additions & 0 deletions docs/targets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Makefile Targets
```
Available targets:

help Help screen
help/all Display help for all targets
help/short This help short screen
lint Lint terraform code

```
83 changes: 83 additions & 0 deletions docs/terraform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| associate_public_ip_address | Associate a public IP address with an instance in a VPC | string | `false` | no |
| attributes | Additional attributes (e.g. `1`) | list | `<list>` | no |
| autoscaling_policies_enabled | Whether to create `aws_autoscaling_policy` and `aws_cloudwatch_metric_alarm` resources to control Auto Scaling | string | `true` | no |
| block_device_mappings | Specify volumes to attach to the instance besides the volumes specified by the AMI | list | `<list>` | no |
| cpu_utilization_high_evaluation_periods | The number of periods over which data is compared to the specified threshold | string | `2` | no |
| cpu_utilization_high_period_seconds | The period in seconds over which the specified statistic is applied | string | `300` | no |
| cpu_utilization_high_statistic | The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` | string | `Average` | no |
| cpu_utilization_high_threshold_percent | The value against which the specified statistic is compared | string | `90` | no |
| cpu_utilization_low_evaluation_periods | The number of periods over which data is compared to the specified threshold | string | `2` | no |
| cpu_utilization_low_period_seconds | The period in seconds over which the specified statistic is applied | string | `300` | no |
| cpu_utilization_low_statistic | The statistic to apply to the alarm's associated metric. Either of the following is supported: `SampleCount`, `Average`, `Sum`, `Minimum`, `Maximum` | string | `Average` | no |
| cpu_utilization_low_threshold_percent | The value against which the specified statistic is compared | string | `10` | no |
| credit_specification | Customize the credit specification of the instances | list | `<list>` | no |
| default_cooldown | The amount of time, in seconds, after a scaling activity completes before another scaling activity can start | string | `300` | no |
| delimiter | Delimiter to be used between `name`, `namespace`, `stage`, etc. | string | `-` | no |
| disable_api_termination | If `true`, enables EC2 Instance Termination Protection | string | `false` | no |
| ebs_optimized | If true, the launched EC2 instance will be EBS-optimized | string | `false` | no |
| elastic_gpu_specifications | Specifications of Elastic GPU to attach to the instances | list | `<list>` | no |
| enable_monitoring | Enable/disable detailed monitoring | string | `true` | no |
| enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | string | `true` | no |
| enabled_metrics | A list of metrics to collect. The allowed values are `GroupMinSize`, `GroupMaxSize`, `GroupDesiredCapacity`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupTerminatingInstances`, `GroupTotalInstances` | list | `<list>` | no |
| environment | Environment, e.g. 'testing', 'UAT' | string | `` | no |
| force_delete | Allows deleting the autoscaling group without waiting for all instances in the pool to terminate. You can force an autoscaling group to delete even if it's in the process of scaling a resource. Normally, Terraform drains all the instances before deleting the group. This bypasses that behavior and potentially leaves resources dangling | string | `false` | no |
| health_check_grace_period | Time (in seconds) after instance comes into service before checking health | string | `300` | no |
| health_check_type | Controls how health checking is done. Valid values are `EC2` or `ELB` | string | `EC2` | no |
| iam_instance_profile_name | The IAM instance profile name to associate with launched instances | string | `` | no |
| image_id | The EC2 image ID to launch | string | `` | no |
| instance_initiated_shutdown_behavior | Shutdown behavior for the instances. Can be `stop` or `terminate` | string | `terminate` | no |
| instance_market_options | The market (purchasing) option for the instances | list | `<list>` | no |
| instance_type | Instance type to launch | string | - | yes |
| key_name | The SSH key name that should be used for the instance | string | `` | no |
| launch_template_version | Launch template version. Can be version number, `$Latest` or `$Default` | string | `$$Latest` | no |
| load_balancers | A list of elastic load balancer names to add to the autoscaling group names. Only valid for classic load balancers. For ALBs, use `target_group_arns` instead | list | `<list>` | no |
| max_size | The maximum size of the autoscale group | string | - | yes |
| metrics_granularity | The granularity to associate with the metrics to collect. The only valid value is 1Minute | string | `1Minute` | no |
| min_elb_capacity | Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes | string | `0` | no |
| min_size | The minimum size of the autoscale group | string | - | yes |
| name | Solution name, e.g. 'app' or 'cluster' | string | `app` | no |
| namespace | Namespace, which could be your organization name, e.g. 'eg' or 'cp' | string | - | yes |
| placement | The placement specifications of the instances | list | `<list>` | no |
| placement_group | The name of the placement group into which you'll launch your instances, if any | string | `` | no |
| protect_from_scale_in | Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events | string | `false` | no |
| scale_down_adjustment_type | Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity` | string | `ChangeInCapacity` | no |
| scale_down_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | string | `300` | no |
| scale_down_policy_type | The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling` | string | `SimpleScaling` | no |
| scale_down_scaling_adjustment | The number of instances by which to scale. `scale_down_scaling_adjustment` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | string | `-1` | no |
| scale_up_adjustment_type | Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity` | string | `ChangeInCapacity` | no |
| scale_up_cooldown_seconds | The amount of time, in seconds, after a scaling activity completes and before the next scaling activity can start | string | `300` | no |
| scale_up_policy_type | The scalling policy type, either `SimpleScaling`, `StepScaling` or `TargetTrackingScaling` | string | `SimpleScaling` | no |
| scale_up_scaling_adjustment | The number of instances by which to scale. `scale_up_adjustment_type` determines the interpretation of this number (e.g. as an absolute number or as a percentage of the existing Auto Scaling group size). A positive increment adds to the current capacity and a negative value removes from the current capacity | string | `1` | no |
| security_group_ids | A list of associated security group IDs | list | `<list>` | no |
| service_linked_role_arn | The ARN of the service-linked role that the ASG will use to call other AWS services | string | `` | no |
| stage | Stage, e.g. 'prod', 'staging', 'dev', or 'test' | string | - | yes |
| subnet_ids | A list of subnet IDs to launch resources in | list | - | yes |
| suspended_processes | A list of processes to suspend for the AutoScaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your autoscaling group from functioning properly. | list | `<list>` | no |
| tags | Additional tags (e.g. `map('BusinessUnit`,`XYZ`) | map | `<map>` | no |
| target_group_arns | A list of aws_alb_target_group ARNs, for use with Application Load Balancing | list | `<list>` | no |
| termination_policies | 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 | `<list>` | no |
| user_data_base64 | The Base64-encoded user data to provide when launching the instances | string | `` | no |
| wait_for_capacity_timeout | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior | string | `10m` | no |
| wait_for_elb_capacity | Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over `min_elb_capacity` behavior | string | `false` | no |

## Outputs

| Name | Description |
|------|-------------|
| autoscaling_group_arn | The ARN for this AutoScaling Group |
| autoscaling_group_default_cooldown | Time between a scaling activity and the succeeding scaling activity |
| autoscaling_group_desired_capacity | The number of Amazon EC2 instances that should be running in the group |
| autoscaling_group_health_check_grace_period | Time after instance comes into service before checking health |
| autoscaling_group_health_check_type | `EC2` or `ELB`. Controls how health checking is done |
| autoscaling_group_id | The autoscaling group id |
| autoscaling_group_max_size | The maximum size of the autoscale group |
| autoscaling_group_min_size | The minimum size of the autoscale group |
| autoscaling_group_name | The autoscaling group name |
| launch_template_arn | The ARN of the launch template |
| launch_template_id | The ID of the launch template |

Loading