Skip to content

Commit

Permalink
Add default routes over TGW (#12)
Browse files Browse the repository at this point in the history
* Fix type for variables

* Separate filters for attachment and private subnets

* Fix docs

* Fix example

* Add routes only to private subnets by default

* Add parameter to control routes for private subnets

* Use 0.0.0.0/0 for private subnets if flag is set

* Update description for parameter

* Adjust example

* Fix docs

* Add separate test case for default route

* Refactor variables

* Rename testcase

* Fix docs

* Add more test cases

* Fix condition in data section
  • Loading branch information
snovikov committed Sep 18, 2020
1 parent 05e67de commit 5059d20
Show file tree
Hide file tree
Showing 26 changed files with 787 additions and 26 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ Check the `subnet_name_keyword_selector` variable if you want to change this.
| aws\_account\_id\_hub | AWS account number containing the TGW hub | `string` | n/a | yes |
| aws\_login\_profile | Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles | `any` | n/a | yes |
| role\_to\_assume\_hub | IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB) | `string` | n/a | yes |
| attachment\_subnet\_filters | List of maps selecting the subnet(s) where TGW will be attached | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "*private*"<br> ]<br> }<br>]<br></pre> | no |
| aws\_account\_id\_satellite | AWS account number containing the TGW satellite | `string` | `""` | no |
| hub\_destination\_cidr\_blocks | List of CIDRs to be routed for the hub | `list` | `[]` | no |
| hub\_destination\_cidr\_blocks | List of CIDRs to be routed for the hub | `list(string)` | `[]` | no |
| private\_subnet\_filters | List of maps selecting the subnet(s) which are private | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "*private*"<br> ]<br> }<br>]<br></pre> | no |
| ram\_resource\_association\_id | Identifier of the Resource Access Manager Resource Association | `string` | `""` | no |
| role\_to\_assume\_satellite | IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE) | `string` | `""` | no |
| route\_entire\_satellite\_vpc | Boolean flag for toggling the creation of network routes for all the subnets of the satellite VPC | `bool` | `false` | no |
| route\_private\_subnets\_via\_tgw | Use TGW attachment as a default route (0.0.0.0/0) for private subnets. Value `satellite_destination_cidr_block`s will be ignored. | `bool` | `false` | no |
| satellite\_create | Boolean flag for toggling the handling of satellite resources | `bool` | `false` | no |
| satellite\_destination\_cidr\_blocks | List of CIDRs to be routed for the satellite | `list` | `[]` | no |
| subnet\_filters | List of maps selecting the subnet(s) for which the routing will be added | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "private"<br> ]<br> }<br>]<br></pre> | no |
| satellite\_destination\_cidr\_blocks | List of CIDRs to be routed for the satellite | `list(string)` | `[]` | no |
| transit\_gateway\_default\_route\_table\_association | Set this to false when the hub account also becomes a satellite. Check the official docs for more info. | `bool` | `true` | no |
| transit\_gateway\_default\_route\_table\_propagation | Set this to false when the hub account also becomes a satellite. Check the official docs for more info. | `bool` | `true` | no |
| transit\_gateway\_hub\_name | Name of the Transit Gateway to attach to | `string` | `""` | no |
Expand Down
20 changes: 17 additions & 3 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,21 @@ data "aws_subnet_ids" "this" {
vpc_id = data.aws_vpc.this[0].id

dynamic "filter" {
for_each = var.subnet_filters
for_each = var.attachment_subnet_filters
content {
name = filter.value["name"]
values = filter.value["values"]
}
}
}

data "aws_subnet_ids" "private" {
provider = aws.satellite
count = local.create ? 1 : 0
vpc_id = data.aws_vpc.this[0].id

dynamic "filter" {
for_each = var.private_subnet_filters
content {
name = filter.value["name"]
values = filter.value["values"]
Expand All @@ -25,12 +39,12 @@ data "aws_route_table" "this" {
provider = aws.satellite
count = local.create ? length(data.aws_subnet_ids.this[0].ids) : 0

subnet_id = sort(data.aws_subnet_ids.this[0].ids)[count.index]
subnet_id = sort(data.aws_subnet_ids.private[0].ids)[count.index]
}

data "aws_route_tables" "all" {
provider = aws.satellite
count = local.create && var.route_entire_satellite_vpc ? 1 : 0
count = local.create ? 1 : 0
vpc_id = data.aws_vpc.this[0].id
}

Expand Down
32 changes: 32 additions & 0 deletions examples/satellite-all/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Standalone invocation of the Transit Gateway satellite module

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Providers

No provider.

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:-----:|
| aws\_account\_id\_hub | AWS account number containing the TGW hub | `string` | n/a | yes |
| aws\_account\_id\_satellite | List of AWS account numbers representing the satellites of the TGW | `list(string)` | n/a | yes |
| aws\_login\_profile | Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles | `any` | n/a | yes |
| role\_to\_assume\_hub | IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB) | `string` | n/a | yes |
| role\_to\_assume\_satellite | IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE) | `string` | n/a | yes |
| attachment\_subnet\_filters | List of maps selecting the subnet(s) where TGW will be attached | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "*private*"<br> ]<br> }<br>]<br></pre> | no |
| hub\_destination\_cidr\_blocks | List of CIDRs to be routed for the hub | `list(string)` | `[]` | no |
| private\_subnet\_filters | List of maps selecting the subnet(s) which are private | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "*private*"<br> ]<br> }<br>]<br></pre> | no |
| route\_entire\_satellite\_vpc | Boolean flag for toggling the creation of network routes for all the subnets of the satellite VPC | `bool` | `false` | no |
| route\_private\_subnets\_via\_tgw | Use TGW attachment as a default route (0.0.0.0/0) for private subnets. Value `satellite_destination_cidr_block`s will be ignored. | `bool` | `false` | no |
| satellite\_create | Boolean flag for toggling the handling of satellite resources | `bool` | `false` | no |
| satellite\_destination\_cidr\_blocks | List of CIDRs to be routed for the satellite | `list(string)` | `[]` | no |
| transit\_gateway\_hub\_name | Name of the Transit Gateway to attach to | `string` | `""` | no |
| transit\_gateway\_id | Identifier of the Transit Gateway | `string` | `""` | no |
| vpc\_name\_to\_attach | Name of the satellite VPC to be attached to the TGW | `string` | `""` | no |

## Outputs

No output.

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
6 changes: 6 additions & 0 deletions examples/satellite-all/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Workaround for this error when passing undeclared vars using CI/CD
# https://github.com/hashicorp/terraform/issues/22004
# TODO: refactor it after issue is resolved
locals {
aws_account_id_satellite = var.aws_account_id_satellite[0]
}
34 changes: 34 additions & 0 deletions examples/satellite-all/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# The Transit Gateway (hub) has already been created in AWS, as a fixture for
# this test case due to not being able to use 'depends_on' on Terraform modules
module "tgw-satellite-all" {
source = "../../"

providers = {
aws.satellite = aws.satellite
aws.hub = aws.hub
}

aws_login_profile = var.aws_login_profile
satellite_create = var.satellite_create

aws_account_id_hub = var.aws_account_id_hub
aws_account_id_satellite = local.aws_account_id_satellite

role_to_assume_hub = var.role_to_assume_hub
role_to_assume_satellite = var.role_to_assume_satellite

vpc_name_to_attach = var.vpc_name_to_attach

satellite_destination_cidr_blocks = var.satellite_destination_cidr_blocks
hub_destination_cidr_blocks = var.hub_destination_cidr_blocks

attachment_subnet_filters = var.attachment_subnet_filters

transit_gateway_hub_name = var.transit_gateway_hub_name

route_entire_satellite_vpc = var.route_entire_satellite_vpc

route_private_subnets_via_tgw = var.route_private_subnets_via_tgw

private_subnet_filters = var.private_subnet_filters
}
19 changes: 19 additions & 0 deletions examples/satellite-all/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
provider "aws" {
alias = "satellite"
region = "eu-central-1"
profile = var.aws_login_profile
assume_role {
role_arn = "arn:aws:iam::${local.aws_account_id_satellite}:role/${var.role_to_assume_satellite}"
session_name = "tf-tgw-module-satellite"
}
}

provider "aws" {
alias = "hub"
region = "eu-central-1"
profile = var.aws_login_profile
assume_role {
role_arn = "arn:aws:iam::${var.aws_account_id_hub}:role/${var.role_to_assume_hub}"
session_name = "tf-tgw-module-satellite"
}
}
28 changes: 28 additions & 0 deletions examples/satellite-all/variables.auto.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
satellite_create = true

aws_login_profile = "login"

role_to_assume_hub = "ASSUME-ENG-CI"
role_to_assume_satellite = "ASSUME-ENG-CI"

vpc_name_to_attach = "default"

satellite_destination_cidr_blocks = ["208.67.222.222/32", "208.67.220.220/32"]
hub_destination_cidr_blocks = ["8.8.4.4/32", "8.8.8.8/32"]

attachment_subnet_filters = [
{
name = "tag:Name"
values = ["*private*"]
},
{
name = "availability-zone"
values = ["eu-central-1a", "eu-central-1b"]
}
]

transit_gateway_hub_name = "test-tgw-fixture"

route_entire_satellite_vpc = true

private_subnet_filters = []
99 changes: 99 additions & 0 deletions examples/satellite-all/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
variable "satellite_create" {
description = "Boolean flag for toggling the handling of satellite resources"
default = false
type = bool
}

variable "aws_login_profile" {
description = "Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles"
}

variable "aws_account_id_hub" {
description = "AWS account number containing the TGW hub"
type = string
}

variable "aws_account_id_satellite" {
description = "List of AWS account numbers representing the satellites of the TGW"
type = list(string)
}

variable "role_to_assume_hub" {
description = "IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB)"
type = string
}

variable "role_to_assume_satellite" {
description = "IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE)"
type = string
}

variable "vpc_name_to_attach" {
description = "Name of the satellite VPC to be attached to the TGW"
type = string
default = ""
}

variable "satellite_destination_cidr_blocks" {
description = "List of CIDRs to be routed for the satellite"
type = list(string)
default = []
}

variable "hub_destination_cidr_blocks" {
description = "List of CIDRs to be routed for the hub"
type = list(string)
default = []
}

variable "attachment_subnet_filters" {
description = "List of maps selecting the subnet(s) where TGW will be attached"
type = list(object({
name = string
values = list(string)
}))
default = [
{
name = "tag:Name"
values = ["*private*"]
}
]
}

variable "route_private_subnets_via_tgw" {
description = "Use TGW attachment as a default route (0.0.0.0/0) for private subnets. Value `satellite_destination_cidr_block`s will be ignored."
type = bool
default = false
}

variable "private_subnet_filters" {
description = "List of maps selecting the subnet(s) which are private"
type = list(object({
name = string
values = list(string)
}))
default = [
{
name = "tag:Name"
values = ["*private*"]
}
]
}

variable "transit_gateway_hub_name" {
description = "Name of the Transit Gateway to attach to"
type = string
default = ""
}

variable "transit_gateway_id" {
description = "Identifier of the Transit Gateway"
type = string
default = ""
}

variable "route_entire_satellite_vpc" {
description = "Boolean flag for toggling the creation of network routes for all the subnets of the satellite VPC"
type = bool
default = false
}
32 changes: 32 additions & 0 deletions examples/satellite-default-route-all/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Standalone invocation of the Transit Gateway satellite module

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Providers

No provider.

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:-----:|
| aws\_account\_id\_hub | AWS account number containing the TGW hub | `string` | n/a | yes |
| aws\_account\_id\_satellite | List of AWS account numbers representing the satellites of the TGW | `list(string)` | n/a | yes |
| aws\_login\_profile | Name of the AWS login profile as seen under ~/.aws/config used for assuming cross-account roles | `any` | n/a | yes |
| role\_to\_assume\_hub | IAM role name to assume in the AWS account containing the TGW hub (eg. ASSUME-ROLE-HUB) | `string` | n/a | yes |
| role\_to\_assume\_satellite | IAM role name to assume in the AWS account containing the TGW satellite (eg. ASSUME-ROLE-SATELLITE) | `string` | n/a | yes |
| attachment\_subnet\_filters | List of maps selecting the subnet(s) where TGW will be attached | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "*private*"<br> ]<br> }<br>]<br></pre> | no |
| hub\_destination\_cidr\_blocks | List of CIDRs to be routed for the hub | `list(string)` | `[]` | no |
| private\_subnet\_filters | List of maps selecting the subnet(s) which are private | <pre>list(object({<br> name = string<br> values = list(string)<br> }))<br></pre> | <pre>[<br> {<br> "name": "tag:Name",<br> "values": [<br> "*private*"<br> ]<br> }<br>]<br></pre> | no |
| route\_entire\_satellite\_vpc | Boolean flag for toggling the creation of network routes for all the subnets of the satellite VPC | `bool` | `false` | no |
| route\_private\_subnets\_via\_tgw | Use TGW attachment as a default route (0.0.0.0/0) for private subnets. Value `satellite_destination_cidr_block`s will be ignored. | `bool` | `false` | no |
| satellite\_create | Boolean flag for toggling the handling of satellite resources | `bool` | `false` | no |
| satellite\_destination\_cidr\_blocks | List of CIDRs to be routed for the satellite | `list(string)` | `[]` | no |
| transit\_gateway\_hub\_name | Name of the Transit Gateway to attach to | `string` | `""` | no |
| transit\_gateway\_id | Identifier of the Transit Gateway | `string` | `""` | no |
| vpc\_name\_to\_attach | Name of the satellite VPC to be attached to the TGW | `string` | `""` | no |

## Outputs

No output.

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
6 changes: 6 additions & 0 deletions examples/satellite-default-route-all/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Workaround for this error when passing undeclared vars using CI/CD
# https://github.com/hashicorp/terraform/issues/22004
# TODO: refactor it after issue is resolved
locals {
aws_account_id_satellite = var.aws_account_id_satellite[0]
}
34 changes: 34 additions & 0 deletions examples/satellite-default-route-all/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# The Transit Gateway (hub) has already been created in AWS, as a fixture for
# this test case due to not being able to use 'depends_on' on Terraform modules
module "tgw-satellite-default-route-all" {
source = "../../"

providers = {
aws.satellite = aws.satellite
aws.hub = aws.hub
}

aws_login_profile = var.aws_login_profile
satellite_create = var.satellite_create

aws_account_id_hub = var.aws_account_id_hub
aws_account_id_satellite = local.aws_account_id_satellite

role_to_assume_hub = var.role_to_assume_hub
role_to_assume_satellite = var.role_to_assume_satellite

vpc_name_to_attach = var.vpc_name_to_attach

satellite_destination_cidr_blocks = var.satellite_destination_cidr_blocks
hub_destination_cidr_blocks = var.hub_destination_cidr_blocks

attachment_subnet_filters = var.attachment_subnet_filters

transit_gateway_hub_name = var.transit_gateway_hub_name

route_entire_satellite_vpc = var.route_entire_satellite_vpc

route_private_subnets_via_tgw = var.route_private_subnets_via_tgw

private_subnet_filters = var.private_subnet_filters
}
19 changes: 19 additions & 0 deletions examples/satellite-default-route-all/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
provider "aws" {
alias = "satellite"
region = "eu-central-1"
profile = var.aws_login_profile
assume_role {
role_arn = "arn:aws:iam::${local.aws_account_id_satellite}:role/${var.role_to_assume_satellite}"
session_name = "tf-tgw-module-satellite"
}
}

provider "aws" {
alias = "hub"
region = "eu-central-1"
profile = var.aws_login_profile
assume_role {
role_arn = "arn:aws:iam::${var.aws_account_id_hub}:role/${var.role_to_assume_hub}"
session_name = "tf-tgw-module-satellite"
}
}
Loading

0 comments on commit 5059d20

Please sign in to comment.