Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
jch254 committed Nov 5, 2016
0 parents commit d7981e5
Show file tree
Hide file tree
Showing 93 changed files with 5,177 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
@@ -0,0 +1,8 @@
dist/
npm-debug.log
yarn-error.log
node_modules/
.DS_Store
.terraform
*.tfstate
*.tfstate.backup
5 changes: 5 additions & 0 deletions README.md
@@ -0,0 +1,5 @@
# Terraform-ecs-autoscale-alb

TODO: Write readmes
TODO: Add Dynamo DB and CRUD API
TODO: Add service contracts and tests with Apiary and Dredd
9 changes: 9 additions & 0 deletions alpha-service/alpha-service.tfvars
@@ -0,0 +1,9 @@
region = "ap-southeast-2"

service_name = "alpha-service"

container_port = "3000"

docker_image = "jch254/ecs-demo-crud-service"

docker_tag = "latest"
15 changes: 15 additions & 0 deletions alpha-service/deploy.bash
@@ -0,0 +1,15 @@
#!/bin/bash -ex

cd infra

terraform remote config -backend=s3 \
-backend-config="bucket=603-terraform-remote-state" \
-backend-config="key=terraform-ecs-autoscale-alb/alpha-service.tfstate" \
-backend-config="region=ap-southeast-2" \
-backend-config="encrypt=true"

terraform get --update
terraform plan -var-file alpha-service.tfvars
terraform apply -var-file alpha-service.tfvars

cd ..
47 changes: 47 additions & 0 deletions alpha-service/modules.tf
@@ -0,0 +1,47 @@
provider "aws" {
region = "${var.region}"
}

data "terraform_remote_state" "base_remote_state" {
backend = "s3"
config {
bucket = "603-terraform-remote-state"
key = "terraform-ecs-autoscale-alb/base-infra.tfstate"
region = "${var.region}"
}
}

module "alb_listener" {
source = "./modules/alb-listener"

service_name = "${var.service_name}"
container_port = "${var.container_port}"
vpc_id = "${data.terraform_remote_state.base_remote_state.vpc_id}"
alb_listener_arn = "${data.terraform_remote_state.base_remote_state.alb_listener_arn}"
}

module "ecs_service" {
source = "./modules/ecs-service"

service_name = "${var.service_name}"
docker_image = "${var.docker_image}"
docker_tag = "${var.docker_tag}"
container_cpu = "${var.container_cpu}"
container_memory = "${var.container_memory}"
container_port = "${var.container_port}"
region = "${var.region}"
cluster_name = "${data.terraform_remote_state.base_remote_state.cluster_name}"
desired_count = "${var.min_capacity}"
ecs_service_role_arn = "${data.terraform_remote_state.base_remote_state.ecs_service_role_arn}"
target_group_arn = "${module.alb_listener.target_group_arn}"
}

module "autoscaling" {
source = "./modules/autoscaling"

service_name = "${var.service_name}"
cluster_name = "${data.terraform_remote_state.base_remote_state.cluster_name}"
ecs_service_autoscale_role_arn = "${data.terraform_remote_state.base_remote_state.ecs_service_autoscale_role_arn}"
min_capacity = "${var.min_capacity}"
max_capacity = "${var.max_capacity}"
}
26 changes: 26 additions & 0 deletions alpha-service/modules/alb-listener/main.tf
@@ -0,0 +1,26 @@
resource "aws_alb_target_group" "alpha_service_tg" {
name = "${replace(var.service_name, "/(.{0,28})(.*)/", "$1")}-tg"

protocol = "HTTP"
port = "${var.container_port}"
vpc_id = "${var.vpc_id}"

health_check {
path = "/ping"
}
}

resource "aws_alb_listener_rule" "alpha_service_listener" {
listener_arn = "${var.alb_listener_arn}"
priority = 100

action {
type = "forward"
target_group_arn = "${aws_alb_target_group.alpha_service_tg.arn}"
}

condition {
field = "path-pattern"
values = ["/alpha/*"]
}
}
3 changes: 3 additions & 0 deletions alpha-service/modules/alb-listener/outputs.tf
@@ -0,0 +1,3 @@
output "target_group_arn" {
value = "${aws_alb_target_group.alpha_service_tg.arn}"
}
15 changes: 15 additions & 0 deletions alpha-service/modules/alb-listener/variables.tf
@@ -0,0 +1,15 @@
variable "service_name" {
description = "Name of service"
}

variable "container_port" {
description = "Port that service will listen on"
}

variable "vpc_id" {
description = "Id of the VPC where service should be deployed"
}

variable "alb_listener_arn" {
description = "ARN of ALB listener"
}
115 changes: 115 additions & 0 deletions alpha-service/modules/autoscaling/main.tf
@@ -0,0 +1,115 @@
# A CloudWatch alarm that moniors CPU utilization of containers for scaling up
resource "aws_cloudwatch_metric_alarm" "alpha_service_cpu_high" {
alarm_name = "${var.service_name}-cpu-utilization-above-80"
alarm_description = "This alarm monitors ${var.service_name} CPU utilization for scaling up"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = "CPUUtilization"
namespace = "AWS/ECS"
period = "120"
statistic = "Average"
threshold = "80"
alarm_actions = ["${aws_appautoscaling_policy.scale_up.arn}"]

dimensions {
ClusterName = "${var.cluster_name}"
ServiceName = "${var.service_name}"
}
}

# A CloudWatch alarm that monitors CPU utilization of containers for scaling down
resource "aws_cloudwatch_metric_alarm" "alpha_service_cpu_low" {
alarm_name = "${var.service_name}-cpu-utilization-below-5"
alarm_description = "This alarm monitors ${var.service_name} CPU utilization for scaling down"
comparison_operator = "LessThanThreshold"
evaluation_periods = "1"
metric_name = "CPUUtilization"
namespace = "AWS/ECS"
period = "120"
statistic = "Average"
threshold = "5"
alarm_actions = ["${aws_appautoscaling_policy.scale_down.arn}"]

dimensions {
ClusterName = "${var.cluster_name}"
ServiceName = "${var.service_name}"
}
}

# A CloudWatch alarm that monitors memory utilization of containers for scaling up
resource "aws_cloudwatch_metric_alarm" "alpha_service_memory_high" {
alarm_name = "${var.service_name}-memory-utilization-above-80"
alarm_description = "This alarm monitors ${var.service_name} memory utilization for scaling up"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = "MemoryUtilization"
namespace = "AWS/ECS"
period = "120"
statistic = "Average"
threshold = "80"
alarm_actions = ["${aws_appautoscaling_policy.scale_up.arn}"]

dimensions {
ClusterName = "${var.cluster_name}"
ServiceName = "${var.service_name}"
}
}

# A CloudWatch alarm that monitors memory utilization of containers for scaling down
resource "aws_cloudwatch_metric_alarm" "alpha_service_memory_low" {
alarm_name = "${var.service_name}-memory-utilization-below-5"
alarm_description = "This alarm monitors ${var.service_name} memory utilization for scaling down"
comparison_operator = "LessThanThreshold"
evaluation_periods = "1"
metric_name = "MemoryUtilization"
namespace = "AWS/ECS"
period = "120"
statistic = "Average"
threshold = "5"
alarm_actions = ["${aws_appautoscaling_policy.scale_down.arn}"]

dimensions {
ClusterName = "${var.cluster_name}"
ServiceName = "${var.service_name}"
}
}

resource "aws_appautoscaling_target" "target" {
resource_id = "service/${var.cluster_name}/${var.service_name}"
role_arn = "${var.ecs_service_autoscale_role_arn}"
scalable_dimension = "ecs:service:DesiredCount"
min_capacity = "${var.min_capacity}"
max_capacity = "${var.max_capacity}"
}

resource "aws_appautoscaling_policy" "scale_up" {
name = "${var.service_name}-scale-up"
resource_id = "service/${var.cluster_name}/${var.service_name}"
scalable_dimension = "ecs:service:DesiredCount"
adjustment_type = "ChangeInCapacity"
cooldown = 120
metric_aggregation_type = "Average"

step_adjustment {
metric_interval_lower_bound = 0
scaling_adjustment = 1
}

depends_on = ["aws_appautoscaling_target.target"]
}

resource "aws_appautoscaling_policy" "scale_down" {
name = "${var.service_name}-scale-down"
resource_id = "service/${var.cluster_name}/${var.service_name}"
scalable_dimension = "ecs:service:DesiredCount"
adjustment_type = "ChangeInCapacity"
cooldown = 120
metric_aggregation_type = "Average"

step_adjustment {
metric_interval_upper_bound = 0
scaling_adjustment = -1
}

depends_on = ["aws_appautoscaling_target.target"]
}
Empty file.
19 changes: 19 additions & 0 deletions alpha-service/modules/autoscaling/variables.tf
@@ -0,0 +1,19 @@
variable "service_name" {
description = "Name of service"
}

variable "cluster_name" {
description = "Name of ECS cluster"
}

variable "ecs_service_autoscale_role_arn" {
description = "ARN of IAM role for ECS service autoscaling"
}

variable "min_capacity" {
description = "Minimum number of containers to run"
}

variable "max_capacity" {
description = "Minimum number of containers to run"
}
41 changes: 41 additions & 0 deletions alpha-service/modules/ecs-service/main.tf
@@ -0,0 +1,41 @@
resource "aws_cloudwatch_log_group" "alpha_service_lg" {
name = "${var.service_name}"
}

data "template_file" "task_definition" {
template = "${file("${path.module}/task-definition.json")}"

vars {
service_name = "${var.service_name}"
docker_image = "${var.docker_image}"
docker_tag = "${var.docker_tag}"
container_cpu = "${var.container_cpu}"
container_memory = "${var.container_memory}"
container_port = "${var.container_port}"
log_group_name = "${aws_cloudwatch_log_group.alpha_service_lg.name}"
log_group_region = "${var.region}"
}
}

# The ECS task that specifies what Docker containers we need to run the service
resource "aws_ecs_task_definition" "alpha_service" {
family = "${var.service_name}"
container_definitions = "${data.template_file.task_definition.rendered}"
}

# A long-running ECS service for the alpha_service task
resource "aws_ecs_service" "alpha_service" {
name = "${var.service_name}"
cluster = "${var.cluster_name}"
task_definition = "${aws_ecs_task_definition.alpha_service.arn}"
desired_count = "${var.desired_count}"
deployment_minimum_healthy_percent = 50
deployment_maximum_percent = 100
iam_role = "${var.ecs_service_role_arn}"

load_balancer {
target_group_arn = "${var.target_group_arn}"
container_name = "${var.service_name}"
container_port = "${var.container_port}"
}
}
3 changes: 3 additions & 0 deletions alpha-service/modules/ecs-service/outputs.tf
@@ -0,0 +1,3 @@
output "service_name" {
value = "${aws_ecs_service.alpha_service.name}"
}
24 changes: 24 additions & 0 deletions alpha-service/modules/ecs-service/task-definition.json
@@ -0,0 +1,24 @@
[
{
"name": "${service_name}",
"image": "${docker_image}:${docker_tag}",
"cpu": ${container_cpu},
"memory": ${container_memory},
"essential": true,
"portMappings": [
{
"containerPort": ${container_port}
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "${log_group_name}",
"awslogs-region": "${log_group_region}"
}
},
"environment": [
{ "name": "SERVICE_NAME", "value": "${service_name}"}
]
}
]
43 changes: 43 additions & 0 deletions alpha-service/modules/ecs-service/variables.tf
@@ -0,0 +1,43 @@
variable "service_name" {
description = "Name of service"
}

variable "docker_image" {
description = "Docker image to run"
}

variable "docker_tag" {
description = "Tag of docker image to run"
}

variable "container_cpu" {
description = "The number of cpu units to reserve for the container. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html"
}

variable "container_memory" {
description = "The number of MiB of memory to reserve for the container. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html"
}

variable "container_port" {
description = "Port that service will listen on"
}

variable "region" {
description = "AWS region to deploy to (e.g. ap-southeast-2)"
}

variable "cluster_name" {
description = "Name of ECS cluster"
}

variable "desired_count" {
description = "Initial number of containers to run"
}

variable "ecs_service_role_arn" {
description = "ARN of IAM role for ECS service"
}

variable "target_group_arn" {
description = "ARN of ALB target group for service"
}

0 comments on commit d7981e5

Please sign in to comment.