From bb81085619769aca861ab5d5bbff86f71c9435d2 Mon Sep 17 00:00:00 2001 From: Spike Date: Sun, 7 Apr 2019 22:03:31 +0100 Subject: Autoscaling Group, and associated controls and configs --- asg.tf | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ cloudwatch.tf | 45 ++++++++++++++++++++++++++++++++++++ eip.tf | 15 ++++++++++++ elb.tf | 36 +++++++++++++++++++++++++++++ files/app_data.tpl | 11 +++++++++ iam.tf | 53 ++++++++++++++++++++++++++++++++++++++++++ keypair.tf | 4 ++++ main.tf | 27 ++++++++++++++++++++++ nat.tf | 18 +++++++++++++++ route_tables.tf | 22 ++++++++++++++++++ s3.tf | 5 ++++ sg.tf | 59 +++++++++++++++++++++++++++++++++++++++++++++++ subnets.tf | 18 +++++++++++++++ variables.tf | 35 ++++++++++++++++++++++++++++ 14 files changed, 415 insertions(+) create mode 100644 asg.tf create mode 100644 cloudwatch.tf create mode 100644 eip.tf create mode 100644 elb.tf create mode 100644 files/app_data.tpl create mode 100644 iam.tf create mode 100644 keypair.tf create mode 100644 main.tf create mode 100644 nat.tf create mode 100644 route_tables.tf create mode 100644 s3.tf create mode 100644 sg.tf create mode 100644 subnets.tf create mode 100644 variables.tf diff --git a/asg.tf b/asg.tf new file mode 100644 index 0000000..46c3616 --- /dev/null +++ b/asg.tf @@ -0,0 +1,67 @@ +resource "aws_launch_configuration" "fundapp_demo" { + name_prefix = "${var.vpc_name}_app" + image_id = "${var.image_id}" + instance_type = "t2.nano" + iam_instance_profile = "${aws_iam_instance_profile.app_profile.id}" + key_name = "${aws_key_pair.server_keypair.key_name}" + + security_groups = [ + "${aws_security_group.app_sg.id}", + "${aws_security_group.external_ssh_accept_sg.id}", + ] + + user_date = "${data.template_file.app_user_data.rendered}" + + root_block_device { + volume_type = "gp2" + volume_size = "30" + } + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_autoscaling_group" "app_asg" { + name = "${var.vpc_name}_app_asg" + launch_configuration = "${aws_launch_configuration.fundapp_demo.name}" + + availability_zones = [ + "${var.aws_az_1}", + "${var.aws_az_2}", + "${var.aws_az_3}", + ] + + vpc_zone_identifier = [ + "${aws_subnet.public_1.id}", + "${aws_subnet.public_2.id}", + "${aws_subnet.public_3.id}", + ] + + min_size = 1 + max_size = 3 + desired_capacity = 2 + health_check_grace_period = 300 + + enabled_metrics = [ + "GroupMinSize", + "GroupMazSize", + "GroupDesiredCapacity", + "GroupInServiceInstances", + "GroupPendingInstances", + "GroupStandbyInstances", + "GroupTerminatingInstances", + "GroupTotalInstances", + ] + + load_balancers = ["${aws_elb.app_elb.name}"] + health_check_type = "EC2" + + lifecycle { + create_before_destroy = true + } +} + +data "template_file" "app_user_data" { + template = "${file("${path.module}/files/app_data.tpl")}" +} diff --git a/cloudwatch.tf b/cloudwatch.tf new file mode 100644 index 0000000..9a73918 --- /dev/null +++ b/cloudwatch.tf @@ -0,0 +1,45 @@ +resource "aws_cloudwatch_metric_alarm" "target_healthy_count" { + alarm_name = "ELB-target-healthy-count" + comparison_operator = "LessThanOrEqualToThreshold" + evaluation_periods = "1" + metric_name = "HealthyHostCount" + period = "60" + statistic = "Average" + threshold = "0" + + dimensions { + LoadBalancer = "${aws_elb.app_elb.id}" + } + + alarm_description = "Trigger an alert when elb has 1 or more unhealthy hosts" + + #alarm_actions = "Would point at sns here" + #ok_actions = "Would also point at sns" + treat_missing_data = "breaching" +} + +resource "aws_autoscaling_policy" "app_as_policy" { + name = "app_autoscaling_policy" + scaling_adjustment = 1 + adjustment_type = "ChangeInCapacity" + cooldown = 300 + autoscaling_group_name = "${aws_autoscaling_group.app_asg.name}" +} + +resource "aws_cloudwatch_metric_alarm" "app_asg_alarm" { + alarm_name = "app_asg_alarm" + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "2" + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + period = "120" + statistic = "Average" + threshold = "80" + + dimensions = { + AutoScalingGroupName = "${aws_autoscaling_group.app_asg.name}" + } + + alarm_description = "This metric monitors ec2 cpu utilization" + alarm_actions = ["${aws_autoscaling_policy.app_as_policy.arn}"] +} diff --git a/eip.tf b/eip.tf new file mode 100644 index 0000000..3c6110b --- /dev/null +++ b/eip.tf @@ -0,0 +1,15 @@ +# Elastic IPs +resource "aws_eip" "fundapp_demo_eip_az1" { + vpc = true + depends_on = ["aws_internet_gateway.fundapp_demo_aws_igw"] +} + +resource "aws_eip" "fundapp_demo_eip_az2" { + vpc = true + depends_on = ["aws_internet_gateway.fundapp_demo_aws_igw"] +} + +resource "aws_eip" "fundapp_demo_eip_az3" { + vpc = true + depends_on = ["aws_internet_gateway.fundapp_demo_aws_igw"] +} diff --git a/elb.tf b/elb.tf new file mode 100644 index 0000000..69a090a --- /dev/null +++ b/elb.tf @@ -0,0 +1,36 @@ +resource "aws_elb" "app_elb" { + name = "${var.vpc_name}_app_elb" + + access_logs { + bucket = "${aws_s3_bucket.elb_logs.name}" + bucket_prefix = "app_logs" + interval = 60 + } + + listener { + instance_port = 80 + instance_protocol = "http" + lb_port = 80 + lb_protocol = "http" + } + + health_check { + healthy_threshold = 2 + unhealthy_threshold = 2 + timeout = 3 + target = "HTTP:80" + interval = 5 + } + + cross_zone_load_balancing = true + idle_timeout = 400 + connection_draining = true + connetion_draining_timeout = 400 + security_groups = ["${aws_security_group.app_sg.id}"] + + subnets = [ + "${aws_subnet.public_1.id}", + "${aws_subnet.public_2.id}", + "${aws_subnet.public_3.id}", + ] +} diff --git a/files/app_data.tpl b/files/app_data.tpl new file mode 100644 index 0000000..419eff6 --- /dev/null +++ b/files/app_data.tpl @@ -0,0 +1,11 @@ +#!/bin/bash + +# Update OS +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get -y upgrade + +# Install nginx +apt-get -y install nginx + +# Start nginx. This will act the part of our healthcheck +service nginx start diff --git a/iam.tf b/iam.tf new file mode 100644 index 0000000..9578c64 --- /dev/null +++ b/iam.tf @@ -0,0 +1,53 @@ +resource "aws_iam_role" "app_role" { + name = "app_role" + path = "/" + + assume_role_policy = <