From 742ce9f6a193f147d59de0b6a0f6a88a162b9d3b Mon Sep 17 00:00:00 2001 From: Gilgamesh The God of Kings <2153849+Unverified@users.noreply.github.com> Date: Sat, 1 Jun 2024 03:31:24 -0700 Subject: [PATCH] Add routes for VPC + Subnet IPv6 space (#116) * Add routes for VPC + Subnet IPv6 space VPC's can be setup as dual stack which will allow for them to have ipv6 addresses as well as ipv4 ones. This will make it so if vpc's get paried that do have ipv6 addressing on them that the route tables also get setup with the ipv6 addresses. * Add a test for when only 1 side has ipv6 addresses --- docker-compose.yaml | 1 - examples/partial-subnets/main.tf | 50 ++++++------ examples/partial-subnets/variables.tf | 32 ++++---- .../main.tf | 4 +- locals.tf | 48 ++++++----- main.tf | 34 ++++++-- .../main.tf | 81 +++++++++++++++++++ .../outputs.tf | 7 ++ .../provider.tf | 29 +++++++ .../variables.tf | 11 +++ test/fixtures/partial-subnets/data.tf | 12 +-- test/fixtures/partial-subnets/main.tf | 16 ++-- .../main.tf | 73 +++++++++++++++++ .../outputs.tf | 7 ++ .../provider.tf | 13 +++ .../variables.tf | 5 ++ test/peering-active_test.go | 2 + 17 files changed, 341 insertions(+), 84 deletions(-) create mode 100644 test/fixtures/multi-account-single-region-both-dualstack/main.tf create mode 100644 test/fixtures/multi-account-single-region-both-dualstack/outputs.tf create mode 100644 test/fixtures/multi-account-single-region-both-dualstack/provider.tf create mode 100644 test/fixtures/multi-account-single-region-both-dualstack/variables.tf create mode 100644 test/fixtures/single-account-single-region-one-dualstack/main.tf create mode 100644 test/fixtures/single-account-single-region-one-dualstack/outputs.tf create mode 100644 test/fixtures/single-account-single-region-one-dualstack/provider.tf create mode 100644 test/fixtures/single-account-single-region-one-dualstack/variables.tf diff --git a/docker-compose.yaml b/docker-compose.yaml index 57652a4..7747a6e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,4 @@ --- -version: "3.8" services: localstack: container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}" diff --git a/examples/partial-subnets/main.tf b/examples/partial-subnets/main.tf index 154db4f..05c3b25 100644 --- a/examples/partial-subnets/main.tf +++ b/examples/partial-subnets/main.tf @@ -4,17 +4,17 @@ # peer vpc main route table data "aws_route_table" "peer_main_route_table" { - provider = aws.peer + provider = aws.peer vpc_id = var.peer_vpc_id filter { name = "association.main" values = ["true"] - } + } } # peer subnets data "aws_subnets" "peer" { - provider = aws.peer + provider = aws.peer filter { name = "vpc-id" values = [var.peer_vpc_id] @@ -23,7 +23,7 @@ data "aws_subnets" "peer" { # get route tables associated with subnets data "aws_route_tables" "peer_associated_route_tables" { - for_each = { for subnet in data.aws_subnets.peer.ids: subnet => subnet } + for_each = { for subnet in data.aws_subnets.peer.ids : subnet => subnet } provider = aws.peer vpc_id = var.peer_vpc_id filter { @@ -34,37 +34,37 @@ data "aws_route_tables" "peer_associated_route_tables" { locals { peer_subnet_route_table_map = { - for subnet in data.aws_subnets.peer.ids: - subnet => concat( - data.aws_route_tables.peer_associated_route_tables[subnet].ids, - [data.aws_route_table.peer_main_route_table.id] - )[0] + for subnet in data.aws_subnets.peer.ids : + subnet => concat( + data.aws_route_tables.peer_associated_route_tables[subnet].ids, + [data.aws_route_table.peer_main_route_table.id] + )[0] } peer_subnets_associated_map = { - for subnet, route_table in local.peer_subnet_route_table_map: - subnet => route_table - if route_table != data.aws_route_table.peer_main_route_table.id + for subnet, route_table in local.peer_subnet_route_table_map : + subnet => route_table + if route_table != data.aws_route_table.peer_main_route_table.id } peer_subnets_unassociated_map = { - for subnet, route_table in local.peer_subnet_route_table_map: - subnet => route_table - if route_table == data.aws_route_table.peer_main_route_table.id + for subnet, route_table in local.peer_subnet_route_table_map : + subnet => route_table + if route_table == data.aws_route_table.peer_main_route_table.id } peer_subnet_ids = distinct(concat( try(slice(keys(local.peer_subnets_associated_map), 0, 1), []), - try(slice(keys(local.peer_subnets_unassociated_map),0, 1), []), + try(slice(keys(local.peer_subnets_unassociated_map), 0, 1), []), )) # actually, peer route tables should be detected from peer subnets if specified - peer_route_tables = distinct([ for subnet in local.peer_subnet_ids: local.peer_subnet_route_table_map[subnet] ]) + peer_route_tables = distinct([for subnet in local.peer_subnet_ids : local.peer_subnet_route_table_map[subnet]]) } module "partial_subnets" { - - source = "../../" + + source = "../../" #version = "6.0.0" providers = { @@ -77,15 +77,15 @@ module "partial_subnets" { auto_accept_peering = true peer_dns_resolution = true - this_dns_resolution = true - peer_subnets_ids = length(var.peer_subnets_ids) > 0 ? var.peer_subnets_ids : local.peer_subnet_ids - this_subnets_ids = var.this_subnets_ids - this_rts_ids = var.this_rts_ids - peer_rts_ids = length(var.peer_rts_ids)>0 ? var.peer_rts_ids : local.peer_route_tables + this_dns_resolution = true + peer_subnets_ids = length(var.peer_subnets_ids) > 0 ? var.peer_subnets_ids : local.peer_subnet_ids + this_subnets_ids = var.this_subnets_ids + this_rts_ids = var.this_rts_ids + peer_rts_ids = length(var.peer_rts_ids) > 0 ? var.peer_rts_ids : local.peer_route_tables tags = { Name = "tf-partial-subnets" Environment = "Test" } - + } diff --git a/examples/partial-subnets/variables.tf b/examples/partial-subnets/variables.tf index 0520e67..afe8a79 100644 --- a/examples/partial-subnets/variables.tf +++ b/examples/partial-subnets/variables.tf @@ -1,50 +1,50 @@ -variable this_assume_role_arn { - type = string +variable "this_assume_role_arn" { + type = string default = "" } -variable peer_assume_role_arn { - type = string +variable "peer_assume_role_arn" { + type = string default = "" } variable "aws_this_access_key" { description = "AWS Access Key for requester account" - default = "" + default = "" } variable "aws_this_secret_key" { description = "AWS Secret Key for requester account" - default = "" + default = "" } variable "aws_peer_access_key" { description = "AWS Access Key for accepter account" - default = "" + default = "" } variable "aws_peer_secret_key" { description = "AWS Secret Key for accepter account" - default = "" + default = "" } -variable this_region { - type = string +variable "this_region" { + type = string default = "eu-central-1" } -variable peer_region { - type = string +variable "peer_region" { + type = string default = "eu-central-1" } -variable this_vpc_id { - type = string +variable "this_vpc_id" { + type = string } -variable peer_vpc_id { - type = string +variable "peer_vpc_id" { + type = string } variable "auto_accept_peering" { diff --git a/examples/single-account-single-region-with-options/main.tf b/examples/single-account-single-region-with-options/main.tf index c02cbfb..0b87c6e 100644 --- a/examples/single-account-single-region-with-options/main.tf +++ b/examples/single-account-single-region-with-options/main.tf @@ -14,10 +14,10 @@ module "single_account_single_region_options" { auto_accept_peering = true // Peering options for requester - this_dns_resolution = true + this_dns_resolution = true // Peering options for accepter - peer_dns_resolution = true + peer_dns_resolution = true tags = { Name = "tf-single-account-single-region-with-options" diff --git a/locals.tf b/locals.tf index 9fa8d06..c3d08ca 100644 --- a/locals.tf +++ b/locals.tf @@ -2,9 +2,9 @@ locals { this_region = data.aws_region.this.name peer_region = data.aws_region.peer.name - same_region = data.aws_region.this.name == data.aws_region.peer.name - same_account = data.aws_caller_identity.this.account_id == data.aws_caller_identity.peer.account_id - same_acount_and_region = local.same_region && local.same_account + same_region = data.aws_region.this.name == data.aws_region.peer.name + same_account = data.aws_caller_identity.this.account_id == data.aws_caller_identity.peer.account_id + same_account_and_region = local.same_region && local.same_account # Rout table should either be the one for the vpc, or the ones associated to the subnets if subnets are given this_subnet_route_table_map = { @@ -34,36 +34,49 @@ locals { # `this_dest_cidrs` represent CIDR of peer VPC, therefore a destination CIDR for this_vpc # `peer_dest_cidrs` represent CIDR of this VPC, therefore a destination CIDR for peer_vpc # Destination cidrs for this are in peer and vice versa - this_dest_cidrs = length(var.peer_subnets_ids) == 0 ? toset([data.aws_vpc.peer_vpc.cidr_block]) : toset(data.aws_subnet.peer[*].cidr_block) - peer_dest_cidrs = length(var.this_subnets_ids) == 0 ? toset([data.aws_vpc.this_vpc.cidr_block]) : toset(data.aws_subnet.this[*].cidr_block) + this_dest_ipv4_cidrs = toset(compact(length(var.peer_subnets_ids) == 0 ? [data.aws_vpc.peer_vpc.cidr_block] : data.aws_subnet.peer[*].cidr_block)) + this_dest_ipv6_cidrs = toset(compact(length(var.peer_subnets_ids) == 0 ? [data.aws_vpc.peer_vpc.ipv6_cidr_block] : data.aws_subnet.peer[*].ipv6_cidr_block)) + peer_dest_ipv4_cidrs = toset(compact(length(var.this_subnets_ids) == 0 ? [data.aws_vpc.this_vpc.cidr_block] : data.aws_subnet.this[*].cidr_block)) + peer_dest_ipv6_cidrs = toset(compact(length(var.this_subnets_ids) == 0 ? [data.aws_vpc.this_vpc.ipv6_cidr_block] : data.aws_subnet.this[*].ipv6_cidr_block)) # Get associated CIDR blocks - this_associated_dest_cidrs = toset(tolist([for k, v in data.aws_vpc.peer_vpc.cidr_block_associations : v.cidr_block])) - peer_associated_dest_cidrs = toset(tolist([for k, v in data.aws_vpc.this_vpc.cidr_block_associations : v.cidr_block])) + this_associated_dest_cidrs = toset(compact([for k, v in data.aws_vpc.peer_vpc.cidr_block_associations : v.cidr_block])) + peer_associated_dest_cidrs = toset(compact([for k, v in data.aws_vpc.this_vpc.cidr_block_associations : v.cidr_block])) # Allow specifying route tables explicitly this_rts_ids_hack = length(var.this_rts_ids) == 0 ? local.this_rts_ids : var.this_rts_ids peer_rts_ids_hack = length(var.peer_rts_ids) == 0 ? local.peer_rts_ids : var.peer_rts_ids # In each route table there should be 1 route for each subnet, so combining the two sets - this_routes = [ - for pair in setproduct(local.this_rts_ids_hack, local.this_dest_cidrs) : { - rts_id = pair[0] - dest_cidr = pair[1] + this_ipv4_routes = [ + for pair in setproduct(local.this_rts_ids_hack, local.this_dest_ipv4_cidrs) : { + rts_id = pair[0] + dest_ipv4_cidr = pair[1] } ] - # In each route table there should be 1 route for each subnet, so combining the two sets - peer_routes = [ - for pair in setproduct(local.peer_rts_ids_hack, local.peer_dest_cidrs) : { - rts_id = pair[0] - dest_cidr = pair[1] + this_ipv6_routes = [ + for pair in setproduct(local.this_rts_ids_hack, local.this_dest_ipv6_cidrs) : { + rts_id = pair[0] + dest_ipv6_cidr = pair[1] } ] + peer_ipv4_routes = [ + for pair in setproduct(local.peer_rts_ids_hack, local.peer_dest_ipv4_cidrs) : { + rts_id = pair[0] + dest_ipv4_cidr = pair[1] + } + ] + peer_ipv6_routes = [ + for pair in setproduct(local.peer_rts_ids_hack, local.peer_dest_ipv6_cidrs) : { + rts_id = pair[0] + dest_ipv6_cidr = pair[1] + } + ] - # Routes for associated subnets + # Routes for additional associated CIDRs this_associated_routes = [ for pair in setproduct(local.this_rts_ids_hack, local.this_associated_dest_cidrs) : { rts_id = pair[0] @@ -71,7 +84,6 @@ locals { } ] - # In each route table there should be 1 route for each subnet, so combining the two sets peer_associated_routes = [ for pair in setproduct(local.peer_rts_ids_hack, local.peer_associated_dest_cidrs) : { rts_id = pair[0] diff --git a/main.tf b/main.tf index 46f1a2e..ba931ea 100644 --- a/main.tf +++ b/main.tf @@ -7,7 +7,7 @@ resource "aws_vpc_peering_connection" "this" { peer_vpc_id = var.peer_vpc_id vpc_id = var.this_vpc_id peer_region = data.aws_region.peer.name - tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_acount_and_region ? "Both" : "Requester" })) + tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_account_and_region ? "Both" : "Requester" })) # hardcoded timeouts { create = "15m" @@ -22,7 +22,7 @@ resource "aws_vpc_peering_connection_accepter" "peer_accepter" { provider = aws.peer vpc_peering_connection_id = aws_vpc_peering_connection.this.id auto_accept = var.auto_accept_peering - tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_acount_and_region ? "Both" : "Accepter" })) + tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_account_and_region ? "Both" : "Accepter" })) } ####################### @@ -52,12 +52,21 @@ resource "aws_vpc_peering_connection_options" "accepter" { resource "aws_route" "this_routes" { provider = aws.this # Only create routes for this route table if input dictates it, and in that case, for all combinations - count = local.create_routes_this ? length(local.this_routes) : 0 - route_table_id = local.this_routes[count.index].rts_id - destination_cidr_block = local.this_routes[count.index].dest_cidr + count = local.create_routes_this ? length(local.this_ipv4_routes) : 0 + route_table_id = local.this_ipv4_routes[count.index].rts_id + destination_cidr_block = local.this_ipv4_routes[count.index].dest_ipv4_cidr vpc_peering_connection_id = aws_vpc_peering_connection.this.id } +resource "aws_route" "this_ipv6_routes" { + provider = aws.this + # Only create routes for this route table if input dictates it, and in that case, for all combinations + count = local.create_routes_this ? length(local.this_ipv6_routes) : 0 + route_table_id = local.this_ipv6_routes[count.index].rts_id + destination_ipv6_cidr_block = local.this_ipv6_routes[count.index].dest_ipv6_cidr + vpc_peering_connection_id = aws_vpc_peering_connection.this.id +} + ################### # This VPC Associated Routes # Routes from THIS route table to associated PEER CIDR ################### @@ -76,12 +85,21 @@ resource "aws_route" "this_associated_routes" { resource "aws_route" "peer_routes" { provider = aws.peer # Only create routes for peer route table if input dictates it, and in that case, for all combinations - count = local.create_routes_peer ? length(local.peer_routes) : 0 - route_table_id = local.peer_routes[count.index].rts_id - destination_cidr_block = local.peer_routes[count.index].dest_cidr + count = local.create_routes_peer ? length(local.peer_ipv4_routes) : 0 + route_table_id = local.peer_ipv4_routes[count.index].rts_id + destination_cidr_block = local.peer_ipv4_routes[count.index].dest_ipv4_cidr vpc_peering_connection_id = aws_vpc_peering_connection.this.id } +resource "aws_route" "peer_ipv6_routes" { + provider = aws.peer + # Only create routes for peer route table if input dictates it, and in that case, for all combinations + count = local.create_routes_peer ? length(local.peer_ipv6_routes) : 0 + route_table_id = local.peer_ipv6_routes[count.index].rts_id + destination_ipv6_cidr_block = local.peer_ipv6_routes[count.index].dest_ipv6_cidr + vpc_peering_connection_id = aws_vpc_peering_connection.this.id +} + ################### # Peer VPC Associated Routes # Routes from PEER route table to THIS CIDR ################### diff --git a/test/fixtures/multi-account-single-region-both-dualstack/main.tf b/test/fixtures/multi-account-single-region-both-dualstack/main.tf new file mode 100644 index 0000000..4e7b764 --- /dev/null +++ b/test/fixtures/multi-account-single-region-both-dualstack/main.tf @@ -0,0 +1,81 @@ +// Fixtures +// VPC +resource "aws_vpc" "this" { + provider = aws.this + cidr_block = "172.20.0.0/16" + assign_generated_ipv6_cidr_block = true + + tags = { + Name = "this_vpc" + Environment = "Test" + } +} + +resource "aws_vpc" "peer" { + provider = aws.peer + cidr_block = "172.21.0.0/16" + assign_generated_ipv6_cidr_block = true + + tags = { + Name = "peer_vpc" + Environment = "Test" + } +} + +// Route Tables +resource "aws_route_table" "this" { + provider = aws.this + count = length(var.azs_this) + + vpc_id = aws_vpc.this.id + + tags = { + Name = "This VPC RT" + Environment = "Test" + } +} + +resource "aws_route_table" "peer" { + provider = aws.peer + count = length(var.azs_peer) + + vpc_id = aws_vpc.peer.id + + tags = { + Name = "Peer VPC RT" + Environment = "Test" + } +} + +// Subnets +resource "aws_subnet" "this" { + provider = aws.peer + for_each = toset(var.azs_this) + + vpc_id = aws_vpc.this.id + cidr_block = cidrsubnet(aws_vpc.this.cidr_block, 5, index(var.azs_this, each.value)) + // IPV6 Subnet cidr needs to align to /64, aws provides a /56 CIDR automatically + ipv6_cidr_block = cidrsubnet(aws_vpc.this.ipv6_cidr_block, 8, index(var.azs_this, each.value)) + availability_zone = each.value + + tags = { + Name = "This VPC Subnet" + Environment = "Test" + } +} + +resource "aws_subnet" "peer" { + provider = aws.peer + for_each = toset(var.azs_peer) + + vpc_id = aws_vpc.peer.id + cidr_block = cidrsubnet(aws_vpc.peer.cidr_block, 5, index(var.azs_peer, each.value)) + // IPV6 Subnet cidr needs to align to /64, aws provides a /56 CIDR automatically + ipv6_cidr_block = cidrsubnet(aws_vpc.peer.ipv6_cidr_block, 8, index(var.azs_peer, each.value)) + availability_zone = each.value + + tags = { + Name = "This VPC Subnet" + Environment = "Test" + } +} diff --git a/test/fixtures/multi-account-single-region-both-dualstack/outputs.tf b/test/fixtures/multi-account-single-region-both-dualstack/outputs.tf new file mode 100644 index 0000000..9e20e58 --- /dev/null +++ b/test/fixtures/multi-account-single-region-both-dualstack/outputs.tf @@ -0,0 +1,7 @@ +output "this_vpc_id" { + value = aws_vpc.this.id +} + +output "peer_vpc_id" { + value = aws_vpc.peer.id +} diff --git a/test/fixtures/multi-account-single-region-both-dualstack/provider.tf b/test/fixtures/multi-account-single-region-both-dualstack/provider.tf new file mode 100644 index 0000000..8bcd58f --- /dev/null +++ b/test/fixtures/multi-account-single-region-both-dualstack/provider.tf @@ -0,0 +1,29 @@ +provider "aws" { + alias = "this" + endpoints { + ec2 = "http://localhost:4566" + s3 = "http://localhost:4566" + sts = "http://localhost:4566" + } + region = "ap-southeast-2" + access_key = "null" + secret_key = "null" + skip_credentials_validation = true + skip_metadata_api_check = true + skip_requesting_account_id = true +} + +provider "aws" { + alias = "peer" + endpoints { + ec2 = "http://localhost:4566" + s3 = "http://localhost:4566" + sts = "http://localhost:4566" + } + region = "ap-southeast-2" + access_key = "null" + secret_key = "null" + skip_credentials_validation = true + skip_metadata_api_check = true + skip_requesting_account_id = true +} diff --git a/test/fixtures/multi-account-single-region-both-dualstack/variables.tf b/test/fixtures/multi-account-single-region-both-dualstack/variables.tf new file mode 100644 index 0000000..8824875 --- /dev/null +++ b/test/fixtures/multi-account-single-region-both-dualstack/variables.tf @@ -0,0 +1,11 @@ +variable "azs_this" { + description = "Availability Zones for requester VPC" + type = list(string) + default = ["ap-southeast-2a", "ap-southeast-2b", "ap-southeast-2c"] +} + +variable "azs_peer" { + description = "Availability Zones for accepter VPC" + type = list(string) + default = ["ap-southeast-2a", "ap-southeast-2b", "ap-southeast-2c"] +} diff --git a/test/fixtures/partial-subnets/data.tf b/test/fixtures/partial-subnets/data.tf index e62b1cb..3f2846e 100644 --- a/test/fixtures/partial-subnets/data.tf +++ b/test/fixtures/partial-subnets/data.tf @@ -1,17 +1,17 @@ data "aws_route_table" "peer_main_route_table" { - provider = aws.peer - vpc_id = aws_vpc.peer.id + provider = aws.peer + vpc_id = aws_vpc.peer.id filter { name = "association.main" values = ["true"] - } + } } data "aws_route_table" "this_main_route_table" { - provider = aws.this - vpc_id = aws_vpc.this.id + provider = aws.this + vpc_id = aws_vpc.this.id filter { name = "association.main" values = ["true"] - } + } } \ No newline at end of file diff --git a/test/fixtures/partial-subnets/main.tf b/test/fixtures/partial-subnets/main.tf index 509589d..bea0e48 100644 --- a/test/fixtures/partial-subnets/main.tf +++ b/test/fixtures/partial-subnets/main.tf @@ -1,8 +1,8 @@ // Fixtures // VPC resource "aws_vpc" "this" { - provider = aws.this - cidr_block = "172.20.0.0/16" + provider = aws.this + cidr_block = "172.20.0.0/16" enable_dns_hostnames = true tags = { Name = "this_vpc" @@ -11,8 +11,8 @@ resource "aws_vpc" "this" { } resource "aws_vpc" "peer" { - provider = aws.peer - cidr_block = "172.21.0.0/16" + provider = aws.peer + cidr_block = "172.21.0.0/16" enable_dns_hostnames = true tags = { Name = "peer_vpc" @@ -74,8 +74,8 @@ resource "aws_subnet" "this_separate_routes" { } resource "aws_route_table_association" "this" { - provider = aws.this - count = length(var.azs_this) + provider = aws.this + count = length(var.azs_this) subnet_id = aws_subnet.this_separate_routes[count.index].id route_table_id = aws_route_table.this[count.index].id } @@ -107,8 +107,8 @@ resource "aws_subnet" "peer_separate_routes" { } resource "aws_route_table_association" "peer" { - provider = aws.peer - count = length(var.azs_peer) + provider = aws.peer + count = length(var.azs_peer) subnet_id = aws_subnet.peer_separate_routes[count.index].id route_table_id = aws_route_table.peer[count.index].id } \ No newline at end of file diff --git a/test/fixtures/single-account-single-region-one-dualstack/main.tf b/test/fixtures/single-account-single-region-one-dualstack/main.tf new file mode 100644 index 0000000..5bce1f8 --- /dev/null +++ b/test/fixtures/single-account-single-region-one-dualstack/main.tf @@ -0,0 +1,73 @@ +// Fixtures +// VPC +resource "aws_vpc" "this" { + cidr_block = "172.20.0.0/16" + assign_generated_ipv6_cidr_block = true + + tags = { + Name = "this_vpc" + Environment = "Test" + } +} + +resource "aws_vpc" "peer" { + cidr_block = "172.21.0.0/16" + assign_generated_ipv6_cidr_block = false + + tags = { + Name = "peer_vpc" + Environment = "Test" + } +} + +// Route Tables +resource "aws_route_table" "this" { + count = length(var.azs) + + vpc_id = aws_vpc.this.id + + tags = { + Name = "This VPC RT" + Environment = "Test" + } +} + +resource "aws_route_table" "peer" { + count = length(var.azs) + + vpc_id = aws_vpc.peer.id + + tags = { + Name = "Peer VPC RT" + Environment = "Test" + } +} + +// Subnets +resource "aws_subnet" "this" { + for_each = toset(var.azs) + + vpc_id = aws_vpc.this.id + cidr_block = cidrsubnet(aws_vpc.this.cidr_block, 5, index(var.azs, each.value)) + // IPV6 Subnet cidr needs to align to /64, aws provides a /56 CIDR automatically + ipv6_cidr_block = cidrsubnet(aws_vpc.this.ipv6_cidr_block, 8, index(var.azs, each.value)) + availability_zone = each.value + + tags = { + Name = "This VPC Subnet" + Environment = "Test" + } +} + +resource "aws_subnet" "peer" { + for_each = toset(var.azs) + + vpc_id = aws_vpc.peer.id + cidr_block = cidrsubnet(aws_vpc.peer.cidr_block, 5, index(var.azs, each.value)) + availability_zone = each.value + + tags = { + Name = "This VPC Subnet" + Environment = "Test" + } +} diff --git a/test/fixtures/single-account-single-region-one-dualstack/outputs.tf b/test/fixtures/single-account-single-region-one-dualstack/outputs.tf new file mode 100644 index 0000000..9e20e58 --- /dev/null +++ b/test/fixtures/single-account-single-region-one-dualstack/outputs.tf @@ -0,0 +1,7 @@ +output "this_vpc_id" { + value = aws_vpc.this.id +} + +output "peer_vpc_id" { + value = aws_vpc.peer.id +} diff --git a/test/fixtures/single-account-single-region-one-dualstack/provider.tf b/test/fixtures/single-account-single-region-one-dualstack/provider.tf new file mode 100644 index 0000000..4aa3a6c --- /dev/null +++ b/test/fixtures/single-account-single-region-one-dualstack/provider.tf @@ -0,0 +1,13 @@ +provider "aws" { + endpoints { + ec2 = "http://localhost:4566" + s3 = "http://localhost:4566" + sts = "http://localhost:4566" + } + region = "eu-west-1" + access_key = "null" + secret_key = "null" + skip_credentials_validation = true + skip_metadata_api_check = true + skip_requesting_account_id = true +} diff --git a/test/fixtures/single-account-single-region-one-dualstack/variables.tf b/test/fixtures/single-account-single-region-one-dualstack/variables.tf new file mode 100644 index 0000000..f6aedef --- /dev/null +++ b/test/fixtures/single-account-single-region-one-dualstack/variables.tf @@ -0,0 +1,5 @@ +variable "azs" { + description = "Availability Zones" + type = list(string) + default = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] +} diff --git a/test/peering-active_test.go b/test/peering-active_test.go index 4b59777..5477fe4 100644 --- a/test/peering-active_test.go +++ b/test/peering-active_test.go @@ -17,8 +17,10 @@ func TestPeeringActive(t *testing.T) { testCases := []TestCase{ {"SingleAccountSingleRegion", "./fixtures/single-account-single-region", "../examples/single-account-single-region"}, {"SingleAccountSingleRegionWithOptions", "./fixtures/single-account-single-region-with-options", "../examples/single-account-single-region-with-options"}, + {"SingleAccountSingleRegionOneDualstack", "./fixtures/single-account-single-region-one-dualstack", "../examples/single-account-single-region"}, {"SingleAccountMultiRegion", "./fixtures/single-account-multi-region", "../examples/single-account-multi-region"}, {"MultiAccountSingleRegion", "./fixtures/multi-account-single-region", "../examples/multi-account-single-region"}, + {"MultiAccountSingleRegionBothDualstack", "./fixtures/multi-account-single-region-both-dualstack", "../examples/multi-account-single-region"}, {"MultiAccountMultiRegion", "./fixtures/multi-account-multi-region", "../examples/multi-account-multi-region"}, // There is a bug with `depends_on` functionality. //{"ModuleDependsOn", "", "../examples/module-depends-on"},