Skip to content

Commit

Permalink
This is a fix for #108 (#109)
Browse files Browse the repository at this point in the history
* Test fixture for partial-subnets

* Update gitignore

* Fix unable to find route table bug
  • Loading branch information
herrbpl authored Dec 15, 2023
1 parent 764ae14 commit 6da054b
Show file tree
Hide file tree
Showing 13 changed files with 526 additions and 22 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
*.tfstate.backup
**/.terraform.lock.hcl
.terraform/
**/terraform.tfstate
**/terraform.tfstate.backup
**/terraform.tfvars
**/a.out

# go deps
vendor/
Expand Down
78 changes: 61 additions & 17 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ data "aws_vpc" "peer_vpc" {
id = var.peer_vpc_id
}

# Get all route tables from vpcs
data "aws_route_tables" "this_vpc_rts" {
provider = aws.this
vpc_id = var.this_vpc_id
}
data "aws_route_tables" "peer_vpc_rts" {
provider = aws.peer
vpc_id = var.peer_vpc_id
}

# get subnets info
data "aws_subnet" "this" {
count = length(var.this_subnets_ids)
Expand All @@ -44,15 +34,69 @@ data "aws_subnet" "peer" {
id = var.peer_subnets_ids[count.index]
}

# Get info for only those route tables associated with the given subnets
data "aws_route_table" "this_subnet_rts" {
count = length(var.this_subnets_ids)

# Get subnets and route tables from this

# this vpc main route table
data "aws_route_table" "this_main_route_table" {
provider = aws.this
subnet_id = var.this_subnets_ids[count.index]
vpc_id = var.this_vpc_id
filter {
name = "association.main"
values = ["true"]
}
}

# this subnets
data "aws_subnets" "this" {
provider = aws.this
filter {
name = "vpc-id"
values = [var.this_vpc_id]
}
}

# get route tables associated with subnets
data "aws_route_tables" "this_associated_route_tables" {
for_each = { for subnet in data.aws_subnets.this.ids: subnet => subnet }
provider = aws.this
vpc_id = var.this_vpc_id
filter {
name = "association.subnet-id"
values = [each.key]
}
}


# Get subnets and route tables from peer

# peer vpc main route table
data "aws_route_table" "peer_main_route_table" {
provider = aws.peer
vpc_id = var.peer_vpc_id
filter {
name = "association.main"
values = ["true"]
}
}

data "aws_route_table" "peer_subnet_rts" {
count = length(var.peer_subnets_ids)
# peer subnets
data "aws_subnets" "peer" {
provider = aws.peer
subnet_id = var.peer_subnets_ids[count.index]
filter {
name = "vpc-id"
values = [var.peer_vpc_id]
}
}

# 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 }
provider = aws.peer
vpc_id = var.peer_vpc_id
filter {
name = "association.subnet-id"
values = [each.key]
}
}

91 changes: 91 additions & 0 deletions examples/partial-subnets/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
/ To make it unit testable, get required parameters from vpcs.
*/

# peer vpc main route table
data "aws_route_table" "peer_main_route_table" {
provider = aws.peer
vpc_id = var.peer_vpc_id
filter {
name = "association.main"
values = ["true"]
}
}

# peer subnets
data "aws_subnets" "peer" {
provider = aws.peer
filter {
name = "vpc-id"
values = [var.peer_vpc_id]
}
}

# 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 }
provider = aws.peer
vpc_id = var.peer_vpc_id
filter {
name = "association.subnet-id"
values = [each.key]
}
}

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]
}
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
}

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
}
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), []),
))
# 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] ])
}




module "partial_subnets" {

source = "../../"
#version = "6.0.0"

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

this_vpc_id = var.this_vpc_id
peer_vpc_id = var.peer_vpc_id

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

tags = {
Name = "tf-partial-subnets"
Environment = "Test"
}

}
6 changes: 6 additions & 0 deletions examples/partial-subnets/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Required for tests

output "vpc_peering_accept_status" {
value = module.partial_subnets.vpc_peering_accept_status
}

20 changes: 20 additions & 0 deletions examples/partial-subnets/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
provider "aws" {
alias = "this"
region = var.this_region != "" ? var.this_region : "eu-west-2"
assume_role {
role_arn = var.this_assume_role_arn != "" ? var.this_assume_role_arn : null
}
access_key = var.aws_this_access_key != "" ? var.aws_this_access_key : null
secret_key = var.aws_this_secret_key != "" ? var.aws_this_secret_key : null
}

provider "aws" {
alias = "peer"
region = var.peer_region != "" ? var.peer_region : "eu-central-1"
assume_role {
role_arn = var.peer_assume_role_arn != "" ? var.peer_assume_role_arn : null
}
access_key = var.aws_peer_access_key != "" ? var.aws_peer_access_key : null
secret_key = var.aws_peer_secret_key != "" ? var.aws_peer_secret_key : null
}

84 changes: 84 additions & 0 deletions examples/partial-subnets/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
variable this_assume_role_arn {
type = string
default = ""
}

variable peer_assume_role_arn {
type = string
default = ""
}

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

variable "aws_this_secret_key" {
description = "AWS Secret Key for requester account"
default = ""
}

variable "aws_peer_access_key" {
description = "AWS Access Key for accepter account"
default = ""
}

variable "aws_peer_secret_key" {
description = "AWS Secret Key for accepter account"
default = ""
}


variable this_region {
type = string
default = "eu-central-1"
}

variable peer_region {
type = string
default = "eu-central-1"
}

variable this_vpc_id {
type = string
}

variable peer_vpc_id {
type = string
}

variable "auto_accept_peering" {
description = "Auto accept peering connection: bool"
type = bool
default = false
}

variable "tags" {
description = "Tags: map"
type = map(string)
default = {}
}

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)
default = []
}

variable "this_subnets_ids" {
description = "If communication can only go to some specific subnets of this vpc. If empty whole vpc cidr is allowed"
type = list(string)
default = []
}

variable "this_rts_ids" {
description = "Allows to explicitly specify route tables for this VPC"
type = list(string)
default = []
}

variable "peer_rts_ids" {
description = "Allows to explicitly specify route tables for peer VPC"
type = list(string)
default = []
}
29 changes: 24 additions & 5 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,29 @@ locals {
same_acount_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_rts_ids_new = data.aws_route_tables.this_vpc_rts.ids
peer_rts_ids_new = data.aws_route_tables.peer_vpc_rts.ids
this_subnet_route_table_map = {
for subnet in data.aws_subnets.this.ids:
subnet => concat(
data.aws_route_tables.this_associated_route_tables[subnet].ids,
[data.aws_route_table.this_main_route_table.id]
)[0]
}

this_rts_ids = length(var.this_subnets_ids) == 0 ? local.this_rts_ids_new : data.aws_route_table.this_subnet_rts[*].route_table_id
peer_rts_ids = length(var.peer_subnets_ids) == 0 ? local.peer_rts_ids_new : data.aws_route_table.peer_subnet_rts[*].route_table_id
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]
}

this_rts_ids = length(var.this_subnets_ids) == 0 ? distinct(values(local.this_subnet_route_table_map)) : distinct([
for subnet_id in var.this_subnets_ids : local.this_subnet_route_table_map[subnet_id]
])

peer_rts_ids = length(var.peer_subnets_ids) == 0 ? distinct(values(local.peer_subnet_route_table_map)) : distinct([
for subnet_id in var.peer_subnets_ids : local.peer_subnet_route_table_map[subnet_id]
])

# `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
Expand Down Expand Up @@ -43,6 +61,8 @@ locals {
}
]



# Routes for associated subnets
this_associated_routes = [
for pair in setproduct(local.this_rts_ids_hack, local.this_associated_dest_cidrs) : {
Expand All @@ -64,4 +84,3 @@ locals {
create_routes_this = var.from_this && !local.create_associated_routes_this
create_routes_peer = var.from_peer && !local.create_associated_routes_peer
}

17 changes: 17 additions & 0 deletions test/fixtures/partial-subnets/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
data "aws_route_table" "peer_main_route_table" {
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
filter {
name = "association.main"
values = ["true"]
}
}
Loading

0 comments on commit 6da054b

Please sign in to comment.