Module 12, AWS Compute with Terraform
Elastic Beanstalk
resource "aws_elastic_beanstalk_application" "app" {
name = var.app_name
description = "FinPay application"
}
resource "aws_elastic_beanstalk_environment" "production" {
name = "${var.app_name}-production"
application = aws_elastic_beanstalk_application.app.name
solution_stack_name = "64bit Amazon Linux 2023 v4.3.0 running Docker"
setting {
namespace = "aws:autoscaling:asg"
name = "MinSize"
value = "2"
}
setting {
namespace = "aws:autoscaling:asg"
name = "MaxSize"
value = "4"
}
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "LoadBalancerType"
value = "application"
}
setting {
namespace = "aws:elasticbeanstalk:healthreporting:system"
name = "SystemType"
value = "enhanced"
}
}
Deployment Policies (Exam Critical)
| Policy | Downtime | Speed | Rollback |
|---|---|---|---|
| All at once | Yes | Fastest | Re-deploy old version |
| Rolling | No | Medium | Re-deploy old version |
| Rolling with additional batch | No | Slowest | Re-deploy old version |
| Immutable | No | Slow | Terminate new instances ✅ |
| Blue/Green | No | Slow | Swap CNAME back ✅ |
setting {
namespace = "aws:elasticbeanstalk:command"
name = "DeploymentPolicy"
value = "Immutable" # safest for production
}
ECS Fargate
resource "aws_ecs_cluster" "main" {
name = "${var.app_name}-cluster"
}
resource "aws_ecs_task_definition" "app" {
family = var.app_name
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 256
memory = 512
execution_role_arn = aws_iam_role.ecs_execution.arn
container_definitions = jsonencode([{
name = var.app_name
image = "${aws_ecr_repository.app.repository_url}:latest"
portMappings = [{ containerPort = 3000; protocol = "tcp" }]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = "/ecs/${var.app_name}"
"awslogs-region" = var.aws_region
"awslogs-stream-prefix" = "ecs"
}
}
}])
}
resource "aws_ecs_service" "app" {
name = var.app_name
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.private_app[*].id
security_groups = [aws_security_group.ecs.id]
assign_public_ip = false
}
}
Knowledge Check
- What is the difference between Immutable and Rolling deployment policies?
- Which EB deployment policy causes downtime?
- What does
FARGATElaunch type mean vsEC2? - Why would you use ECS over Elastic Beanstalk?
- What is the purpose of
execution_role_arnin an ECS task definition?
Exam Mapping
- AWS DevOps Pro Domain 1: Deployment strategies, heavily tested