# 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" } } }