From 1d6fcd6d8b1de307b813d77742d43de25de343c0 Mon Sep 17 00:00:00 2001 From: Sokratis Siozos-Drosos Date: Wed, 24 Apr 2019 11:06:55 +0200 Subject: [PATCH] (MODE-11365) Added deployment folder with initial structure and module from terraform-modules repo. --- deployment/eu-central-1/dev/tileserver/source | 1 + .../dev/tileserver/terraform.tfvars | 18 +++ .../eu-central-1/prod/tileserver/source | 1 + .../prod/tileserver/terraform.tfvars | 18 +++ deployment/modules/tileserver/README.md | 6 + .../modules/tileserver/alb_listeners.tf | 9 ++ deployment/modules/tileserver/autoscaling.tf | 124 ++++++++++++++++++ deployment/modules/tileserver/data.tf | 75 +++++++++++ .../modules/tileserver/files/cloud-init.cfg | 1 + .../modules/tileserver/files/user-data.sh | 10 ++ deployment/modules/tileserver/iam.tf | 18 +++ deployment/modules/tileserver/main.tf | 7 + deployment/modules/tileserver/outputs.tf | 15 +++ .../policies/assume-role-policy.json | 16 +++ .../modules/tileserver/policies/policies.json | 45 +++++++ .../modules/tileserver/security-groups.tf | 52 ++++++++ .../modules/tileserver/target_groups.tf | 24 ++++ deployment/modules/tileserver/variables.tf | 51 +++++++ 18 files changed, 491 insertions(+) create mode 100644 deployment/eu-central-1/dev/tileserver/source create mode 100644 deployment/eu-central-1/dev/tileserver/terraform.tfvars create mode 100644 deployment/eu-central-1/prod/tileserver/source create mode 100644 deployment/eu-central-1/prod/tileserver/terraform.tfvars create mode 100644 deployment/modules/tileserver/README.md create mode 100644 deployment/modules/tileserver/alb_listeners.tf create mode 100644 deployment/modules/tileserver/autoscaling.tf create mode 100644 deployment/modules/tileserver/data.tf create mode 100644 deployment/modules/tileserver/files/cloud-init.cfg create mode 100644 deployment/modules/tileserver/files/user-data.sh create mode 100644 deployment/modules/tileserver/iam.tf create mode 100644 deployment/modules/tileserver/main.tf create mode 100644 deployment/modules/tileserver/outputs.tf create mode 100644 deployment/modules/tileserver/policies/assume-role-policy.json create mode 100644 deployment/modules/tileserver/policies/policies.json create mode 100644 deployment/modules/tileserver/security-groups.tf create mode 100644 deployment/modules/tileserver/target_groups.tf create mode 100644 deployment/modules/tileserver/variables.tf diff --git a/deployment/eu-central-1/dev/tileserver/source b/deployment/eu-central-1/dev/tileserver/source new file mode 100644 index 0000000..addbabe --- /dev/null +++ b/deployment/eu-central-1/dev/tileserver/source @@ -0,0 +1 @@ +../../../modules/tileserver \ No newline at end of file diff --git a/deployment/eu-central-1/dev/tileserver/terraform.tfvars b/deployment/eu-central-1/dev/tileserver/terraform.tfvars new file mode 100644 index 0000000..1cacb42 --- /dev/null +++ b/deployment/eu-central-1/dev/tileserver/terraform.tfvars @@ -0,0 +1,18 @@ +terragrunt = { + include { + path = "${find_in_parent_folders()}" + } + terraform { + source = "/tmp/repo/deployment/modules/tileserver" + } +} +region = "eu-central-1" +environment = "dev" +instance_type = "t2.large" +mono_vpc_remote_state = "dev/vpc/terraform.tfstate" +mono_alb_remote_state = "dev/tileserver-alb/terraform.tfstate" +mono_keypair_remote_state = "dev/mono-keypair/terraform.tfstate" +mono_efs_remote_state = "dev/mono-efs/terraform.tfstate" +mono_region = "fra" +version = "2.0" +state_bucket = "tg-state-eu-central-1" diff --git a/deployment/eu-central-1/prod/tileserver/source b/deployment/eu-central-1/prod/tileserver/source new file mode 100644 index 0000000..addbabe --- /dev/null +++ b/deployment/eu-central-1/prod/tileserver/source @@ -0,0 +1 @@ +../../../modules/tileserver \ No newline at end of file diff --git a/deployment/eu-central-1/prod/tileserver/terraform.tfvars b/deployment/eu-central-1/prod/tileserver/terraform.tfvars new file mode 100644 index 0000000..b859069 --- /dev/null +++ b/deployment/eu-central-1/prod/tileserver/terraform.tfvars @@ -0,0 +1,18 @@ +terragrunt = { + include { + path = "${find_in_parent_folders()}" + } + terraform { + source = "git::ssh://git@github.com/monosolutions/terraform-modules.git//mono-tileserver" + } +} +region = "eu-central-1" +environment = "prod" +instance_type = "t2.large" +mono_vpc_remote_state = "prod/vpc/terraform.tfstate" +mono_alb_remote_state = "prod/tileserver-alb/terraform.tfstate" +mono_keypair_remote_state = "prod/mono-keypair/terraform.tfstate" +mono_efs_remote_state = "prod/mono-efs/terraform.tfstate" +mono_region = "fra" +version = "2.0" +state_bucket = "tg-state-eu-central-1" diff --git a/deployment/modules/tileserver/README.md b/deployment/modules/tileserver/README.md new file mode 100644 index 0000000..84fc659 --- /dev/null +++ b/deployment/modules/tileserver/README.md @@ -0,0 +1,6 @@ +# mono-tileserver module + +Original repo: `https://github.com/klokantech/tileserver-gl` +Original documentation: `http://tileserver.readthedocs.io/en/latest/` + +This module uses the AMI that is built through the [mono-tileserver-ami](https://github.com/monosolutions/mono-tileserver-ami) repo. \ No newline at end of file diff --git a/deployment/modules/tileserver/alb_listeners.tf b/deployment/modules/tileserver/alb_listeners.tf new file mode 100644 index 0000000..38710ab --- /dev/null +++ b/deployment/modules/tileserver/alb_listeners.tf @@ -0,0 +1,9 @@ +resource "aws_alb_listener" "this_alb_listener" { + load_balancer_arn = "${data.terraform_remote_state.mono_alb.this_alb_arn}" + port = 80 + protocol = "HTTP" + default_action { + target_group_arn = "${aws_alb_target_group.target_group_this.arn}" + type = "forward" + } +} \ No newline at end of file diff --git a/deployment/modules/tileserver/autoscaling.tf b/deployment/modules/tileserver/autoscaling.tf new file mode 100644 index 0000000..560af92 --- /dev/null +++ b/deployment/modules/tileserver/autoscaling.tf @@ -0,0 +1,124 @@ +resource "aws_launch_configuration" "launchconfiguration" { + name_prefix = "maps-${var.environment}-" + image_id = "${data.aws_ami.amazon_linux.id}" + key_name = "${data.terraform_remote_state.mono_keypair.key_name}" + iam_instance_profile = "${aws_iam_instance_profile.profile.name}" + security_groups = ["${aws_security_group.this.id}", + "${data.terraform_remote_state.mono_efs.ec2_security_group_id}"] + instance_type = "${var.instance_type}" + user_data = "${data.template_cloudinit_config.cloudinit.rendered}" + ebs_optimized = false + root_block_device { + delete_on_termination = true + volume_size = 50 + } + lifecycle { + create_before_destroy = true + } +} + +resource "aws_autoscaling_group" "autoscalinggroup" { + vpc_zone_identifier = ["${data.terraform_remote_state.mono_vpc.sn_private_a_id}"] + name_prefix = "maps-${var.environment}-${var.version}" + launch_configuration = "${aws_launch_configuration.launchconfiguration.name}" + max_size = 5 + desired_capacity = 1 + min_size = 1 + health_check_grace_period = 300 + health_check_type = "ELB" + force_delete = true + termination_policies = ["OldestInstance"] + + target_group_arns = ["${aws_alb_target_group.target_group_this.arn}"] + enabled_metrics = ["GroupMinSize", "GroupMaxSize", + "GroupDesiredCapacity", "GroupInServiceInstances", + "GroupPendingInstances", "GroupStandbyInstances", + "GroupTerminatingInstances", "GroupTotalInstances"] + + lifecycle { + create_before_destroy = true + } + + tag { + key = "Name" + value = "maps" + propagate_at_launch = true + } +} + +# +# Autoscaling policies +# +resource "aws_autoscaling_policy" "this-autoscale_group_policy_up_x1" { + name = "maps-autoscale_group_policy_up_x1" + scaling_adjustment = 1 + adjustment_type = "ChangeInCapacity" + cooldown = 60 + autoscaling_group_name = "${aws_autoscaling_group.autoscalinggroup.name}" +} + +resource "aws_autoscaling_policy" "this-autoscale_group_policy_down_x1" { + name = "maps-autoscale_group_policy_down_x1" + scaling_adjustment = -1 + adjustment_type = "ChangeInCapacity" + cooldown = 60 + autoscaling_group_name = "${aws_autoscaling_group.autoscalinggroup.name}" +} + +# +# ASG alarms +# + +resource "aws_cloudwatch_metric_alarm" "this-cpu_high_alarm" { + alarm_name = "alarm-cpu-high-maps" + alarm_description = "This alarm triggers when CPU load in Autoscaling group is high." + + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + dimensions { + AutoScalingGroupName = "${aws_autoscaling_group.autoscalinggroup.name}" + } + statistic = "Average" + + comparison_operator = "GreaterThanOrEqualToThreshold" + evaluation_periods = "1" + + period = "60" + threshold = "70" + + # Use autoscaling policy ARN as an alarm action here + # Reference: http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html + alarm_actions = [ + "${aws_autoscaling_policy.this-autoscale_group_policy_up_x1.arn}", + ] + dimensions { + AutoScalingGroupName = "${aws_autoscaling_group.autoscalinggroup.name}" + } +} + +resource "aws_cloudwatch_metric_alarm" "this-cpu_low_alarm" { + alarm_name = "alarm-cpu-low-maps" + alarm_description = "This alarm triggers when CPU load in Autoscaling group is low." + + metric_name = "CPUUtilization" + namespace = "AWS/EC2" + dimensions { + AutoScalingGroupName = "${aws_autoscaling_group.autoscalinggroup.name}" + } + statistic = "Average" + + comparison_operator = "LessThanOrEqualToThreshold" + evaluation_periods = "1" + + period = "60" + threshold = "35" + + # Use autoscaling policy ARN as an alarm action here + # Reference: http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html + alarm_actions = [ + "${aws_autoscaling_policy.this-autoscale_group_policy_down_x1.arn}", + ] + dimensions { + AutoScalingGroupName = "${aws_autoscaling_group.autoscalinggroup.name}" + } +} \ No newline at end of file diff --git a/deployment/modules/tileserver/data.tf b/deployment/modules/tileserver/data.tf new file mode 100644 index 0000000..09a2f9e --- /dev/null +++ b/deployment/modules/tileserver/data.tf @@ -0,0 +1,75 @@ +data "aws_caller_identity" "current" {} +data "aws_elb_service_account" "main" {} + +data "aws_availability_zones" "all" {} + +data "aws_ami" "amazon_linux" { + most_recent = true + + filter { + name = "name" + values = ["mono-tileserver-ami *"] + } + + owners = ["self"] +} + +data "terraform_remote_state" "mono_vpc" { + backend = "s3" + config { + bucket = "${var.state_bucket}" + key = "${var.mono_vpc_remote_state}" + region = "${var.region}" + } +} + +data "template_file" "cloud_init" { + template = "${file("files/cloud-init.cfg")}" +} + +data "template_file" "shell-script" { + template = "${file("files/user-data.sh")}" + vars { + efs_dns_name = "${data.terraform_remote_state.mono_efs.efs_dns_name}" + } +} + +data "template_cloudinit_config" "cloudinit" { + part { + filename = "init.cfg" + content_type = "text/cloud-config" + content = "${data.template_file.cloud_init.rendered}" + } + + part { + content_type = "text/x-shellscript" + content = "${data.template_file.shell-script.rendered}" + } +} + +data "terraform_remote_state" "mono_efs" { + backend = "s3" + config { + bucket = "${var.state_bucket}" + key = "${var.mono_efs_remote_state}" + region = "${var.region}" + } +} + +data "terraform_remote_state" "mono_keypair" { + backend = "s3" + config { + bucket = "${var.state_bucket}" + key = "${var.mono_keypair_remote_state}" + region = "${var.region}" + } +} + +data "terraform_remote_state" "mono_alb" { + backend = "s3" + config { + bucket = "${var.state_bucket}" + key = "${var.mono_alb_remote_state}" + region = "${var.region}" + } +} \ No newline at end of file diff --git a/deployment/modules/tileserver/files/cloud-init.cfg b/deployment/modules/tileserver/files/cloud-init.cfg new file mode 100644 index 0000000..5fb6966 --- /dev/null +++ b/deployment/modules/tileserver/files/cloud-init.cfg @@ -0,0 +1 @@ +#cloud-config \ No newline at end of file diff --git a/deployment/modules/tileserver/files/user-data.sh b/deployment/modules/tileserver/files/user-data.sh new file mode 100644 index 0000000..660db7a --- /dev/null +++ b/deployment/modules/tileserver/files/user-data.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -x +#shellcheck disable=SC2154,SC2086,SC2035 +sudo sed -i -e 's/node \/usr\/src\/app\/ -p 80 "$@" \&/node \/usr\/src\/app\/ -p 8080 "$@" -c config.json \&/g' /usr/src/app/run.sh +{ + sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport "${efs_dns_name}:/mbtiles/" /data/mbtiles +} || { + echo "Could not mount EFS!!!" +} +bash /usr/src/app/run.sh & diff --git a/deployment/modules/tileserver/iam.tf b/deployment/modules/tileserver/iam.tf new file mode 100644 index 0000000..68f045a --- /dev/null +++ b/deployment/modules/tileserver/iam.tf @@ -0,0 +1,18 @@ +resource "aws_iam_role" "role" { + name = "maps-role-${var.environment}-${var.region}" + assume_role_policy = "${file("policies/assume-role-policy.json")}" +} + +resource "aws_iam_instance_profile" "profile" { + depends_on = ["aws_iam_role.role"] + name = "maps-profile-${var.environment}-${var.region}" + role = "${aws_iam_role.role.name}" +} + +data "template_file" "policies_json" { + template = "${file("policies/policies.json")}" + vars { + environment = "${var.environment}" + region = "${var.region}" + } +} \ No newline at end of file diff --git a/deployment/modules/tileserver/main.tf b/deployment/modules/tileserver/main.tf new file mode 100644 index 0000000..c532283 --- /dev/null +++ b/deployment/modules/tileserver/main.tf @@ -0,0 +1,7 @@ +terraform { + backend "s3" {} +} + +provider "aws" { + region = "${var.region}" +} diff --git a/deployment/modules/tileserver/outputs.tf b/deployment/modules/tileserver/outputs.tf new file mode 100644 index 0000000..a9cf885 --- /dev/null +++ b/deployment/modules/tileserver/outputs.tf @@ -0,0 +1,15 @@ +output "this_security_group_id" { + value = "${aws_security_group.this.id}" +} + +output "this_group_name" { + value = "${aws_autoscaling_group.autoscalinggroup.name}" +} + +output "this_group_policy_up_arn" { + value = "${aws_autoscaling_policy.this-autoscale_group_policy_up_x1.arn}" +} + +output "this_group_policy_down_arn" { + value = "${aws_autoscaling_policy.this-autoscale_group_policy_down_x1.arn}" +} \ No newline at end of file diff --git a/deployment/modules/tileserver/policies/assume-role-policy.json b/deployment/modules/tileserver/policies/assume-role-policy.json new file mode 100644 index 0000000..8f8ebf6 --- /dev/null +++ b/deployment/modules/tileserver/policies/assume-role-policy.json @@ -0,0 +1,16 @@ +{ + "Version": "2012-10-17", + "Statement": [{ + "Action": "sts:AssumeRole", + "Principal": { + "Service": [ + "ec2.amazonaws.com", + "ssm.amazonaws.com", + "sns.amazonaws.com", + "autoscaling.amazonaws.com" + ] + }, + "Effect": "Allow", + "Sid": "" + }] +} \ No newline at end of file diff --git a/deployment/modules/tileserver/policies/policies.json b/deployment/modules/tileserver/policies/policies.json new file mode 100644 index 0000000..423d5d4 --- /dev/null +++ b/deployment/modules/tileserver/policies/policies.json @@ -0,0 +1,45 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "", + "Effect": "Allow", + "Action": [ + "ssm:ListInventoryEntries", + "ec2:Describe*", + "autoscaling:Describe*", + "ssm:ListCommands", + "ssm:DescribeParameters", + "route53:ChangeResourceRecordSets", + "ssm:ListDocuments", + "ssm:GetInventory" + ], + "Resource": "*" + }, + { + "Sid": "", + "Effect": "Allow", + "Action": [ + "ssm:GetDocument", + "ssm:GetParameters", + "ssm:GetParameter" + ], + "Resource": [ + "arn:aws:ssm:${region}:*:document/*", + "arn:aws:ssm:${region}:*:parameter/*", + ] + }, + { + "Sid": "", + "Effect": "Allow", + "Action": "cloudwatch:*", + "Resource": "*" + }, + { + "Sid": "", + "Effect": "Allow", + "Action": "logs:*", + "Resource": "*" + } + ] +} \ No newline at end of file diff --git a/deployment/modules/tileserver/security-groups.tf b/deployment/modules/tileserver/security-groups.tf new file mode 100644 index 0000000..ea956fb --- /dev/null +++ b/deployment/modules/tileserver/security-groups.tf @@ -0,0 +1,52 @@ +resource "aws_security_group" "this" { + name_prefix = "maps-sg-" + description = "Security group for maps instances that allows web traffic inside the VPC" + vpc_id = "${data.terraform_remote_state.mono_vpc.vpc_id[0]}" + tags { + Name = "sg-maps" + } + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "this_rule_ingress_ssh" { + description = "Ingress ssh rule for deployed instance}" + security_group_id = "${aws_security_group.this.id}" + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] +} + +resource "aws_security_group_rule" "this_rule_ingress_traffic" { + description = "Ingress rule for deployed instance maps" + security_group_id = "${aws_security_group.this.id}" + type = "ingress" + from_port = 80 + to_port = 80 + protocol = "tcp" + source_security_group_id = "${data.terraform_remote_state.mono_alb.this_alb_sg}" +} + +resource "aws_security_group_rule" "this_rule_ingress_healthcheck" { + description = "Egress rule for deployed instance maps" + security_group_id = "${aws_security_group.this.id}" + type = "ingress" + from_port = 81 + to_port = 81 + protocol = "tcp" + source_security_group_id = "${data.terraform_remote_state.mono_alb.this_alb_sg}" +} + +resource "aws_security_group_rule" "this_rules_egress_traffic" { + description = "Egress rule for deployed instance traffic" + security_group_id = "${aws_security_group.this.id}" + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] +} + diff --git a/deployment/modules/tileserver/target_groups.tf b/deployment/modules/tileserver/target_groups.tf new file mode 100644 index 0000000..5bf452d --- /dev/null +++ b/deployment/modules/tileserver/target_groups.tf @@ -0,0 +1,24 @@ +resource "aws_alb_target_group" "target_group_this" { + name_prefix = "maps-" + port = "80" + protocol = "HTTP" + vpc_id = "${data.terraform_remote_state.mono_vpc.vpc_id[0]}" + stickiness { + type = "lb_cookie" + enabled = true + cookie_duration = "300" + } + health_check { + interval = "60" + path = "/health" + port = "80" + healthy_threshold = "2" + unhealthy_threshold = "3" + timeout = "5" + protocol = "HTTP" + matcher = "200" + } + lifecycle { + create_before_destroy = true + } +} diff --git a/deployment/modules/tileserver/variables.tf b/deployment/modules/tileserver/variables.tf new file mode 100644 index 0000000..29a7c27 --- /dev/null +++ b/deployment/modules/tileserver/variables.tf @@ -0,0 +1,51 @@ +variable "instance_type" { + description = "Type of instances to be created" + default = "t2.micro" +} + +variable "region" { + type = "string" + description = "Which Region to deploy to" + default = "eu-central-1" +} + +variable "environment" { + type = "string" + description = "Environment name" + default = "dev" +} + +variable "version" { + type = "string" + description = "Build version" +} + +variable "mono_region" { + type = "string" + description = "Dns zone id" +} + +variable "mono_vpc_remote_state" { + type = "string" + description = "Mono VPC remote state key" +} + +variable "state_bucket" { + type = "string" + description = "Name of bucket containing remote state" +} + +variable "mono_efs_remote_state" { + type = "string" + description = "Mono EFS remote state key" +} + +variable "mono_keypair_remote_state" { + type = "string" + description = "Mono keypair remote state key" +} + +variable "mono_alb_remote_state" { + type = "string" + description = "Remote state for mono_alb" +} \ No newline at end of file