diff --git a/README.md b/README.md index f554d6d..ae8640c 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,13 @@ The workflow for each part is basically quite the same: 3. Run `terraform plan -var-file=configuration.tfvars` and confirm changes 4. Run `terraform apply -var-file=configuration.tfvars` +## Fargate + +By default the ECS cluster is deployed on EC2 ECS instances. Specifying variable +``` + launch_type = "FARGATE" +``` +will cause the cluster to use FARGATE infrastructure. Currently fargate doesn't support docker private registries. Only Amazon's ECR Registry and Docker Public Registries. ## Additional information diff --git a/asg/alb.tf b/asg/alb.tf index 00adea5..934092e 100644 --- a/asg/alb.tf +++ b/asg/alb.tf @@ -17,6 +17,8 @@ resource "aws_alb_target_group" "webapp_tg" { deregistration_delay = 180 + target_type = "${var.launch_type == "FARGATE" ? "ip" : "instance"}" + health_check { interval = "60" path = "/" diff --git a/asg/autoscaling.tf b/asg/autoscaling.tf index 922e8b6..8a18311 100644 --- a/asg/autoscaling.tf +++ b/asg/autoscaling.tf @@ -1,4 +1,5 @@ resource "aws_launch_configuration" "webapp_on_demand" { + count = "${var.launch_type == "FARGATE" ? 0 : 1}" instance_type = "${var.instance_type}" image_id = "${lookup(var.ecs_image_id, var.aws_region)}" iam_instance_profile = "${var.ecs_instance_profile}" @@ -13,10 +14,11 @@ resource "aws_launch_configuration" "webapp_on_demand" { } resource "aws_autoscaling_group" "webapp_on_demand" { + count = "${var.launch_type == "FARGATE" ? 0 : 1}" name = "${var.name_prefix}_webapp_on_demand" max_size = 50 min_size = 0 - desired_capacity = "${var.desired_capacity_on_demand}" + desired_capacity = "${var.desired_capacity_on_demand}" health_check_grace_period = 300 health_check_type = "EC2" force_delete = true @@ -35,6 +37,7 @@ resource "aws_autoscaling_group" "webapp_on_demand" { } data "template_file" "autoscaling_user_data" { + count = "${var.launch_type == "FARGATE" ? 0 : 1}" template = "${file("autoscaling_user_data.tpl")}" vars { ecs_cluster = "${aws_ecs_cluster.webapp_cluster.name}" diff --git a/asg/configuration.tfvars b/asg/configuration.tfvars index f213d4a..a1bb580 100644 --- a/asg/configuration.tfvars +++ b/asg/configuration.tfvars @@ -10,7 +10,7 @@ desired_capacity_on_demand = 2 ec2_key_name = "key-name" instance_type = "t2.micro" minimum_healthy_percent_webapp = 50 - +launch_type = "EC2" # can also be "FARGATE" ## # This is a sample (public) Docker image from which can be accessed at https://github.com/docker-training/webapp # This sample image utilizes Flask and it's not RECOMMENDED to run it directly in production (performance degradation) @@ -20,7 +20,7 @@ webapp_docker_image_name = "training/webapp" webapp_docker_image_tag = "latest" ## -# These variables are required, please fill it out with your environment outputs +# These variables are required, please fill it out with your environment outputs or use remote state references ## sg_webapp_albs_id = "sg-12345678" sg_webapp_instances_id = "sg-23456789" @@ -29,3 +29,4 @@ subnet_ids = "subnet-34567890,subnet-4567890a" ecs_instance_profile = "arn:aws:iam::123456789012:instance-profile/tutorial-test_ecs_instance_profile" ecs_service_role = "tutorial-test_ecs_service_role" +ecs_task_execution_role = "arn:aws:iam::123456789012:role/tutorial-test_ecs_task_execution_role" # only used with launch type FARGATE diff --git a/asg/ecs.tf b/asg/ecs.tf index 7f92609..fbf216b 100644 --- a/asg/ecs.tf +++ b/asg/ecs.tf @@ -5,6 +5,7 @@ resource "aws_ecs_cluster" "webapp_cluster" { /* ECS service definition */ resource "aws_ecs_service" "webapp_service" { + count = "${var.launch_type == "FARGATE" ? 0 : 1}" name = "${var.name_prefix}_webapp_service" cluster = "${aws_ecs_cluster.webapp_cluster.id}" task_definition = "${aws_ecs_task_definition.webapp_definition.arn}" @@ -23,9 +24,51 @@ resource "aws_ecs_service" "webapp_service" { } } +resource "aws_ecs_service" "webapp_service_fargate" { + count = "${var.launch_type == "FARGATE" ? 1 : 0}" + name = "${var.name_prefix}_webapp_service" + cluster = "${aws_ecs_cluster.webapp_cluster.id}" + task_definition = "${aws_ecs_task_definition.webapp_definition_fargate.arn}" + launch_type = "FARGATE" + desired_count = "${var.count_webapp}" + deployment_minimum_healthy_percent = "${var.minimum_healthy_percent_webapp}" + iam_role = "${var.ecs_service_role}" + + network_configuration { + security_groups = ["${var.sg_webapp_instances_id}"] + subnets = ["${split(",", var.subnet_ids)}"] + } + + load_balancer { + target_group_arn = "${aws_alb_target_group.webapp_tg.arn}" + container_name = "webapp" + container_port = 5000 + } + + lifecycle { + create_before_destroy = true + } +} + resource "aws_ecs_task_definition" "webapp_definition" { + count = "${var.launch_type == "FARGATE" ? 0 : 1}" + family = "${var.name_prefix}_webapp" + container_definitions = "${data.template_file.task_webapp.rendered}" + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_ecs_task_definition" "webapp_definition_fargate" { + count = "${var.launch_type == "FARGATE" ? 1 : 0}" family = "${var.name_prefix}_webapp" container_definitions = "${data.template_file.task_webapp.rendered}" + requires_compatibilities = ["FARGATE"] + network_mode = "awsvpc" + execution_role_arn = "${var.ecs_task_execution_role}" + cpu = "512" + memory = "1024" lifecycle { create_before_destroy = true diff --git a/asg/vars.tf b/asg/vars.tf index a6d92f2..83c116e 100644 --- a/asg/vars.tf +++ b/asg/vars.tf @@ -24,6 +24,7 @@ variable "ecs_image_id" { us-west-1 = "ami-9ad4dcfa" us-west-2 = "ami-92e06fea" } + description = "ECS Optimized AMI. Not used with launch_type FARGATE." } variable "webapp_docker_image_name" { @@ -43,7 +44,12 @@ variable "count_webapp" { variable "desired_capacity_on_demand" { default = 2 - description = "Number of instance to run" + description = "Number of instances to run. Not used with launch_type FARGATE" +} + +variable "launch_type" { + default = "EC2" + description = "launch type. set to FARGATE to use fargate. default is EC2 launch type." } variable "ec2_key_name" { @@ -53,7 +59,7 @@ variable "ec2_key_name" { variable "instance_type" { default = "t2.micro" - description = "EC2 instance type to use" + description = "EC2 instance type to use. Not used with launch_type FARGATE" } variable "minimum_healthy_percent_webapp" { @@ -70,6 +76,8 @@ variable "subnet_ids" {} /* Consume static outputs */ variable "ecs_instance_profile" {} variable "ecs_service_role" {} +variable "ecs_task_execution_role" {} + /* Region settings for AWS provider */ provider "aws" { diff --git a/static/iam/iam.tf b/static/iam/iam.tf index d2d6d89..577102b 100644 --- a/static/iam/iam.tf +++ b/static/iam/iam.tf @@ -104,3 +104,51 @@ resource "aws_iam_role_policy" "ecs_service_role_policy" { } EOF } + +/** + * Role for ECS using Fargate to use awslogs and access ECR registry +*/ + + resource "aws_iam_role" "ecs_task_execution_role" { + name = "${var.name_prefix}_ecs_task_execution_role" + assume_role_policy = <