diff options
author | Spike <avlampson+git@gmail.com> | 2019-04-07 22:03:31 +0100 |
---|---|---|
committer | Spike <avlampson+git@gmail.com> | 2019-04-07 22:03:31 +0100 |
commit | bb81085619769aca861ab5d5bbff86f71c9435d2 (patch) | |
tree | 80b45de34d9f0647c10e6d6fae5b408c21c190c5 | |
download | fundapp_demo-bb81085619769aca861ab5d5bbff86f71c9435d2.zip fundapp_demo-bb81085619769aca861ab5d5bbff86f71c9435d2.tar.gz fundapp_demo-bb81085619769aca861ab5d5bbff86f71c9435d2.tar.bz2 |
-rw-r--r-- | asg.tf | 67 | ||||
-rw-r--r-- | cloudwatch.tf | 45 | ||||
-rw-r--r-- | eip.tf | 15 | ||||
-rw-r--r-- | elb.tf | 36 | ||||
-rw-r--r-- | files/app_data.tpl | 11 | ||||
-rw-r--r-- | iam.tf | 53 | ||||
-rw-r--r-- | keypair.tf | 4 | ||||
-rw-r--r-- | main.tf | 27 | ||||
-rw-r--r-- | nat.tf | 18 | ||||
-rw-r--r-- | route_tables.tf | 22 | ||||
-rw-r--r-- | s3.tf | 5 | ||||
-rw-r--r-- | sg.tf | 59 | ||||
-rw-r--r-- | subnets.tf | 18 | ||||
-rw-r--r-- | variables.tf | 35 |
14 files changed, 415 insertions, 0 deletions
@@ -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}"] +} @@ -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"] +} @@ -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 @@ -0,0 +1,53 @@ +resource "aws_iam_role" "app_role" { + name = "app_role" + path = "/" + + assume_role_policy = <<EOF +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Principal": { + "Service": "ec2.amazonaws.com" + }, + "Effect": "Allow", + "Sid": "" + } + ] +} +EOF +} + +data "aws_iam_policy" "app_policy_document" { + statement { + actions = ["sts:AssumeRole"] + resources = ["*"] + } + + statement { + actions = ["ec2:DescribeInstances"] + resources = ["*"] + } + + statement { + actions = ["s3:*"] + resources = ["*"] + } +} + +resource "aws_iam_policy" "app_policy" { + name = "app_policy" + path = "/" + policy = "${data.aws_iam_policy_document.app_policy_document.json}" +} + +resource "aws_iam_role_policy_attachment" "app_policy_attachment" { + role = "${aws_iam_role.app_role.name}" + policy_arn = "${aws_iam_policy.app_policy.arn}" +} + +resource "aws_iam_instance_profile" "app_profile" { + name = "app_profile" + role = "${aws_iam_role.app_role.name}" +} diff --git a/keypair.tf b/keypair.tf new file mode 100644 index 0000000..16c2ae5 --- /dev/null +++ b/keypair.tf @@ -0,0 +1,4 @@ +resource "aws_key_pair" "server_keypair" { + key_name = "${var.vpc_name}_server_key" + public_key = "${var.keypair_pubkey}" +} @@ -0,0 +1,27 @@ +terraform { + backend "s3" { + bucket = "fundapp_demo_remote_state" + region = "eu-west-2" + key = "terraform.tfstate" + dynamodb_table = "terraform-state-lock-dynamo" + encrypt = true + } +} + +provider "aws" { + region = "${var.aws_region}" +} + +resource "aws_vpc" "fundapp_demo_vpc" { + cidr_block = "${var.vpn_cidr}" + enable_dns_support = true + enable_dns_hostnames = true +} + +resource "aws_internet_gateway" "fundapp_demo_aws_igw" { + vpc_id = "${aws_vpc.fundapp_demo_vpc.id}" + + tags { + Name = "${var.vpc_name}_igw" + } +} @@ -0,0 +1,18 @@ +# Nat gateways +resource "aws_nat_gateway" "fundapp_demo_nat_gateway_az1" { + allocation_id = "${aws_eip.fundapp_demo_eip_az1.id}" + subnet_id = "${aws_subnet.public_1.id}" + depends_on = ["aws_internet_gateway.fundapp_demo_aws_igw"] +} + +resource "aws_nat_gateway" "fundapp_demo_nat_gateway_az2" { + allocation_id = "${aws_eip.fundapp_demo_eip_az2.id}" + subnet_id = "${aws_subnet.public_2.id}" + depends_on = ["aws_internet_gateway.fundapp_demo_aws_igw"] +} + +resource "aws_nat_gateway" "fundapp_demo_nat_gateway_az3" { + allocation_id = "${aws_eip.fundapp_demo_eip_az3.id}" + subnet_id = "${aws_subnet.public_3.id}" + depends_on = ["aws_internet_gateway.fundapp_demo_aws_igw"] +} diff --git a/route_tables.tf b/route_tables.tf new file mode 100644 index 0000000..c4ead17 --- /dev/null +++ b/route_tables.tf @@ -0,0 +1,22 @@ +# Public route table +resource "aws_route" "fundapp_demo_public_route_table" { + route_table_id = "${aws_vpc.fundapp_demo_vpc.main_route_table_id}" + destination_cidr_block = "0.0.0.0/0" + gateway_id = "${aws_internet_gateway.fundapp_demo_aws_igw.id}" +} + +# Public route table associations +resource "aws_route_table_association" "vpc_pub_net_association_az1" { + subnet_id = "${aws_subnet.public_1.id}" + route_table_id = "${aws_vpc.fundapp_demo_vpc.main_route_table_id}" +} + +resource "aws_route_table_association" "vpc_pub_net_association_az2" { + subnet_id = "${aws_subnet.public_2.id}" + route_table_id = "${aws_vpc.fundapp_demo_vpc.main_route_table_id}" +} + +resource "aws_route_table_association" "vpc_pub_net_association_az2" { + subnet_id = "${aws_subnet.public_2.id}" + route_table_id = "${aws_vpc.fundapp_demo_vpc.main_route_table_id}" +} @@ -0,0 +1,5 @@ +resource "aws_s3_bucket" "elb_logs" { + bucket = "${var.vpc_name}_elb_logs" + acl = "private" + region = "${var.vpc_region}" +} @@ -0,0 +1,59 @@ +resource "aws_security_group" "external_ssh_accept_sg" { + name = "${var.vpc-name}_external_ssh_accept_sg" + description = "${var.vpc-name}_external_ssh_accept_sg" + vpc_id = "${aws_vpc.fundapp_demo_aws_vpc.id}" + + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_security_group" "app_sg" { + name = "${var.vpc_name}_app_sg" + description = "${var.vpc_name}_app_sg" + vpc_id = "${aws_vpc.fundapp_demo_vpc.id}" + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + security_groups = ["${aws_security_group.app_elb_sg.id}"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_security_group" "app_elb_sg" { + name = "${var.vpc_name}_app_elb_sg" + description = "${var.vpc_name}_app_elb_sg" + vpc_id = "${aws_vpc.fundapp_demo_vpc.id}" + + ingress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} diff --git a/subnets.tf b/subnets.tf new file mode 100644 index 0000000..7ed881f --- /dev/null +++ b/subnets.tf @@ -0,0 +1,18 @@ +# Public Subnets +resource "aws_subnet" "public_1" { + vpc_id = "${aws_vpc.fundapp_demo_vpc.id}" + cidr_block = "${var.vpc_net_prefix}.10.0/24" + availability_zone = "${var.aws_az_1}" +} + +resource "aws_subnet" "public_2" { + vpc_id = "${aws_vpc.fundapp_demo_vpc.id}" + cidr_block = "${var.vpc_net_prefix}.20.0/24" + availability_zone = "${var.aws_az_2}" +} + +resource "aws_subnet" "public_3" { + vpc_id = "${aws_vpc.fundapp_demo_vpc.id}" + cidr_block = "${var.vpc_net_prefix}.30.0/24" + availability_zone = "${var.aws_az_3}" +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..9bdc1bb --- /dev/null +++ b/variables.tf @@ -0,0 +1,35 @@ +variable "aws_region" { + default = "eu-west-2" +} + +variable "aws_az_1" { + default = "eu-west-2a" +} + +variable "aws_az_2" { + default = "eu-west-2b" +} + +variable "aws_az_3" { + default = "eu-west-2c" +} + +variable "vpc_net_prefix" { + default = "10.0" +} + +variable "vpc_cidr" { + default = "10.0.0.0/16" +} + +variable "vpc_name" { + default = "fundapp_demo" +} + +variable "keypair_pubkey" { + default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf1MEiSSwe2ew6ahu7SZRkucrDEDvbYVoMMEvMk091/YQFOvzE+sSl6kh+9qTceayxEEMzSw3Rmlyon+OZiDf6vp8ovxdINUfJjAUiSeo/O4pg4BMHrv1rJ+kft70lyBAHs9zGzu8JB0jVHrJMlAt4e9VCbAUvFUB+DPhCTIBeZjOpoMU7cLf0LqVoRtwGrp4YbXaBVFQWm9SZIJk2Fq5mcF+3+wxkOzacKq8ZYP3AvGoZbvSBOrhMvw9vpoBSprXzKXSd+HkBnqN2O4JRAxsxgwhQU3/HNROvha/L+aPt/muOksZtOA9wlrSbeWmFsdto/eOxFUlBgwaDMv1PSSjd hen3ry@Hen3ry-Desktop" +} + +variable "image_id" { + default = "ami-068f09e337d7da0c4" +} |