Skip to content

Commit

Permalink
IPv6 + NAT64 Support
Browse files Browse the repository at this point in the history
  • Loading branch information
RaJiska committed Nov 18, 2023
1 parent d013102 commit 94a1d71
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 13 deletions.
5 changes: 5 additions & 0 deletions ec2.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ resource "aws_launch_template" "main" {
subnet_id = var.subnet_id
associate_public_ip_address = true
security_groups = [aws_security_group.main.id]
ipv6_address_count = var.use_nat64 ? 1 : null
}

dynamic "instance_market_options" {
Expand Down Expand Up @@ -83,6 +84,10 @@ resource "aws_launch_template" "main" {
TERRAFORM_EIP_ID = length(var.eip_allocation_ids) != 0 ? var.eip_allocation_ids[0] : ""
TERRAFORM_CWAGENT_ENABLED = var.use_cloudwatch_agent ? "true" : ""
TERRAFORM_CWAGENT_CFG_PARAM_NAME = local.cwagent_param_name != null ? local.cwagent_param_name : ""
TERRAFORM_NAT64_ENABLED = var.use_nat64 ? "true" : ""
TERRAFORM_NAT64_IPV4_ADDR = var.use_nat64 ? var.nat64_configuration.tayga_ipv4_addr : ""
TERRAFORM_NAT64_IPV6_ADDR = var.use_nat64 ? var.nat64_configuration.tayga_ipv6_addr : ""
TERRAFORM_NAT64_DYNAMIC_POOL = var.use_nat64 ? var.nat64_configuration.tayga_dynamic_pool : ""
}))

tags = var.tags
Expand Down
18 changes: 16 additions & 2 deletions examples/full/main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
locals {
name = "fck-nat-example"
vpc_cidr = "10.255.255.0/24"
name = "fck-nat-example"
vpc_cidr = "10.255.255.0/24"
ipv6_support = true
}

data "aws_region" "current" {}
Expand All @@ -14,4 +15,17 @@ module "fck-nat" {
update_route_table = true
route_table_id = aws_route_table.private.id
ha_mode = false
use_nat64 = local.ipv6_support
}

resource "aws_route" "ipv6_route" {
count = local.ipv6_support ? 1 : 0

# Is there only because for some reason I made the parameter `route_table_id` take only one ID instead of an array of
# IDs as multiple subnets might depend on a single NAT instance. This is not fixed yet as it would break
# compatibility. Will be fixed in v2.

route_table_id = aws_route_table.private_ipv6[0].id
destination_ipv6_cidr_block = "64:ff9b::/96"
network_interface_id = module.fck-nat.eni_id
}
40 changes: 39 additions & 1 deletion examples/full/network.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
resource "aws_vpc" "main" {
cidr_block = local.vpc_cidr
cidr_block = local.vpc_cidr
assign_generated_ipv6_cidr_block = local.ipv6_support

tags = {
Name = local.name
Expand All @@ -12,6 +13,7 @@ resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(local.vpc_cidr, 4, 0)
availability_zone = "${data.aws_region.current.name}a"
ipv6_cidr_block = local.ipv6_support ? cidrsubnet(aws_vpc.main.ipv6_cidr_block, 8, 0) : null

tags = {
Name = "${local.name}-public"
Expand Down Expand Up @@ -52,6 +54,7 @@ resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(local.vpc_cidr, 4, 1)
availability_zone = "${data.aws_region.current.name}a"
ipv6_cidr_block = local.ipv6_support ? cidrsubnet(aws_vpc.main.ipv6_cidr_block, 8, 1) : null

tags = {
Name = "${local.name}-private"
Expand All @@ -70,3 +73,38 @@ resource "aws_route_table_association" "private" {
subnet_id = aws_subnet.private.id
route_table_id = aws_route_table.private.id
}

### Private IPv6

resource "aws_subnet" "private_ipv6" {
count = local.ipv6_support ? 1 : 0

vpc_id = aws_vpc.main.id
ipv6_cidr_block = cidrsubnet(aws_vpc.main.ipv6_cidr_block, 8, 2)
availability_zone = "${data.aws_region.current.name}a"
enable_dns64 = true
ipv6_native = true
assign_ipv6_address_on_creation = true
enable_resource_name_dns_aaaa_record_on_launch = true

tags = {
Name = "${local.name}-private-ipv6"
}
}

resource "aws_route_table" "private_ipv6" {
count = local.ipv6_support ? 1 : 0

vpc_id = aws_vpc.main.id

tags = {
Name = "${local.name}-private-ipv6"
}
}

resource "aws_route_table_association" "private_ipv6" {
count = local.ipv6_support ? 1 : 0

subnet_id = aws_subnet.private_ipv6[0].id
route_table_id = aws_route_table.private_ipv6[0].id
}
28 changes: 19 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ resource "aws_security_group" "main" {
vpc_id = data.aws_vpc.main.id

ingress {
description = "Unrestricted ingress from within VPC"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["${data.aws_vpc.main.cidr_block}"]
description = "Unrestricted ingress from within VPC"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["${data.aws_vpc.main.cidr_block}"]
ipv6_cidr_blocks = var.use_nat64 ? ["${data.aws_vpc.main.ipv6_cidr_block}"] : null
}

egress {
Expand All @@ -40,10 +41,11 @@ resource "aws_security_group" "main" {
}

resource "aws_network_interface" "main" {
description = "${var.name} static private ENI"
subnet_id = var.subnet_id
security_groups = [aws_security_group.main.id]
source_dest_check = false
description = "${var.name} static private ENI"
subnet_id = var.subnet_id
security_groups = [aws_security_group.main.id]
source_dest_check = false
ipv6_address_count = var.use_nat64 ? 1 : null

tags = merge(var.tags, {
Name = var.name
Expand All @@ -58,6 +60,14 @@ resource "aws_route" "main" {
network_interface_id = aws_network_interface.main.id
}

resource "aws_route" "main_ipv6" {
count = var.update_route_table && var.use_nat64 ? 1 : 0

route_table_id = var.route_table_id
destination_ipv6_cidr_block = "64:ff9b::/96"
network_interface_id = aws_network_interface.main.id
}

resource "aws_ssm_parameter" "cloudwatch_agent_config" {
count = var.use_cloudwatch_agent && var.cloudwatch_agent_configuration_param_arn == null ? 1 : 0

Expand Down
5 changes: 4 additions & 1 deletion templates/user_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
echo "eni_id=${TERRAFORM_ENI_ID}" >> /etc/fck-nat.conf
echo "eip_id=${TERRAFORM_EIP_ID}" >> /etc/fck-nat.conf
echo "cwagent_enabled=${TERRAFORM_CWAGENT_ENABLED}" >> /etc/fck-nat.conf
echo "cwagent_cfg_param_name=${TERRAFORM_CWAGENT_CFG_PARAM_NAME}" >> /etc/fck-nat.conf
echo "nat64_enabled=${TERRAFORM_NAT64_ENABLED}" >> /etc/fck-nat.conf
echo "nat64_ipv4_addr=${TERRAFORM_NAT64_IPV4_ADDR}" >> /etc/fck-nat.conf
echo "nat64_ipv6_addr=${TERRAFORM_NAT64_IPV6_ADDR}" >> /etc/fck-nat.conf
echo "nat64_ipv4_dynamic_pool=${TERRAFORM_NAT64_DYNAMIC_POOL}" >> /etc/fck-nat.conf

service fck-nat restart
22 changes: 22 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,28 @@ variable "cloudwatch_agent_configuration_param_arn" {
default = null
}

variable "use_nat64" {
description = "Whether or not to enable NAT64 on the NAT instance. Your VPC and at least the public subnet this NAT instance is deployed into must support IPv6"
type = bool
default = false
}

variable "nat64_configuration" {
description = "NAT64 configuration for the NAT instance through TAYGA"
type = object({
tayga_ipv4_addr = optional(string, "192.168.255.1"),
tayga_ipv6_addr = optional(string, "2001:db8:1::2"),
tayga_dynamic_pool = optional(string, "192.168.0.0/16"),
})
default = {
default = {
tayga_ipv4_addr = "192.168.255.1",
tayga_ipv6_addr = "2001:db8:1::2",
tayga_dynamic_pool = "192.168.0.0/16"
}
}
}

variable "tags" {
description = "Tags to apply to resources created within the module"
type = map(string)
Expand Down

0 comments on commit 94a1d71

Please sign in to comment.