|
| 1 | +locals { |
| 2 | + private_enabled = local.enabled && var.private_subnets_enabled |
| 3 | + private4_enabled = local.private_enabled && local.ipv4_enabled |
| 4 | + ipv4_enabled = local.enabled && var.ipv4_enabled |
| 5 | + nat_gateway_setting = var.nat_instance_enabled == true ? var.enable_nat_gateway == true : !( |
| 6 | + var.enable_nat_gateway == false # not true or null |
| 7 | + ) |
| 8 | + nat_instance_setting = local.nat_gateway_setting ? false : var.nat_instance_enabled == true # not false or null |
| 9 | + nat_instance_useful = local.private4_enabled |
| 10 | + nat_instance_enabled = local.nat_instance_useful && local.nat_instance_setting |
| 11 | + need_nat_ami_id = local.nat_instance_enabled && length(var.nat_instance_ami_id) == 0 |
| 12 | + nat_instance_ami_id = local.need_nat_ami_id ? data.aws_ami.nat_instance[0].id : try(var.nat_instance_ami_id[0], "") |
| 13 | +} |
| 14 | + |
| 15 | +resource "aws_security_group" "nat_instance" { |
| 16 | + count = local.nat_instance_enabled ? 1 : 0 |
| 17 | + description = "Security Group for NAT Instance" |
| 18 | + vpc_id = join("", aws_vpc._.*.id) |
| 19 | + tags = merge(var.additional_tags, var.additional_private_subnet_tags, tomap({ "VPC" = join("", aws_vpc._.*.id), |
| 20 | + "Availability Zone" = length(var.azs_list_names) > 0 ? element(var.azs_list_names, count.index) : element(data.aws_availability_zones.azs.names, count.index), |
| 21 | + "Name" = join(local.delimiter, [local.name, local.az_map_list_short[local.availability_zones[count.index]]]) } |
| 22 | + )) |
| 23 | +} |
| 24 | + |
| 25 | +resource "aws_security_group_rule" "nat_instance_egress" { |
| 26 | + count = local.nat_instance_enabled ? 1 : 0 |
| 27 | + |
| 28 | + description = "Allow all egress traffic" |
| 29 | + from_port = 0 |
| 30 | + to_port = 0 |
| 31 | + protocol = "-1" |
| 32 | + cidr_blocks = ["0.0.0.0/0"] |
| 33 | + security_group_id = join("", aws_security_group.nat_instance.*.id) |
| 34 | + type = "egress" |
| 35 | +} |
| 36 | + |
| 37 | +resource "aws_security_group_rule" "nat_instance_ingress" { |
| 38 | + count = local.nat_instance_enabled ? 1 : 0 |
| 39 | + |
| 40 | + description = "Allow ingress traffic from the VPC CIDR block" |
| 41 | + from_port = 0 |
| 42 | + to_port = 0 |
| 43 | + protocol = "-1" |
| 44 | + cidr_blocks = [var.cidr_block] |
| 45 | + security_group_id = join("", aws_security_group.nat_instance.*.id) |
| 46 | + type = "ingress" |
| 47 | +} |
| 48 | + |
| 49 | +# aws --region us-west-2 ec2 describe-images --owners amazon --filters Name="name",Values="amzn-ami-vpc-nat*" Name="virtualization-type",Values="hvm" |
| 50 | +data "aws_ami" "nat_instance" { |
| 51 | + count = local.need_nat_ami_id ? 1 : 0 |
| 52 | + |
| 53 | + most_recent = true |
| 54 | + |
| 55 | + filter { |
| 56 | + name = "name" |
| 57 | + values = ["amzn-ami-vpc-nat*"] |
| 58 | + } |
| 59 | + |
| 60 | + filter { |
| 61 | + name = "virtualization-type" |
| 62 | + values = ["hvm"] |
| 63 | + } |
| 64 | + |
| 65 | + owners = ["amazon"] |
| 66 | +} |
| 67 | + |
| 68 | +# https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-comparison.html |
| 69 | +# https://docs.aws.amazon.com/vpc/latest/userguide/VPC_NAT_Instance.html |
| 70 | +# https://dzone.com/articles/nat-instance-vs-nat-gateway |
| 71 | +resource "aws_instance" "nat_instance" { |
| 72 | + count = local.nat_instance_enabled ? 1 : 0 |
| 73 | + |
| 74 | + ami = local.nat_instance_ami_id |
| 75 | + instance_type = var.nat_instance_type |
| 76 | + subnet_id = aws_subnet.public[count.index].id |
| 77 | + vpc_security_group_ids = [aws_security_group.nat_instance[0].id] |
| 78 | + |
| 79 | + tags = merge( |
| 80 | + var.additional_tags, |
| 81 | + { |
| 82 | + "Name" = join(local.delimiter, [local.name, count.index]), |
| 83 | + "VPC" = join("", aws_vpc._.*.id) |
| 84 | + } |
| 85 | + ) |
| 86 | + |
| 87 | + # Required by NAT |
| 88 | + # https://docs.aws.amazon.com/vpc/latest/userguide/VPC_NAT_Instance.html#EIP_Disable_SrcDestCheck |
| 89 | + source_dest_check = false |
| 90 | + associate_public_ip_address = true |
| 91 | + |
| 92 | + ebs_optimized = true |
| 93 | +} |
| 94 | + |
| 95 | +resource "aws_eip_association" "nat_instance" { |
| 96 | + count = local.nat_instance_enabled ? 1 : 0 |
| 97 | + |
| 98 | + instance_id = aws_instance.nat_instance[count.index].id |
| 99 | + allocation_id = aws_eip._[count.index].id |
| 100 | +} |
| 101 | + |
| 102 | +# If private IPv4 subnets and NAT Instance are both enabled, create a |
| 103 | +# default route from private subnet to NAT Instance in each subnet |
| 104 | + |
| 105 | +resource "aws_route" "nat_instance" { |
| 106 | + count = local.enabled && var.nat_instance_enabled ? 1 : 0 |
| 107 | + |
| 108 | + route_table_id = element(aws_route_table.private.*.id, count.index) |
| 109 | + network_interface_id = element(aws_instance.nat_instance.*.primary_network_interface_id, count.index) |
| 110 | + destination_cidr_block = "0.0.0.0/0" |
| 111 | + depends_on = [aws_route_table.private] |
| 112 | + |
| 113 | + timeouts { |
| 114 | + create = var.route_create_timeout |
| 115 | + delete = var.route_delete_timeout |
| 116 | + } |
| 117 | +} |
0 commit comments