Files
KenF bc71da905f NEW: Initial commit
Terraform modules for AWS Zonal Shift demo
2025-05-17 22:10:34 +08:00

190 lines
4.8 KiB
Terraform

# main.tf
data "aws_availability_zones" "available" {}
locals {
azs = slice(data.aws_availability_zones.available.names, 0, 2)
vpc_cidr = "10.0.0.0/16"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.21.0"
name = "${var.environment}-${var.project}-${var.application}-vpc01"
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 4)]
# private_subnet_names = ["vpc01-private1", "vpc01-private2"]
manage_default_network_acl = false
manage_default_route_table = false
manage_default_security_group = false
enable_dns_hostnames = true
enable_dns_support = true
enable_nat_gateway = true
single_nat_gateway = true
enable_flow_log = false
}
data "aws_ami" "al2023" {
most_recent = true
name_regex = "^al2023-ami-2023.*kernel-6.12-arm64"
owners = ["amazon"]
}
module "ec2" {
source = "terraform-aws-modules/ec2-instance/aws"
count = length(local.azs)
name = "${var.environment}-${var.project}-${var.application}-web${count.index + 1}"
instance_type = "t4g.nano"
ami = data.aws_ami.al2023.id
launch_template = {
id = aws_launch_template.this.id
version = "$Latest"
}
vpc_security_group_ids = [module.sg.id]
subnet_id = module.vpc.private_subnets[count.index]
}
module "sg" {
source = "modules/security_group"
name = "WebServers"
description = "SG of Web servers"
vpc-id = module.vpc.vpc_id
ingress = {
r1 = "tcp,80,80,0.0.0.0/0,Public web access"
}
egress = {
r1 = "-1,-1,-1,0.0.0.0/0,Allow outbound traffic"
}
}
module "Ec2InstanceProfile" {
source = "modules/iam-role-v2"
role-name = "${var.environment}-${var.project}-${var.application}-role"
description = "Ec2 instance role"
create-instance-profile = true
trusted-entity = "ec2.amazonaws.com"
}
resource "aws_iam_role_policy_attachment" "this" {
role = module.Ec2InstanceProfile.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_launch_template" "this" {
name = "${var.environment}-${var.project}-${var.application}-web"
description = "Al2023 spot with nginx"
block_device_mappings {
device_name = "/dev/sda1"
ebs {
volume_size = 10
}
}
credit_specification {
cpu_credits = "standard"
}
ebs_optimized = true
iam_instance_profile {
name = module.Ec2InstanceProfile.profile-name[0]
}
image_id = data.aws_ami.al2023.id
instance_type = "t4g.nano"
instance_initiated_shutdown_behavior = "terminate"
instance_market_options {
market_type = "spot"
}
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 1
instance_metadata_tags = "enabled"
}
vpc_security_group_ids = [module.sg.id]
user_data = filebase64("userdata.sh")
}
resource "aws_eip" "eip" {
count = length(local.azs)
domain = "vpc"
}
module "nlb" {
source = "terraform-aws-modules/alb/aws"
version = "9.16.0"
name = "${var.environment}-${var.project}-${var.application}-nlb01"
load_balancer_type = "network"
vpc_id = module.vpc.vpc_id
create_security_group = false
enable_deletion_protection = false
subnet_mapping = [for i, eip in aws_eip.eip :
{
allocation_id = eip.id
subnet_id = module.vpc.public_subnets[i]
}
]
enable_cross_zone_load_balancing = true
enable_zonal_shift = true
listeners = {
tcp80 = {
port = 80
protocol = "TCP"
forward = {
target_group_key = "tcp80"
}
}
}
target_groups = {
tcp80 = {
name_prefix = "tcp80-"
protocol = "TCP"
port = 80
target_type = "instance"
target_id = module.ec2[0].id
deregistration_delay = 60
preserve_client_ip = true
target_health_state = {
# must be disabled for zonal shift
# https://docs.aws.amazon.com/elasticloadbalancing/latest/network/enable-zonal-shift.html
enable_unhealthy_connection_termination = false
}
health_check = {
enabled = true
healthy_threshold = 2
unhealthy_threshold = 2
interval = 10
protocol = "TCP"
timeout = 3
}
}
}
additional_target_group_attachments = {
tcp80-2 = {
target_group_key = "tcp80"
target_type = "instance"
target_id = module.ec2[1].id
port = "80"
}
}
}