Created
November 9, 2016 00:03
-
-
Save joshgarnett/db813ed7d6f9c3d8a31ae05926cd6d10 to your computer and use it in GitHub Desktop.
Minimal ECS Terraform Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Update your region | |
provider "aws" { | |
region = "${var.aws_region}" | |
} | |
resource "aws_ecs_cluster" "ecs_cluster" { | |
name = "test-cluster" | |
} | |
# | |
# ECS Instance Section | |
# | |
# | |
# It is assumed you already have a VPC setup, you should replace the values called out | |
# | |
# Update your vpc_id | |
resource "aws_security_group" "internal_only_docker" { | |
name = "internal_only_docker" | |
description = "Allow internal traffic to docker servers" | |
vpc_id = "${var.vpc_id}" | |
ingress { | |
from_port = 0 | |
to_port = 0 | |
protocol = "-1" | |
self = true | |
} | |
egress { | |
from_port = 0 | |
to_port = 0 | |
protocol = "-1" | |
cidr_blocks = ["0.0.0.0/0"] | |
} | |
tags { | |
Name = "internal_only_docker" | |
} | |
} | |
resource "aws_iam_role" "ecsInstanceRole" { | |
name = "ecsInstanceRole" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "ec2.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy_attachment" "ecsInstanceRole" { | |
role = "${aws_iam_role.ecsInstanceRole.name}" | |
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" | |
} | |
data "template_file" "user_data" { | |
template = "${file("user_data.sh")}" | |
vars { | |
ecs_cluster = "${aws_ecs_cluster.ecs_cluster.name}" | |
} | |
} | |
# Grab AMI from http://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html | |
# Update our key_name | |
resource "aws_launch_configuration" "docker_launch_cfg" { | |
image_id = "ami-56ed4936" | |
instance_type = "t2.small" | |
key_name = "${var.key_name}" | |
security_groups = ["${aws_security_group.internal_only_docker.id}"] | |
associate_public_ip_address = true | |
enable_monitoring = false | |
ebs_optimized = "false" | |
user_data = "${data.template_file.user_data.rendered}" | |
iam_instance_profile = "${aws_iam_role.ecsInstanceRole.name}" | |
root_block_device { | |
volume_size = "20" | |
volume_type = "gp2" | |
delete_on_termination = true | |
} | |
} | |
# Update subnets | |
resource "aws_autoscaling_group" "docker_asg" { | |
name = "docker-${var.environment}" | |
min_size = "1" | |
max_size = "1" | |
vpc_zone_identifier = ["${var.subnet_id_a}", "${var.subnet_id_b}", "${var.subnet_id_c}"] | |
health_check_grace_period = 300 | |
health_check_type = "EC2" | |
termination_policies = ["OldestInstance"] | |
launch_configuration = "${aws_launch_configuration.docker_launch_cfg.id}" | |
} | |
# | |
# ECS Service Section | |
# | |
# Update your vpc_id | |
resource "aws_security_group" "external_web" { | |
name = "external_web" | |
description = "Allow external traffic to port 80 & 443" | |
vpc_id = "${var.vpc_id}" | |
ingress { | |
from_port = 80 | |
to_port = 80 | |
protocol = "tcp" | |
cidr_blocks = ["0.0.0.0/0"] | |
} | |
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"] | |
} | |
tags { | |
Name = "external_web" | |
} | |
} | |
resource "aws_iam_role" "ecsServiceRole" { | |
name = "ecsServiceRole" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "ecs.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy_attachment" "ecsServiceRole" { | |
role = "${aws_iam_role.ecsServiceRole.name}" | |
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole" | |
} | |
data "template_file" "web_task_definition" { | |
template = "${file("web.json")}" | |
} | |
resource "aws_ecs_task_definition" "web" { | |
family = "web" | |
container_definitions = "${data.template_file.web_task_definition.rendered}" | |
} | |
resource "aws_ecs_service" "web" { | |
name = "web" | |
cluster = "${aws_ecs_cluster.ecs_cluster.id}" | |
task_definition = "${aws_ecs_task_definition.web.arn}" | |
desired_count = "1" | |
iam_role = "${aws_iam_role.ecsServiceRole.name}" | |
load_balancer { | |
elb_name = "${aws_elb.web.id}" | |
container_name = "nginx" | |
container_port = 80 | |
} | |
} | |
# Update subnets | |
resource "aws_elb" "web" { | |
name = "web" | |
subnets = ["${var.subnet_id_a}", "${var.subnet_id_b}", "${var.subnet_id_c}"] | |
security_groups = ["${aws_security_group.internal_only_docker.id}", "${aws_security_group.external_web.id}"] | |
listener { | |
instance_port = 80 | |
instance_protocol = "http" | |
lb_port = 80 | |
lb_protocol = "http" | |
} | |
# Exercise to reader to setup 443 | |
health_check { | |
healthy_threshold = 2 | |
unhealthy_threshold = 2 | |
timeout = 5 | |
target = "HTTP:80/" | |
interval = 30 | |
} | |
cross_zone_load_balancing = true | |
idle_timeout = 60 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Connect to this host once everything is working | |
output "web_elb" { | |
value = "${aws_elb.web.dns_name}" | |
} | |
# | |
# There may be some delays once terraform apply completes as the ECS service waits for | |
# the docker instance to be up and running to start the container. | |
# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
echo ECS_CLUSTER=${ecs_cluster} >> /etc/ecs/ecs.config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "nginx", | |
"image": "nginx", | |
"cpu": 128, | |
"memory": 32, | |
"essential": true, | |
"portMappings": [ | |
{ | |
"containerPort": 80, | |
"hostPort": 80 | |
}, | |
{ | |
"containerPort": 443, | |
"hostPort": 443 | |
} | |
] | |
} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment