Skip to content

Commit

Permalink
Create routes for associated VPC CIDRs (#97)
Browse files Browse the repository at this point in the history
* Create routes for associated VPC CIDRs

* Create fixtures for associated CIDRs (#98)

* Create fixtures for associated CIDRs

* Add the test

* Separate normal and associated routes
  • Loading branch information
grem11n authored Jan 16, 2023
1 parent de824da commit 5b8a1c3
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ vendor/
main.go
go.mod
go.sum

# Environment variables
.env
23 changes: 23 additions & 0 deletions examples/associated-cidrs/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Basic Module Example
// Creates a peering between VPCs in the same account in the same region
module "associated_cidrs" {
source = "../../"

providers = {
aws.this = aws
aws.peer = aws
}

this_vpc_id = var.this_vpc_id
peer_vpc_id = var.peer_vpc_id

from_this_associated = true
from_peer_associated = true

auto_accept_peering = true

tags = {
Name = "tf-associated-cirds"
Environment = "Test"
}
}
4 changes: 4 additions & 0 deletions examples/associated-cidrs/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Required for tests
output "vpc_peering_accept_status" {
value = module.associated_cidrs.vpc_peering_accept_status
}
5 changes: 5 additions & 0 deletions examples/associated-cidrs/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
provider "aws" {
region = "eu-west-1"
access_key = var.aws_this_access_key
secret_key = var.aws_this_secret_key
}
13 changes: 13 additions & 0 deletions examples/associated-cidrs/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Variables are required to pass them via Terratest
// on fixtures creation
variable "this_vpc_id" {}

variable "peer_vpc_id" {}

variable "aws_this_access_key" {
description = "AWS Access Key for requester account"
}

variable "aws_this_secret_key" {
description = "AWS Secret Key for requester account"
}
2 changes: 1 addition & 1 deletion examples/module-depends-on/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module "module_depends_on" {
auto_accept_peering = true

tags = {
Name = "tf-single-account-single-region"
Name = "tf-module-depends-on"
Environment = "Test"
}
}
26 changes: 26 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ locals {
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)

# 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]))

# 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
Expand All @@ -38,4 +42,26 @@ locals {
dest_cidr = pair[1]
}
]

# Routes for associated subnets
this_associated_routes = [
for pair in setproduct(local.this_rts_ids_hack, local.this_associated_dest_cidrs) : {
rts_id = pair[0]
dest_cidr = pair[1]
}
]

# 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]
dest_cidr = pair[1]
}
]

create_associated_routes_this = var.from_this && var.from_this_associated
create_associated_routes_peer = var.from_peer && var.from_peer_associated
create_routes_this = var.from_this && !local.create_associated_routes_this
create_routes_peer = var.from_peer && !local.create_associated_routes_peer
}

32 changes: 28 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,49 @@ resource "aws_vpc_peering_connection_options" "accepter" {
}

###################
# This VPC Routes # Route from THIS route table to PEER cidr
# This VPC Routes # Routes from THIS route table to PEER CIDR
###################
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 = var.from_this ? length(local.this_routes) : 0
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
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}

###################
# Peer VPC Routes # Route from PEER route table to THIS cidr
# This VPC Associated Routes # Routes from THIS route table to associated PEER CIDR
###################
resource "aws_route" "this_associated_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_associated_routes_this ? length(local.this_associated_routes) : 0
route_table_id = local.this_associated_routes[count.index].rts_id
destination_cidr_block = local.this_associated_routes[count.index].dest_cidr
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}

###################
# Peer VPC Routes # Routes from PEER route table to THIS CIDR
###################
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 = var.from_peer ? length(local.peer_routes) : 0
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
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}

###################
# Peer VPC Associated Routes # Routes from PEER route table to THIS CIDR
###################
resource "aws_route" "peer_associated_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_associated_routes_peer ? length(local.peer_associated_routes) : 0
route_table_id = local.peer_associated_routes[count.index].rts_id
destination_cidr_block = local.peer_associated_routes[count.index].dest_cidr
vpc_peering_connection_id = aws_vpc_peering_connection.this.id
}
53 changes: 53 additions & 0 deletions test/fixtures/associated-cidr/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module "this_vpc" {
source = "terraform-aws-modules/vpc/aws"

name = "this-vpc"
cidr = "10.0.0.0/16"
secondary_cidr_blocks = ["10.10.0.0/16"]

azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
intra_subnets = [
"10.0.1.0/24",
"10.0.2.0/24",
"10.0.3.0/24",
"10.10.1.0/24",
"10.10.2.0/24",
"10.10.3.0/24",
]

enable_nat_gateway = false
enable_vpn_gateway = false

tags = {
Name = "this-vpc"
Terraform = "true"
Environment = "Test"
}
}

module "peer_vpc" {
source = "terraform-aws-modules/vpc/aws"

name = "peer-vpc"
cidr = "10.1.0.0/16"
secondary_cidr_blocks = ["10.11.0.0/16"]

azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
intra_subnets = [
"10.1.1.0/24",
"10.1.2.0/24",
"10.1.3.0/24",
"10.11.1.0/24",
"10.11.2.0/24",
"10.11.3.0/24",
]

enable_nat_gateway = false
enable_vpn_gateway = false

tags = {
Name = "peer-vpc"
Terraform = "true"
Environment = "Test"
}
}
7 changes: 7 additions & 0 deletions test/fixtures/associated-cidr/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "this_vpc_id" {
value = module.this_vpc.vpc_id
}

output "peer_vpc_id" {
value = module.peer_vpc.vpc_id
}
5 changes: 5 additions & 0 deletions test/fixtures/associated-cidr/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
provider "aws" {
region = "eu-west-1"
access_key = var.aws_this_access_key
secret_key = var.aws_this_secret_key
}
8 changes: 8 additions & 0 deletions test/fixtures/associated-cidr/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Variables
variable "aws_this_access_key" {
description = "AWS Access Key for requester account"
}

variable "aws_this_secret_key" {
description = "AWS Secret Key for requester account"
}
1 change: 1 addition & 0 deletions test/peering-active_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func TestPeeringActive(t *testing.T) {
{"MultiAccountSingleRegion", "./fixtures/multi-account-single-region", "../examples/multi-account-single-region"},
{"MultiAccountMultiRegion", "./fixtures/multi-account-multi-region", "../examples/multi-account-multi-region"},
{"ModuleDependsOn", "", "../examples/module-depends-on"},
{"AssociatedCIDRs", "./fixtures/associated-cidr", "../examples/associated-cidrs"},
}

for _, tc := range testCases {
Expand Down
14 changes: 13 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,24 @@ variable "from_this" {
default = true
}

variable "from_this_associated" {
description = "If traffic for associated CIDRs TO peer VPC (from this) should be allowed"
type = bool
default = false
}

variable "from_peer" {
description = "If traffic FROM peer vpc (to this) should be allowed"
description = "If traffic FROM the peer VPC (to this) should be allowed"
type = bool
default = true
}

variable "from_peer_associated" {
description = "If traffic FROM associated CIDRs of the peer VPC (to this) should be allowed"
type = bool
default = false
}

variable "peer_subnets_ids" {
description = "If communication can only go to some specific subnets of peer vpc. If empty whole vpc cidr is allowed"
type = list(string)
Expand Down

0 comments on commit 5b8a1c3

Please sign in to comment.