Skip to content

Commit 742ce9f

Browse files
authored
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
1 parent 0f63b61 commit 742ce9f

File tree

17 files changed

+341
-84
lines changed

17 files changed

+341
-84
lines changed

docker-compose.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
---
2-
version: "3.8"
32
services:
43
localstack:
54
container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"

examples/partial-subnets/main.tf

+25-25
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44

55
# peer vpc main route table
66
data "aws_route_table" "peer_main_route_table" {
7-
provider = aws.peer
7+
provider = aws.peer
88
vpc_id = var.peer_vpc_id
99
filter {
1010
name = "association.main"
1111
values = ["true"]
12-
}
12+
}
1313
}
1414

1515
# peer subnets
1616
data "aws_subnets" "peer" {
17-
provider = aws.peer
17+
provider = aws.peer
1818
filter {
1919
name = "vpc-id"
2020
values = [var.peer_vpc_id]
@@ -23,7 +23,7 @@ data "aws_subnets" "peer" {
2323

2424
# get route tables associated with subnets
2525
data "aws_route_tables" "peer_associated_route_tables" {
26-
for_each = { for subnet in data.aws_subnets.peer.ids: subnet => subnet }
26+
for_each = { for subnet in data.aws_subnets.peer.ids : subnet => subnet }
2727
provider = aws.peer
2828
vpc_id = var.peer_vpc_id
2929
filter {
@@ -34,37 +34,37 @@ data "aws_route_tables" "peer_associated_route_tables" {
3434

3535
locals {
3636
peer_subnet_route_table_map = {
37-
for subnet in data.aws_subnets.peer.ids:
38-
subnet => concat(
39-
data.aws_route_tables.peer_associated_route_tables[subnet].ids,
40-
[data.aws_route_table.peer_main_route_table.id]
41-
)[0]
37+
for subnet in data.aws_subnets.peer.ids :
38+
subnet => concat(
39+
data.aws_route_tables.peer_associated_route_tables[subnet].ids,
40+
[data.aws_route_table.peer_main_route_table.id]
41+
)[0]
4242
}
4343
peer_subnets_associated_map = {
44-
for subnet, route_table in local.peer_subnet_route_table_map:
45-
subnet => route_table
46-
if route_table != data.aws_route_table.peer_main_route_table.id
44+
for subnet, route_table in local.peer_subnet_route_table_map :
45+
subnet => route_table
46+
if route_table != data.aws_route_table.peer_main_route_table.id
4747
}
4848

4949
peer_subnets_unassociated_map = {
50-
for subnet, route_table in local.peer_subnet_route_table_map:
51-
subnet => route_table
52-
if route_table == data.aws_route_table.peer_main_route_table.id
50+
for subnet, route_table in local.peer_subnet_route_table_map :
51+
subnet => route_table
52+
if route_table == data.aws_route_table.peer_main_route_table.id
5353
}
5454
peer_subnet_ids = distinct(concat(
5555
try(slice(keys(local.peer_subnets_associated_map), 0, 1), []),
56-
try(slice(keys(local.peer_subnets_unassociated_map),0, 1), []),
56+
try(slice(keys(local.peer_subnets_unassociated_map), 0, 1), []),
5757
))
5858
# actually, peer route tables should be detected from peer subnets if specified
59-
peer_route_tables = distinct([ for subnet in local.peer_subnet_ids: local.peer_subnet_route_table_map[subnet] ])
59+
peer_route_tables = distinct([for subnet in local.peer_subnet_ids : local.peer_subnet_route_table_map[subnet]])
6060
}
6161

6262

6363

6464

6565
module "partial_subnets" {
66-
67-
source = "../../"
66+
67+
source = "../../"
6868
#version = "6.0.0"
6969

7070
providers = {
@@ -77,15 +77,15 @@ module "partial_subnets" {
7777

7878
auto_accept_peering = true
7979
peer_dns_resolution = true
80-
this_dns_resolution = true
81-
peer_subnets_ids = length(var.peer_subnets_ids) > 0 ? var.peer_subnets_ids : local.peer_subnet_ids
82-
this_subnets_ids = var.this_subnets_ids
83-
this_rts_ids = var.this_rts_ids
84-
peer_rts_ids = length(var.peer_rts_ids)>0 ? var.peer_rts_ids : local.peer_route_tables
80+
this_dns_resolution = true
81+
peer_subnets_ids = length(var.peer_subnets_ids) > 0 ? var.peer_subnets_ids : local.peer_subnet_ids
82+
this_subnets_ids = var.this_subnets_ids
83+
this_rts_ids = var.this_rts_ids
84+
peer_rts_ids = length(var.peer_rts_ids) > 0 ? var.peer_rts_ids : local.peer_route_tables
8585

8686
tags = {
8787
Name = "tf-partial-subnets"
8888
Environment = "Test"
8989
}
90-
90+
9191
}

examples/partial-subnets/variables.tf

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,50 @@
1-
variable this_assume_role_arn {
2-
type = string
1+
variable "this_assume_role_arn" {
2+
type = string
33
default = ""
44
}
55

6-
variable peer_assume_role_arn {
7-
type = string
6+
variable "peer_assume_role_arn" {
7+
type = string
88
default = ""
99
}
1010

1111
variable "aws_this_access_key" {
1212
description = "AWS Access Key for requester account"
13-
default = ""
13+
default = ""
1414
}
1515

1616
variable "aws_this_secret_key" {
1717
description = "AWS Secret Key for requester account"
18-
default = ""
18+
default = ""
1919
}
2020

2121
variable "aws_peer_access_key" {
2222
description = "AWS Access Key for accepter account"
23-
default = ""
23+
default = ""
2424
}
2525

2626
variable "aws_peer_secret_key" {
2727
description = "AWS Secret Key for accepter account"
28-
default = ""
28+
default = ""
2929
}
3030

3131

32-
variable this_region {
33-
type = string
32+
variable "this_region" {
33+
type = string
3434
default = "eu-central-1"
3535
}
3636

37-
variable peer_region {
38-
type = string
37+
variable "peer_region" {
38+
type = string
3939
default = "eu-central-1"
4040
}
4141

42-
variable this_vpc_id {
43-
type = string
42+
variable "this_vpc_id" {
43+
type = string
4444
}
4545

46-
variable peer_vpc_id {
47-
type = string
46+
variable "peer_vpc_id" {
47+
type = string
4848
}
4949

5050
variable "auto_accept_peering" {

examples/single-account-single-region-with-options/main.tf

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ module "single_account_single_region_options" {
1414
auto_accept_peering = true
1515

1616
// Peering options for requester
17-
this_dns_resolution = true
17+
this_dns_resolution = true
1818

1919
// Peering options for accepter
20-
peer_dns_resolution = true
20+
peer_dns_resolution = true
2121

2222
tags = {
2323
Name = "tf-single-account-single-region-with-options"

locals.tf

+30-18
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ locals {
22
this_region = data.aws_region.this.name
33
peer_region = data.aws_region.peer.name
44

5-
same_region = data.aws_region.this.name == data.aws_region.peer.name
6-
same_account = data.aws_caller_identity.this.account_id == data.aws_caller_identity.peer.account_id
7-
same_acount_and_region = local.same_region && local.same_account
5+
same_region = data.aws_region.this.name == data.aws_region.peer.name
6+
same_account = data.aws_caller_identity.this.account_id == data.aws_caller_identity.peer.account_id
7+
same_account_and_region = local.same_region && local.same_account
88

99
# Rout table should either be the one for the vpc, or the ones associated to the subnets if subnets are given
1010
this_subnet_route_table_map = {
@@ -34,44 +34,56 @@ locals {
3434
# `this_dest_cidrs` represent CIDR of peer VPC, therefore a destination CIDR for this_vpc
3535
# `peer_dest_cidrs` represent CIDR of this VPC, therefore a destination CIDR for peer_vpc
3636
# Destination cidrs for this are in peer and vice versa
37-
this_dest_cidrs = length(var.peer_subnets_ids) == 0 ? toset([data.aws_vpc.peer_vpc.cidr_block]) : toset(data.aws_subnet.peer[*].cidr_block)
38-
peer_dest_cidrs = length(var.this_subnets_ids) == 0 ? toset([data.aws_vpc.this_vpc.cidr_block]) : toset(data.aws_subnet.this[*].cidr_block)
37+
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))
38+
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))
39+
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))
40+
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))
3941

4042
# Get associated CIDR blocks
41-
this_associated_dest_cidrs = toset(tolist([for k, v in data.aws_vpc.peer_vpc.cidr_block_associations : v.cidr_block]))
42-
peer_associated_dest_cidrs = toset(tolist([for k, v in data.aws_vpc.this_vpc.cidr_block_associations : v.cidr_block]))
43+
this_associated_dest_cidrs = toset(compact([for k, v in data.aws_vpc.peer_vpc.cidr_block_associations : v.cidr_block]))
44+
peer_associated_dest_cidrs = toset(compact([for k, v in data.aws_vpc.this_vpc.cidr_block_associations : v.cidr_block]))
4345

4446
# Allow specifying route tables explicitly
4547
this_rts_ids_hack = length(var.this_rts_ids) == 0 ? local.this_rts_ids : var.this_rts_ids
4648
peer_rts_ids_hack = length(var.peer_rts_ids) == 0 ? local.peer_rts_ids : var.peer_rts_ids
4749

4850
# In each route table there should be 1 route for each subnet, so combining the two sets
49-
this_routes = [
50-
for pair in setproduct(local.this_rts_ids_hack, local.this_dest_cidrs) : {
51-
rts_id = pair[0]
52-
dest_cidr = pair[1]
51+
this_ipv4_routes = [
52+
for pair in setproduct(local.this_rts_ids_hack, local.this_dest_ipv4_cidrs) : {
53+
rts_id = pair[0]
54+
dest_ipv4_cidr = pair[1]
5355
}
5456
]
5557

56-
# In each route table there should be 1 route for each subnet, so combining the two sets
57-
peer_routes = [
58-
for pair in setproduct(local.peer_rts_ids_hack, local.peer_dest_cidrs) : {
59-
rts_id = pair[0]
60-
dest_cidr = pair[1]
58+
this_ipv6_routes = [
59+
for pair in setproduct(local.this_rts_ids_hack, local.this_dest_ipv6_cidrs) : {
60+
rts_id = pair[0]
61+
dest_ipv6_cidr = pair[1]
6162
}
6263
]
6364

65+
peer_ipv4_routes = [
66+
for pair in setproduct(local.peer_rts_ids_hack, local.peer_dest_ipv4_cidrs) : {
67+
rts_id = pair[0]
68+
dest_ipv4_cidr = pair[1]
69+
}
70+
]
6471

72+
peer_ipv6_routes = [
73+
for pair in setproduct(local.peer_rts_ids_hack, local.peer_dest_ipv6_cidrs) : {
74+
rts_id = pair[0]
75+
dest_ipv6_cidr = pair[1]
76+
}
77+
]
6578

66-
# Routes for associated subnets
79+
# Routes for additional associated CIDRs
6780
this_associated_routes = [
6881
for pair in setproduct(local.this_rts_ids_hack, local.this_associated_dest_cidrs) : {
6982
rts_id = pair[0]
7083
dest_cidr = pair[1]
7184
}
7285
]
7386

74-
# In each route table there should be 1 route for each subnet, so combining the two sets
7587
peer_associated_routes = [
7688
for pair in setproduct(local.peer_rts_ids_hack, local.peer_associated_dest_cidrs) : {
7789
rts_id = pair[0]

main.tf

+26-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ resource "aws_vpc_peering_connection" "this" {
77
peer_vpc_id = var.peer_vpc_id
88
vpc_id = var.this_vpc_id
99
peer_region = data.aws_region.peer.name
10-
tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_acount_and_region ? "Both" : "Requester" }))
10+
tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_account_and_region ? "Both" : "Requester" }))
1111
# hardcoded
1212
timeouts {
1313
create = "15m"
@@ -22,7 +22,7 @@ resource "aws_vpc_peering_connection_accepter" "peer_accepter" {
2222
provider = aws.peer
2323
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
2424
auto_accept = var.auto_accept_peering
25-
tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_acount_and_region ? "Both" : "Accepter" }))
25+
tags = merge(var.tags, { "Name" = var.name }, tomap({ "Side" = local.same_account_and_region ? "Both" : "Accepter" }))
2626
}
2727

2828
#######################
@@ -52,12 +52,21 @@ resource "aws_vpc_peering_connection_options" "accepter" {
5252
resource "aws_route" "this_routes" {
5353
provider = aws.this
5454
# Only create routes for this route table if input dictates it, and in that case, for all combinations
55-
count = local.create_routes_this ? length(local.this_routes) : 0
56-
route_table_id = local.this_routes[count.index].rts_id
57-
destination_cidr_block = local.this_routes[count.index].dest_cidr
55+
count = local.create_routes_this ? length(local.this_ipv4_routes) : 0
56+
route_table_id = local.this_ipv4_routes[count.index].rts_id
57+
destination_cidr_block = local.this_ipv4_routes[count.index].dest_ipv4_cidr
5858
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
5959
}
6060

61+
resource "aws_route" "this_ipv6_routes" {
62+
provider = aws.this
63+
# Only create routes for this route table if input dictates it, and in that case, for all combinations
64+
count = local.create_routes_this ? length(local.this_ipv6_routes) : 0
65+
route_table_id = local.this_ipv6_routes[count.index].rts_id
66+
destination_ipv6_cidr_block = local.this_ipv6_routes[count.index].dest_ipv6_cidr
67+
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
68+
}
69+
6170
###################
6271
# This VPC Associated Routes # Routes from THIS route table to associated PEER CIDR
6372
###################
@@ -76,12 +85,21 @@ resource "aws_route" "this_associated_routes" {
7685
resource "aws_route" "peer_routes" {
7786
provider = aws.peer
7887
# Only create routes for peer route table if input dictates it, and in that case, for all combinations
79-
count = local.create_routes_peer ? length(local.peer_routes) : 0
80-
route_table_id = local.peer_routes[count.index].rts_id
81-
destination_cidr_block = local.peer_routes[count.index].dest_cidr
88+
count = local.create_routes_peer ? length(local.peer_ipv4_routes) : 0
89+
route_table_id = local.peer_ipv4_routes[count.index].rts_id
90+
destination_cidr_block = local.peer_ipv4_routes[count.index].dest_ipv4_cidr
8291
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
8392
}
8493

94+
resource "aws_route" "peer_ipv6_routes" {
95+
provider = aws.peer
96+
# Only create routes for peer route table if input dictates it, and in that case, for all combinations
97+
count = local.create_routes_peer ? length(local.peer_ipv6_routes) : 0
98+
route_table_id = local.peer_ipv6_routes[count.index].rts_id
99+
destination_ipv6_cidr_block = local.peer_ipv6_routes[count.index].dest_ipv6_cidr
100+
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
101+
}
102+
85103
###################
86104
# Peer VPC Associated Routes # Routes from PEER route table to THIS CIDR
87105
###################

0 commit comments

Comments
 (0)