Last active
January 15, 2022 23:05
-
-
Save tusharvikky/4a6835b18d6e5a4902f81a5f22542b55 to your computer and use it in GitHub Desktop.
Deploying your nodejs to Fargate, AWS ECS/ECR via Terraform
This file contains hidden or 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
resource "aws_lb" "main" { | |
name = "${var.name}-alb-${var.environment}" | |
internal = false | |
load_balancer_type = "application" | |
security_groups = var.alb_security_groups | |
subnets = var.subnets.*.id | |
enable_deletion_protection = false | |
tags = { | |
Name = "${var.name}-alb-${var.environment}" | |
Environment = var.environment | |
} | |
} | |
resource "aws_alb_target_group" "main" { | |
name = "${var.name}-tg-${var.environment}" | |
port = 80 | |
protocol = "HTTP" | |
vpc_id = var.vpc_id | |
target_type = "ip" | |
health_check { | |
healthy_threshold = "3" | |
interval = "30" | |
protocol = "HTTP" | |
matcher = "200" | |
timeout = "3" | |
path = var.health_check_path | |
unhealthy_threshold = "2" | |
} | |
tags = { | |
Name = "${var.name}-tg-${var.environment}" | |
Environment = var.environment | |
} | |
depends_on = ["aws_lb.main"] | |
} | |
# Redirect to https listener | |
resource "aws_alb_listener" "http" { | |
load_balancer_arn = aws_lb.main.id | |
port = 80 | |
protocol = "HTTP" | |
default_action { | |
type = "redirect" | |
redirect { | |
port = 443 | |
protocol = "HTTPS" | |
status_code = "HTTP_301" | |
} | |
} | |
} | |
# Redirect traffic to target group | |
resource "aws_alb_listener" "https" { | |
load_balancer_arn = aws_lb.main.id | |
port = 443 | |
protocol = "HTTPS" | |
ssl_policy = "ELBSecurityPolicy-2016-08" | |
certificate_arn = var.alb_tls_cert_arn | |
default_action { | |
target_group_arn = aws_alb_target_group.main.id | |
type = "forward" | |
} | |
} |
This file contains hidden or 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
resource "aws_appautoscaling_policy" "ecs_policy_memory" { | |
name = "memory-autoscaling" | |
policy_type = "TargetTrackingScaling" | |
resource_id = aws_appautoscaling_target.ecs_target.resource_id | |
scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension | |
service_namespace = aws_appautoscaling_target.ecs_target.service_namespace | |
target_tracking_scaling_policy_configuration { | |
predefined_metric_specification { | |
predefined_metric_type = "ECSServiceAverageMemoryUtilization" | |
} | |
target_value = 80 | |
scale_in_cooldown = 300 | |
scale_out_cooldown = 300 | |
} | |
} | |
resource "aws_appautoscaling_policy" "ecs_policy_cpu" { | |
name = "cpu-autoscaling" | |
policy_type = "TargetTrackingScaling" | |
resource_id = aws_appautoscaling_target.ecs_target.resource_id | |
scalable_dimension = aws_appautoscaling_target.ecs_target.scalable_dimension | |
service_namespace = aws_appautoscaling_target.ecs_target.service_namespace | |
target_tracking_scaling_policy_configuration { | |
predefined_metric_specification { | |
predefined_metric_type = "ECSServiceAverageCPUUtilization" | |
} | |
target_value = 60 | |
scale_in_cooldown = 300 | |
scale_out_cooldown = 300 | |
} | |
} |
This file contains hidden or 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
resource "aws_appautoscaling_target" "ecs_target" { | |
max_capacity = 4 | |
min_capacity = 1 | |
resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.main.name}" | |
scalable_dimension = "ecs:service:DesiredCount" | |
service_namespace = "ecs" | |
} |
This file contains hidden or 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
resource "aws_ecr_repository" "main" { | |
name = "${var.name}-${var.environment}" | |
image_tag_mutability = "MUTABLE" | |
image_scanning_configuration { | |
scan_on_push = false | |
} | |
} | |
resource "aws_ecr_lifecycle_policy" "main" { | |
repository = aws_ecr_repository.main.name | |
policy = jsonencode({ | |
rules = [{ | |
rulePriority = 1 | |
description = "keep last 10 images" | |
action = { | |
type = "expire" | |
} | |
selection = { | |
tagStatus = "any" | |
countType = "imageCountMoreThan" | |
countNumber = 10 | |
} | |
}] | |
}) | |
} |
This file contains hidden or 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
resource "aws_ecs_cluster" "main" { | |
name = "${var.name}-cluster-${var.environment}" | |
tags = { | |
Name = "${var.name}-cluster-${var.environment}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
resource "aws_iam_role" "ecs_task_role" { | |
name = "${var.name}-ecsTaskRole-${var.environment}" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "ecs-tasks.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_policy" "dynamodb" { | |
name = "${var.name}-task-policy-dynamodb-${var.environment}" | |
description = "Policy that allows access to DynamoDB" | |
policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"dynamodb:CreateTable", | |
"dynamodb:UpdateTimeToLive", | |
"dynamodb:PutItem", | |
"dynamodb:DescribeTable", | |
"dynamodb:ListTables", | |
"dynamodb:DeleteItem", | |
"dynamodb:GetItem", | |
"dynamodb:Scan", | |
"dynamodb:Query", | |
"dynamodb:UpdateItem", | |
"dynamodb:UpdateTable" | |
], | |
"Resource": "*" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy_attachment" "ecs-task-role-policy-attachment" { | |
role = aws_iam_role.ecs_task_role.name | |
policy_arn = aws_iam_policy.dynamodb.arn | |
} |
This file contains hidden or 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
resource "aws_ecs_service" "main" { | |
name = "${var.name}-service-${var.environment}" | |
cluster = aws_ecs_cluster.main.id | |
task_definition = aws_ecs_task_definition.main.arn | |
desired_count = var.service_desired_count | |
deployment_minimum_healthy_percent = 50 | |
deployment_maximum_percent = 200 | |
health_check_grace_period_seconds = 60 | |
launch_type = "FARGATE" | |
scheduling_strategy = "REPLICA" | |
network_configuration { | |
security_groups = var.ecs_service_security_groups | |
subnets = var.subnets.*.id | |
assign_public_ip = false | |
} | |
load_balancer { | |
target_group_arn = var.aws_alb_target_group_arn | |
container_name = "${var.name}-container-${var.environment}" | |
container_port = var.container_port | |
} | |
# we ignore task_definition changes as the revision changes on deploy | |
# of a new version of the application | |
# desired_count is ignored as it can change due to autoscaling policy | |
lifecycle { | |
ignore_changes = [task_definition, desired_count] | |
} | |
} |
This file contains hidden or 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
resource "aws_ecs_task_definition" "main" { | |
family = "${var.name}-task-${var.environment}" | |
network_mode = "awsvpc" | |
requires_compatibilities = ["FARGATE"] | |
cpu = var.container_cpu | |
memory = var.container_memory | |
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn | |
task_role_arn = aws_iam_role.ecs_task_role.arn | |
container_definitions = jsonencode([{ | |
name = "${var.name}-container-${var.environment}" | |
image = "${var.container_image}:latest" | |
essential = true | |
environment = var.container_environment | |
portMappings = [{ | |
protocol = "tcp" | |
containerPort = var.container_port | |
hostPort = var.container_port | |
}] | |
logConfiguration = { | |
logDriver = "awslogs" | |
options = { | |
awslogs-group = aws_cloudwatch_log_group.main.name | |
awslogs-stream-prefix = "ecs" | |
awslogs-region = var.region | |
} | |
} | |
secrets = var.container_secrets | |
}]) | |
tags = { | |
Name = "${var.name}-task-${var.environment}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
resource "aws_iam_role" "ecs_task_execution_role" { | |
name = "${var.name}-ecsTaskExecutionRole-${var.environment}" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "ecs-tasks.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy_attachment" "ecs-task-execution-role-policy-attachment" { | |
role = aws_iam_role.ecs_task_execution_role.name | |
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" | |
} |
This file contains hidden or 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
resource "aws_nat_gateway" "main" { | |
count = length(var.private_subnets) | |
allocation_id = element(aws_eip.nat.*.id, count.index) | |
subnet_id = element(aws_subnet.public.*.id, count.index) | |
depends_on = [aws_internet_gateway.main] | |
tags = { | |
Name = "${var.name}-nat-${var.environment}-${format("%03d", count.index+1)}" | |
Environment = var.environment | |
} | |
} | |
resource "aws_eip" "nat" { | |
count = length(var.private_subnets) | |
vpc = true | |
tags = { | |
Name = "${var.name}-eip-${var.environment}-${format("%03d", count.index+1)}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
resource "aws_route_table" "public" { | |
vpc_id = aws_vpc.main.id | |
tags = { | |
Name = "${var.name}-routing-table-public" | |
Environment = var.environment | |
} | |
} | |
resource "aws_route" "public" { | |
route_table_id = aws_route_table.public.id | |
destination_cidr_block = "0.0.0.0/0" | |
gateway_id = aws_internet_gateway.main.id | |
} | |
resource "aws_route_table_association" "public" { | |
count = length(var.public_subnets) | |
subnet_id = element(aws_subnet.public.*.id, count.index) | |
route_table_id = aws_route_table.public.id | |
} |
This file contains hidden or 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
resource "aws_route_table" "private" { | |
count = length(var.private_subnets) | |
vpc_id = aws_vpc.main.id | |
tags = { | |
Name = "${var.name}-routing-table-private-${format("%03d", count.index+1)}" | |
Environment = var.environment | |
} | |
} | |
resource "aws_route" "private" { | |
count = length(compact(var.private_subnets)) | |
route_table_id = element(aws_route_table.private.*.id, count.index) | |
destination_cidr_block = "0.0.0.0/0" | |
nat_gateway_id = element(aws_nat_gateway.main.*.id, count.index) | |
} | |
resource "aws_route_table_association" "private" { | |
count = length(var.private_subnets) | |
subnet_id = element(aws_subnet.private.*.id, count.index) | |
route_table_id = element(aws_route_table.private.*.id, count.index) | |
} |
This file contains hidden or 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
resource "aws_security_group" "alb" { | |
name = "${var.name}-sg-alb-${var.environment}" | |
vpc_id = var.vpc_id | |
ingress { | |
protocol = "tcp" | |
from_port = 80 | |
to_port = 80 | |
cidr_blocks = ["0.0.0.0/0"] | |
ipv6_cidr_blocks = ["::/0"] | |
} | |
ingress { | |
protocol = "tcp" | |
from_port = 443 | |
to_port = 443 | |
cidr_blocks = ["0.0.0.0/0"] | |
ipv6_cidr_blocks = ["::/0"] | |
} | |
egress { | |
protocol = "-1" | |
from_port = 0 | |
to_port = 0 | |
cidr_blocks = ["0.0.0.0/0"] | |
ipv6_cidr_blocks = ["::/0"] | |
} | |
tags = { | |
Name = "${var.name}-sg-alb-${var.environment}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
resource "aws_security_group" "ecs_tasks" { | |
name = "${var.name}-sg-task-${var.environment}" | |
vpc_id = var.vpc_id | |
ingress { | |
protocol = "tcp" | |
from_port = var.container_port | |
to_port = var.container_port | |
cidr_blocks = ["0.0.0.0/0"] | |
ipv6_cidr_blocks = ["::/0"] | |
} | |
egress { | |
protocol = "-1" | |
from_port = 0 | |
to_port = 0 | |
cidr_blocks = ["0.0.0.0/0"] | |
ipv6_cidr_blocks = ["::/0"] | |
} | |
tags = { | |
Name = "${var.name}-sg-task-${var.environment}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
resource "aws_subnet" "private" { | |
vpc_id = aws_vpc.main.id | |
cidr_block = element(var.private_subnets, count.index) | |
availability_zone = element(var.availability_zones, count.index) | |
count = length(var.private_subnets) | |
tags = { | |
Name = "${var.name}-private-subnet-${var.environment}-${format("%03d", count.index+1)}" | |
Environment = var.environment | |
} | |
} | |
resource "aws_subnet" "public" { | |
vpc_id = aws_vpc.main.id | |
cidr_block = element(var.public_subnets, count.index) | |
availability_zone = element(var.availability_zones, count.index) | |
count = length(var.public_subnets) | |
map_public_ip_on_launch = true | |
tags = { | |
Name = "${var.name}-public-subnet-${var.environment}-${format("%03d", count.index+1)}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
resource "aws_vpc" "main" { | |
cidr_block = var.cidr | |
enable_dns_support = true | |
enable_dns_hostnames = true | |
tags = { | |
Name = "${var.name}-vpc-${var.environment}" | |
Environment = var.environment | |
} | |
} | |
resource "aws_internet_gateway" "main" { | |
vpc_id = aws_vpc.main.id | |
tags = { | |
Name = "${var.name}-igw-${var.environment}" | |
Environment = var.environment | |
} | |
} |
This file contains hidden or 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
provider "aws" { | |
profile = var.aws_profile | |
region = var.aws-region | |
version = "~> 2.0" | |
} |
This file contains hidden or 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
{ | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Principal": { | |
"AWS": "arn:aws:iam::<AccountID>:user/my-terraform-user" | |
}, | |
"Action": "s3:*", | |
"Resource": "arn:aws:s3:::my-terraform-backend-store" | |
} | |
] | |
} |
This file contains hidden or 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
# copy this file to secrets.tfvars and add your own secrets | |
# never commit the actual secrets.tfvars file | |
aws-access-key = "myAWSAccessKey" | |
aws-secret-key = "myAWSSecret" | |
application-secrets = { | |
"ENV" = "prod" | |
} |
This file contains hidden or 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 = "my-project-name" | |
environment = "test" | |
aws_profile = "default" | |
availability_zones = ["eu-central-1a", "eu-central-1b"] | |
private_subnets = ["10.0.0.0/20", "10.0.32.0/20"] | |
public_subnets = ["10.0.16.0/20", "10.0.48.0/20"] | |
tsl_certificate_arn = "mycertificatearn" | |
container_memory = 512 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment