-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #76 from lorengordon/tgw
- Loading branch information
Showing
53 changed files
with
1,560 additions
and
1,105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,5 @@ tardigrade-ci/ | |
# eclint | ||
.git/ | ||
|
||
# terratest | ||
tests/go.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
SHELL := /bin/bash | ||
|
||
-include $(shell curl -sSL -o .tardigrade-ci "https://raw.githubusercontent.com/plus3it/tardigrade-ci/master/bootstrap/Makefile.bootstrap"; echo .tardigrade-ci) | ||
export TIMEOUT=50m | ||
|
||
-include $(shell curl -sSL -o .tardigrade-ci "https://raw.githubusercontent.com/plus3it/tardigrade-ci/master/bootstrap/Makefile.bootstrap"; echo .tardigrade-ci) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,75 @@ | ||
# terraform-aws-tardigrade-transit-gateway-attachment | ||
# terraform-aws-tardigrade-transit-gateway | ||
|
||
This module assumes there are 2 accounts involved in the process. The first account is the `owner` of the transit gateway and | ||
has shared it with the second account. This module will attach a VPC that exists in the second account to the shared transit | ||
gateway and then go into the first account and accept the attachment. | ||
This module will manage a Transit Gateway, as well as its Route Tables, Routes, VPC attachments, Route | ||
Table associations and propagations, and VPC routes associated with the VPC attachments. | ||
|
||
## Tests | ||
## Submodules | ||
|
||
Given the necessity of two accounts to test this module, the tests assume one of the AWS profiles used for credentials is | ||
called `owner`. | ||
This module includes several submodules for different workflows and use cases. | ||
|
||
- [`cross-account-vpc-attachment`](modules/cross-account-vpc-attachment): Creates a cross-account Transit | ||
Gateway VPC Attachment by managing the invite/accept interaction between two accounts. Requires two | ||
providers, one for each account. The providers must be different accounts, and must be using the same | ||
region. The Transit Gateway must be shared using the AWS Resource Access Manager. | ||
- [`cross-region-peering-attachment`](modules/cross-region-peering-attachment):: Creates a cross-region | ||
Peering Attachment, managing the invite/accept workflow between the two regions. Requires two providers, | ||
one for each region. The providers may be the same or different account, but **must** be different | ||
regions. | ||
- [`peering-accepter`](modules/peering-accepter): Accepts a peering attachment request. Used by the | ||
cross-region-peering-attachment module. | ||
- [`peering-attachment`](modules/peering-attachment): Sends a peering attachment invite. Used by the | ||
cross-region-peering-attachment module. | ||
- [`route`](modules/route): Creates a Transit Gateway Route. | ||
- [`route-table`](modules/route-table): Creates a Transit Gateway Route Table. | ||
- [`vpc-accepter`](modules/vpc-accepter): Accepts a VPC attachment request. Used by the cross-account-vpc-attachment | ||
module. Will also the create Transit Gateway Route Table association and propagations for the attachment, | ||
and will manage VPC routes associated with the attachment. | ||
- [`vpc-attachment`](modules/vpc-attachment): Sends a VPC attachment invite. Used by the cross-account-vpc-attachment | ||
module. Will also the create Transit Gateway Route Table association and propagations for the attachment, | ||
and will manage VPC routes associated with the attachment. | ||
|
||
<!-- BEGIN TFDOCS --> | ||
## Requirements | ||
|
||
No requirements. | ||
| Name | Version | | ||
|------|---------| | ||
| terraform | >= 0.13.0 | | ||
|
||
## Providers | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| aws | n/a | | ||
| aws.owner | n/a | | ||
| null | n/a | | ||
|
||
## Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| create\_tgw\_attachment | Controls whether to create the TGW attachment | `bool` | `true` | no | | ||
| dependencies | List of resource dependencies to force terraform to wait until they are done | `list(string)` | `[]` | no | | ||
| dns\_support | (Optional) Whether DNS support is enabled. Valid values: disable, enable. | `string` | `"enable"` | no | | ||
| name | The name of the TGW attachment for tagging purposes | `string` | `null` | no | | ||
| owner\_routes | List of AWS route objects to create with the "owner" provider. Each route will be created with a target of the transit gateway. | <pre>list(object({<br> route_table_id = string<br> destination_cidr_block = string<br> destination_ipv6_cidr_block = string<br> }))</pre> | `[]` | no | | ||
| routes | List of AWS route objects to create with the "aws" provider. Each route will be created with a target of the transit gateway. | <pre>list(object({<br> route_table_id = string<br> destination_cidr_block = string<br> destination_ipv6_cidr_block = string<br> }))</pre> | `[]` | no | | ||
| subnet\_ids | A list of subnets inside the VPC | `list` | `[]` | no | | ||
| tags | A map of tags to apply to the TGW attachment | `map` | `{}` | no | | ||
| transit\_gateway\_id | The ID of the Transit Gateway | `string` | `null` | no | | ||
| vpc\_id | VPC ID to attach to the TGW | `string` | `null` | no | | ||
| amazon\_side\_asn | Private Autonomous System Number (ASN) for the Amazon side of a BGP session (range is 64512 to 65534 for 16-bit ASNs and 4200000000 to 4294967294 for 32-bit ASN) | `number` | `64512` | no | | ||
| auto\_accept\_shared\_attachments | Whether resource attachment requests are automatically accepted (valid values: disable, enable) | `string` | `"disable"` | no | | ||
| default\_route\_table\_association | Whether resource attachments are automatically associated with the default association route table (valid values: disable, enable) | `string` | `"enable"` | no | | ||
| default\_route\_table\_propagation | Whether resource attachments automatically propagate routes to the default propagation route table (valid values: disable, enable) | `string` | `"enable"` | no | | ||
| description | Description of the EC2 Transit Gateway | `string` | `null` | no | | ||
| dns\_support | Whether DNS support is enabled (valid values: disable, enable) | `string` | `"enable"` | no | | ||
| route\_tables | List of TGW route tables to create with the transit gateway | <pre>list(object({<br> # `name` used as for_each key<br> name = string<br> tags = map(string)<br> }))</pre> | `[]` | no | | ||
| routes | List of TGW routes to add to TGW route tables | <pre>list(object({<br> # `name` used as for_each key<br> name = string<br> blackhole = bool<br> default_route_table = bool<br> destination_cidr_block = string<br> # name from `vpc_attachments` or id of a pre-existing tgw attachment<br> transit_gateway_attachment = string<br> # name from `route_tables` or id of a pre-existing route table<br> transit_gateway_route_table = string<br> }))</pre> | `[]` | no | | ||
| tags | Map of tags to apply to the TGW and associated resources | `map(string)` | `{}` | no | | ||
| vpc\_attachments | List of VPC attachments to create with the transit gateway | <pre>list(object({<br> # `name` used as for_each key<br> name = string<br> subnet_ids = list(string)<br> dns_support = string<br> ipv6_support = string<br> tags = map(string)<br> vpc_routes = list(object({<br> # `name` is used as for_each key<br> name = string<br> route_table_id = string<br> destination_cidr_block = string<br> destination_ipv6_cidr_block = string<br> }))<br> transit_gateway_default_route_table_association = bool<br> transit_gateway_default_route_table_propagation = bool<br> # name from `route_tables` or id of a pre-existing route table<br> transit_gateway_route_table_association = string<br> # list of route table names from `route_tables` or ids of pre-existing route tables<br> transit_gateway_route_table_propagations = list(string)<br> }))</pre> | `[]` | no | | ||
| vpn\_ecmp\_support | Whether VPN Equal Cost Multipath Protocol support is enabled (valid values: disable, enable) | `string` | `"disable"` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| transit\_gateway\_attachment\_id | The ID of the Transit Gateway Attachment | | ||
| route\_tables | Map of TGW route table objects | | ||
| routes | Map of TGW route objects | | ||
| transit\_gateway | Object with attributes of the Transit Gateway | | ||
| vpc\_attachments | Map of TGW peering attachment objects | | ||
|
||
<!-- END TFDOCS --> | ||
|
||
## Testing | ||
|
||
This module has tests that require multiple providers. In order to simplify the provider config, it | ||
assumes you have AWS Profiles named `resource-owner` and `resource-member`. These profiles should | ||
resolve a credential for two different accounts. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,81 @@ | ||
provider "aws" {} | ||
|
||
provider "aws" { | ||
alias = "owner" | ||
terraform { | ||
required_version = ">= 0.13.0" | ||
} | ||
|
||
resource "aws_ec2_transit_gateway_vpc_attachment" "this" { | ||
count = var.create_tgw_attachment ? 1 : 0 | ||
|
||
provider = aws | ||
|
||
subnet_ids = var.subnet_ids | ||
transit_gateway_id = var.transit_gateway_id | ||
vpc_id = var.vpc_id | ||
dns_support = var.dns_support | ||
tags = merge(var.tags, map("Name", var.name)) | ||
|
||
depends_on = [null_resource.dependencies] | ||
resource aws_ec2_transit_gateway this { | ||
amazon_side_asn = var.amazon_side_asn | ||
auto_accept_shared_attachments = var.auto_accept_shared_attachments | ||
default_route_table_association = var.default_route_table_association | ||
default_route_table_propagation = var.default_route_table_propagation | ||
description = var.description | ||
dns_support = var.dns_support | ||
tags = var.tags | ||
vpn_ecmp_support = var.vpn_ecmp_support | ||
} | ||
|
||
resource "aws_ec2_transit_gateway_vpc_attachment_accepter" "this" { | ||
count = local.create_tgw_accepter ? 1 : 0 | ||
module route_tables { | ||
source = "./modules/route-table" | ||
for_each = { for route_table in var.route_tables : route_table.name => route_table } | ||
|
||
provider = aws.owner | ||
transit_gateway_id = aws_ec2_transit_gateway.this.id | ||
|
||
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.this[0].id | ||
tags = merge(var.tags, map("Name", var.name)) | ||
tags = merge( | ||
{ "Name" : each.key }, | ||
each.value.tags, | ||
) | ||
} | ||
|
||
resource "aws_route" "this" { | ||
count = var.create_tgw_attachment ? length(var.routes) : 0 | ||
|
||
provider = aws | ||
|
||
route_table_id = var.routes[count.index].route_table_id | ||
destination_cidr_block = var.routes[count.index].destination_cidr_block | ||
destination_ipv6_cidr_block = var.routes[count.index].destination_ipv6_cidr_block | ||
transit_gateway_id = local.create_tgw_accepter ? aws_ec2_transit_gateway_vpc_attachment_accepter.this[0].transit_gateway_id : aws_ec2_transit_gateway_vpc_attachment.this[0].transit_gateway_id | ||
module routes { | ||
source = "./modules/route" | ||
for_each = { for route in var.routes : route.name => route } | ||
|
||
blackhole = each.value.blackhole | ||
destination_cidr_block = each.value.destination_cidr_block | ||
|
||
transit_gateway_route_table_id = each.value.default_route_table ? ( | ||
aws_ec2_transit_gateway.this.association_default_route_table_id) : ( | ||
try( | ||
module.route_tables[each.value.transit_gateway_route_table].route_table.id, | ||
each.value.transit_gateway_route_table | ||
) | ||
) | ||
|
||
transit_gateway_attachment_id = try( | ||
module.vpc_attachments[each.value.transit_gateway_attachment].vpc_attachment.id, | ||
each.value.transit_gateway_attachment | ||
) | ||
} | ||
|
||
resource "aws_route" "owner" { | ||
count = var.create_tgw_attachment ? length(var.owner_routes) : 0 | ||
|
||
provider = aws.owner | ||
module vpc_attachments { | ||
source = "./modules/vpc-attachment" | ||
for_each = { for attachment in var.vpc_attachments : attachment.name => attachment } | ||
|
||
route_table_id = var.owner_routes[count.index].route_table_id | ||
destination_cidr_block = var.owner_routes[count.index].destination_cidr_block | ||
destination_ipv6_cidr_block = var.owner_routes[count.index].destination_ipv6_cidr_block | ||
transit_gateway_id = local.create_tgw_accepter ? aws_ec2_transit_gateway_vpc_attachment_accepter.this[0].transit_gateway_id : aws_ec2_transit_gateway_vpc_attachment.this[0].transit_gateway_id | ||
} | ||
subnet_ids = each.value.subnet_ids | ||
transit_gateway_id = aws_ec2_transit_gateway.this.id | ||
dns_support = each.value.dns_support | ||
ipv6_support = each.value.ipv6_support | ||
vpc_routes = each.value.vpc_routes | ||
|
||
resource "null_resource" "dependencies" { | ||
count = var.create_tgw_attachment ? 1 : 0 | ||
transit_gateway_default_route_table_association = each.value.transit_gateway_default_route_table_association | ||
transit_gateway_default_route_table_propagation = each.value.transit_gateway_default_route_table_propagation | ||
|
||
triggers = { | ||
this = join(",", var.dependencies) | ||
transit_gateway_route_table_association = each.value.transit_gateway_route_table_association == null ? null : { | ||
transit_gateway_route_table_id = try( | ||
module.route_tables[each.value.transit_gateway_route_table_association].route_table.id, | ||
each.value.transit_gateway_route_table_association | ||
) | ||
} | ||
} | ||
|
||
data "aws_caller_identity" "this" { | ||
count = var.create_tgw_attachment ? 1 : 0 | ||
} | ||
|
||
data "aws_caller_identity" "owner" { | ||
count = var.create_tgw_attachment ? 1 : 0 | ||
|
||
provider = aws.owner | ||
} | ||
|
||
locals { | ||
create_tgw_accepter = var.create_tgw_attachment ? data.aws_caller_identity.this[0].account_id != data.aws_caller_identity.owner[0].account_id : false | ||
transit_gateway_route_table_propagations = [for route_table in each.value.transit_gateway_route_table_propagations : { | ||
name = route_table | ||
transit_gateway_route_table_id = try( | ||
module.route_tables[route_table].route_table.id, | ||
route_table | ||
) | ||
}] | ||
|
||
tags = merge( | ||
{ "Name" : each.key }, | ||
each.value.tags, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# terraform-aws-tardigrade-transit-gateway/cross-account-vpc-attachment | ||
|
||
Terraform module for managing a cross-account Transit Gateway VPC Attachment. | ||
|
||
<!-- BEGIN TFDOCS --> | ||
## Requirements | ||
|
||
No requirements. | ||
|
||
## Providers | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| aws.owner | n/a | | ||
|
||
## Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| ram\_resource\_association\_id | ID of the RAM resource association for the Transit Gateway | `string` | n/a | yes | | ||
| ram\_share\_id | ID of the RAM Share associated with the Transit Gateway | `string` | n/a | yes | | ||
| subnet\_ids | List of subnets to associate with the VPC attachment | `list(string)` | n/a | yes | | ||
| transit\_gateway\_id | ID of the Transit Gateway | `string` | n/a | yes | | ||
| dns\_support | Whether DNS support is enabled. Valid values: disable, enable. | `string` | `"enable"` | no | | ||
| ipv6\_support | Whether IPv6 support is enabled. Valid values: disable, enable | `string` | `"disable"` | no | | ||
| routes | List of TGW route objects with a target of the VPC attachment in the `aws.owner` account (TGW route tables are *only* in the `aws.owner` account) | <pre>list(object({<br> # `name` is used as for_each key<br> name = string<br> destination_cidr_block = string<br> transit_gateway_route_table_id = string<br> }))</pre> | `[]` | no | | ||
| tags | Map of tags to apply to the TGW attachments | `map(string)` | `{}` | no | | ||
| transit\_gateway\_default\_route\_table\_association | Boolean whether the VPC Attachment should be associated to the Transit Gateway default route table | `bool` | `true` | no | | ||
| transit\_gateway\_default\_route\_table\_propagation | Boolean whether the VPC Attachment should propagate routes to the Transit Gateway propagation default route table | `bool` | `true` | no | | ||
| transit\_gateway\_route\_table\_association | ID of the Transit Gateway route table to associate with the VPC attachment (an attachment can be associated with a single TGW route table) | <pre>object({<br> transit_gateway_route_table_id = string<br> })</pre> | `null` | no | | ||
| transit\_gateway\_route\_table\_propagations | List of Transit Gateway route tables this VPC attachment will propagate routes to | <pre>list(object({<br> # `name` is used as for_each key<br> name = string<br> transit_gateway_route_table_id = string<br> }))</pre> | `[]` | no | | ||
| vpc\_routes | List of VPC route objects with a target of the transit gateway. | <pre>list(object({<br> # `name` is used as for_each key<br> name = string<br> provider = string<br> route_table_id = string<br> destination_cidr_block = string<br> destination_ipv6_cidr_block = string<br> }))</pre> | `[]` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| route\_table\_association | Object with the Transit Gateway route table association attributes | | ||
| route\_table\_propagations | Map of Transit Gateway route table propagation objects | | ||
| routes | Map of Transit Gateway route objects | | ||
| vpc\_accepter | Object with the Transit Gateway VPC attachment accepter attributes | | ||
| vpc\_attachment | Object with the Transit Gateway VPC attachment attributes | | ||
| vpc\_routes | Map of VPC route objects | | ||
|
||
<!-- END TFDOCS --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
provider aws { | ||
alias = "owner" | ||
} | ||
|
||
module vpc_attachment { | ||
source = "../vpc-attachment" | ||
|
||
subnet_ids = var.subnet_ids | ||
transit_gateway_id = var.transit_gateway_id | ||
cross_account = true | ||
dns_support = var.dns_support | ||
ipv6_support = var.ipv6_support | ||
vpc_routes = [for route in var.vpc_routes : route if route.provider == "aws"] | ||
|
||
tags = merge( | ||
{ | ||
ram_share_id = var.ram_share_id | ||
ram_resource_association_id = var.ram_resource_association_id | ||
}, | ||
var.tags, | ||
) | ||
} | ||
|
||
module vpc_accepter { | ||
source = "../vpc-accepter" | ||
providers = { | ||
aws = aws.owner | ||
} | ||
|
||
transit_gateway_attachment_id = module.vpc_attachment.vpc_attachment.id | ||
vpc_routes = [for route in var.vpc_routes : route if route.provider == "aws.owner"] | ||
tags = var.tags | ||
|
||
transit_gateway_route_table_association = var.transit_gateway_route_table_association | ||
transit_gateway_route_table_propagations = var.transit_gateway_route_table_propagations | ||
|
||
# default assocation and propagation values must be: | ||
# `false` if the transit gateway has no default route table (== "disable") | ||
transit_gateway_default_route_table_association = ( | ||
data.aws_ec2_transit_gateway.this.default_route_table_association == "disable") ? false : ( | ||
var.transit_gateway_default_route_table_association | ||
) | ||
|
||
transit_gateway_default_route_table_propagation = ( | ||
data.aws_ec2_transit_gateway.this.default_route_table_propagation == "disable") ? false : ( | ||
var.transit_gateway_default_route_table_propagation | ||
) | ||
} | ||
|
||
module routes { | ||
source = "../route" | ||
for_each = { for route in var.routes : route.name => route } | ||
providers = { | ||
aws = aws.owner | ||
} | ||
|
||
destination_cidr_block = each.value.destination_cidr_block | ||
transit_gateway_attachment_id = module.vpc_accepter.vpc_attachment_accepter.id | ||
transit_gateway_route_table_id = each.value.transit_gateway_route_table_id | ||
} | ||
|
||
data aws_ec2_transit_gateway this { | ||
provider = aws.owner | ||
id = var.transit_gateway_id | ||
} |
Oops, something went wrong.