diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cc0b14..60630aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,4 +101,8 @@ - vpc-interface-endpoint - permit use of aws.* name in service +* 1.6.0 -- 20220226 + - vpn-transit-gateway + - setup vpn configurations for the transit gateway + ## Version 2.x diff --git a/common/defaults.tf b/common/defaults.tf index 6d963af..5b39070 100644 --- a/common/defaults.tf +++ b/common/defaults.tf @@ -46,5 +46,6 @@ locals { "additional" = [] "peers" = [] } + "transit-gateway-environments" = ["services", "dev", "test", "stage", "prod", "cre"] } } diff --git a/common/prefixes.tf b/common/prefixes.tf index d2ee1fe..361746b 100644 --- a/common/prefixes.tf +++ b/common/prefixes.tf @@ -9,20 +9,25 @@ locals { "group" = "g-" "security-group" = "" # "sg-" # VPC - "vpc" = "" - "dhcp-options" = "" - "vpc-peer" = "vpcp-" - "route-table" = "route-" - "subnet" = "" - "vpc-endpoint" = "vpce-" - "elastic-ip" = "eip-" - "nat-gateway" = "nat-" - "internet-gateway" = "igw-" - "network-acl" = "nacl-" - "customer-gateway" = "cgw-" - "vpn-gateway" = "vpcg-" - "vpn-connection" = "vpn_" - "log-group" = "lg-" - "log-stream" = "lgs-" + "vpc" = "" + "dhcp-options" = "" + "vpc-peer" = "vpcp-" + "route-table" = "route-" + "subnet" = "" + "vpc-endpoint" = "vpce-" + "elastic-ip" = "eip-" + "nat-gateway" = "nat-" + "internet-gateway" = "igw-" + "network-acl" = "nacl-" + "customer-gateway" = "cgw-" + "vpn-gateway" = "vpcg-" + "vpn-connection" = "vpn_" + "log-group" = "lg-" + "log-stream" = "lgs-" + "transit-gateway" = "tgw-" + "transit-gateway-peer" = "tgwp-" + "transit-gateway-route-table" = "tgwr-" + "transit-gateway-attachment" = "tgwa-" + "transit-gateway-vpn" = "tgwv-" } } diff --git a/common/version.tf b/common/version.tf index 34b1108..2cc7061 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.5.1" + _module_version = "1.6.0" } diff --git a/examples/dns-vpc-region-vpcN/apps/dns/zones.tf b/examples/dns-vpc-region-vpcN/apps/dns/zones.tf index 5e28b4d..d58dcd4 100644 --- a/examples/dns-vpc-region-vpcN/apps/dns/zones.tf +++ b/examples/dns-vpc-region-vpcN/apps/dns/zones.tf @@ -21,8 +21,10 @@ locals { # need to pull this ando ther forward zones up to vpc/apps/dns #--- data "aws_route53_zone" "domain_zone" { - count = var.dns_zone_create ? 0 : 1 - name = local.domain_name + # provider = aws.east + count = var.dns_zone_create ? 0 : 1 + name = local.domain_name + private_zone = true } resource "aws_route53_zone" "domain_zone" { @@ -50,7 +52,8 @@ resource "aws_route53_zone" "domain_zone" { resource "aws_route53_vpc_association_authorization" "west_domain_zone" { # provider = aws.west_main_dns - for_each = tomap({ "zone" = var.dns_zone_create ? aws_route53_zone.domain_zone[0] : data.aws_route53_zone.domain_zone[0] }) + # for_each = tomap({ "zone" = var.dns_zone_create ? aws_route53_zone.domain_zone[0] : data.aws_route53_zone.domain_zone[0] }) + for_each = var.dns_zone_create ? { "zone" = aws_route53_zone.domain_zone[0] } : {} zone_id = each.value.zone_id vpc_region = "us-gov-west-1" vpc_id = var.main_dns_vpcs["us-gov-west-1"] @@ -58,7 +61,7 @@ resource "aws_route53_vpc_association_authorization" "west_domain_zone" { resource "aws_route53_zone_association" "west_domain_zone" { provider = aws.west_main_dns - for_each = aws_route53_vpc_association_authorization.west_domain_zone + for_each = var.dns_zone_create ? aws_route53_vpc_association_authorization.west_domain_zone : {} zone_id = each.value.zone_id vpc_id = each.value.vpc_id @@ -74,7 +77,8 @@ resource "aws_route53_zone_association" "west_domain_zone" { resource "aws_route53_vpc_association_authorization" "east_domain_zone" { # provider = aws.east_main_dns - for_each = tomap({ "zone" = var.dns_zone_create ? aws_route53_zone.domain_zone[0] : data.aws_route53_zone.domain_zone[0] }) + # for_each = tomap({ "zone" = var.dns_zone_create ? aws_route53_zone.domain_zone[0] : data.aws_route53_zone.domain_zone[0] }) + for_each = var.dns_zone_create ? { "zone" = aws_route53_zone.domain_zone[0] } : {} zone_id = each.value.zone_id vpc_region = "us-gov-east-1" @@ -83,7 +87,7 @@ resource "aws_route53_vpc_association_authorization" "east_domain_zone" { resource "aws_route53_zone_association" "east_domain_zone" { provider = aws.east_main_dns - for_each = aws_route53_vpc_association_authorization.east_domain_zone + for_each = var.dns_zone_create ? aws_route53_vpc_association_authorization.east_domain_zone : {} zone_id = each.value.zone_id vpc_id = each.value.vpc_id vpc_region = each.value.vpc_region diff --git a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/ec2.tf b/examples/ec2-vpc-region-vpcN-new/apps/test-instances/ec2.tf index 9dc3c67..bffa088 100644 --- a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/ec2.tf +++ b/examples/ec2-vpc-region-vpcN-new/apps/test-instances/ec2.tf @@ -18,7 +18,7 @@ resource "aws_instance" "test" { for_each = var.enable_instances ? { for k in local.private_subnets_id_list : k => local.private_subnets_id_map[k] } : {} ami = local.ami - instance_type = local.my_instance_type + instance_type = local.instance_type availability_zone = each.value.availability_zone key_name = local.key_name subnet_id = each.value.id diff --git a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/setup/vpc-test-ec2-keypair.pub b/examples/ec2-vpc-region-vpcN-new/apps/test-instances/setup/vpc-test-ec2-keypair.pub deleted file mode 100644 index e70bd03..0000000 --- a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/setup/vpc-test-ec2-keypair.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6UpFuXzZ8kLvXYo+I1pU1DNAiDc6HP15PoMA/IWcgpadvRi+Og15/WUMlAvRZ9nymOIB/oKpZz2B7wpkhQ1PRuiDUlJ0axy7mtWnRuUIuMkZzlCCrZ26HHMWOjTXMaDV8eKd06RLr+OBlfArlDmNEUNAL237jKTU7eHfiF/DU7y9MN6bHRGMPZRrAbzmUbmlV+sDwhLrH1mXLooMeYWzc0t8ReMb2IQyTEtkrlYUdf5D+o2qwRqp8iZp710qaLols02uvTdeBuVlqY0BPjobYwJciuq8XLs1MmQYdpVHHQTOAOlsc5P0nYicEuAh/VJi4Ix8IPS/aJe/9uOS3DWVkQ== vpc-test-ec2-keypair@SOME-DOMAIN diff --git a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/setup/vpc1-test-ec2-keypair.pub b/examples/ec2-vpc-region-vpcN-new/apps/test-instances/setup/vpc1-test-ec2-keypair.pub deleted file mode 100644 index fcbb78a..0000000 --- a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/setup/vpc1-test-ec2-keypair.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsj2lokVWyrpkzM0ObJs03wv6pGmnxVnKRoDxWWbii23BKBRk4jJNOOgpf3cRfrJ+57KiVKrx1QpwBJa7Rk3rzJxrfsV5N+LgmrPaDTGMAr+DSPTrn7fir6TWrRxZbjteJQA7bLL58OrkdRjJhHiLDVlFsPGx24eVSdF+Ec0VRANpPVNaUtyayvN41m3kDI0rPKDYxN8Da3CILdXHyLYzKeRhRTlnVYF3pv3me81p0v6KneFasp89GQMFuq6z/TIe7T7E+JU0FDhcw5m3wq49m5Vw7/cWtq/wuGcSi5w4g6MBEYJr0RZ1EkSZDMrMgJrYYL78FNBTZXzjYUGtjAhs3Q== vpc1-test-ec2-keypair@tgw-test-domain diff --git a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/test-ips.txt b/examples/ec2-vpc-region-vpcN-new/apps/test-instances/test-ips.txt deleted file mode 100644 index fb29b3d..0000000 --- a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/test-ips.txt +++ /dev/null @@ -1,3 +0,0 @@ -10.128.17.32 -10.128.17.119 -10.128.17.154 diff --git a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/test-ips.txt.tpl b/examples/ec2-vpc-region-vpcN-new/apps/test-instances/test-ips.txt.tpl deleted file mode 100644 index 5ca5edb..0000000 --- a/examples/ec2-vpc-region-vpcN-new/apps/test-instances/test-ips.txt.tpl +++ /dev/null @@ -1,3 +0,0 @@ -%{ for k,v in instances ~} -${v.private_ip} -%{ endfor ~} diff --git a/vpn-transit-gateway/README.md b/vpn-transit-gateway/README.md new file mode 100644 index 0000000..25b1596 --- /dev/null +++ b/vpn-transit-gateway/README.md @@ -0,0 +1,107 @@ +# About aws-vpc-setup :: vpn-transit-gateway + +This sets up a VPN for the specified site (hq or bcc) and all the necessary related components: +* customer gateway per site, environment and sequence +* vpn connection to the transit gateway + +It generates a password for each site and uses the same one for each of the site's two tunnels. + +To download the configuration, follow these directions [page 24 from AWS docs](https://docs.aws.amazon.com/vpn/latest/s2svpn/s2s-vpn-user-guide.pdf): + +> To download the configuration file +> 1. Open the Amazon VPC console at https://console.aws.amazon.com/vpc/. +> 1. In the navigation pane, choose Site-to-Site VPN Connections. +> 1. Select your VPN connection and choose Download Configuration. +> 1. Select the vendor, platform, and software that corresponds to your customer gateway device or +> 1oftware. If your device is not listed, choose Generic. Choose Download. +> * Vendor: Cisco Systems, Inc. +> * Platform: Cisco ASR 1000 +> * Software: IOS 12.4+ + +# Usage + +```hcl +module "vpn_transit-gateway" { + source = "git@github.e.it.census.gov:terraform-modules/aws-vpc-setup.git//vpn-transit-gateway" + create = true + vpc_id = "vpc-1234568" + transit_gateway_id = "tgw-12345678" + tgw_environment = "dev" + vpn_settings = [ + { site = "hq", environment = "dev", sequence = 1, "bgp_asn_id" = 65510, "ip_address" = "148.129.160.100" }, + { site = "bcc", environment = "dev", sequence = 1, "bgp_asn_id" = 65511, "ip_address" = "148.129.90.100" }, + ] + tgw_route_table_association = "tgw-rtb-123123123123" + tgw_route_table_propagation = [ "tgw-rtb-123123123123", "tgw-rtb-234234234234" ] + tags = {} + + # optional + # use_tgw_prefixes = true +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [aws](#requirement\_aws) | >= 3.66.0 | +| [null](#requirement\_null) | >= 3.0 | +| [random](#requirement\_random) | >= 3.0 | +| [template](#requirement\_template) | >= 2.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.66.0 | +| [random](#provider\_random) | >= 3.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_customer_gateway.vpn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/customer_gateway) | resource | +| [aws_ec2_tag.vpn_tag_created_by](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag) | resource | +| [aws_ec2_tag.vpn_tag_environment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag) | resource | +| [aws_ec2_tag.vpn_tag_name](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag) | resource | +| [aws_ec2_transit_gateway_route_table_association.route_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_association) | resource | +| [aws_ec2_transit_gateway_route_table_propagation.propagate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_transit_gateway_route_table_propagation) | resource | +| [aws_vpn_connection.vpn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpn_connection) | resource | +| [random_string.tunnel_preshared_key](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | +| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [account\_alias](#input\_account\_alias) | AWS Account Alias | `string` | `""` | no | +| [account\_id](#input\_account\_id) | AWS Account ID (default will pull from current user) | `string` | `""` | no | +| [create](#input\_create) | Flag to indicate whether to create the resources or not (default: true) | `bool` | `true` | no | +| [override\_prefixes](#input\_override\_prefixes) | Override built-in prefixes by component. This should be used primarily for common infrastructure things | `map(string)` | `{}` | no | +| [route\_table\_ids](#input\_route\_table\_ids) | List of created route table IDs for privating routing to be used for VPN route propagation | `list(string)` | `[]` | no | +| [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no | +| [tgw\_environment](#input\_tgw\_environment) | Transit Gatewway environment purpose (services, dev, test, stage, prod, cre) | `string` | `null` | no | +| [tgw\_route\_table\_association](#input\_tgw\_route\_table\_association) | Transit Gateway Route Table to associate the VPN attachments with. Only one route table may be associated with a VPN attachment. | `string` | `null` | no | +| [tgw\_route\_table\_propagation](#input\_tgw\_route\_table\_propagation) | Transit Gateway Route Tables to propagate the VPN attachments. Multiple route tables may be selected. | `list(string)` | `[]` | no | +| [tgw\_vpn\_settings](#input\_tgw\_vpn\_settings) | Transit Gateway VPN Connection details array of objects |
list(object(| `[]` | no | +| [transit\_gateway\_id](#input\_transit\_gateway\_id) | Transit Gateway ID | `string` | n/a | yes | +| [use\_tgw\_prefixes](#input\_use\_tgw\_prefixes) | Flag to enable or disable the use of Transit Gateway prefixes (default: false) | `bool` | `false` | no | +| [vpc\_environment](#input\_vpc\_environment) | VPC environment purpose (infrastructure, common, shared, dev, stage, ite, prod) | `string` | `null` | no | +| [vpc\_full\_name](#input\_vpc\_full\_name) | VPC full name component (vpc{index}-{vpc\_name}) | `string` | `null` | no | +| [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | n/a | yes | +| [vpc\_index](#input\_vpc\_index) | VPC index number (integer starting at 1) | `number` | `null` | no | +| [vpc\_name](#input\_vpc\_name) | VPC name component used through the VPC descrbing its purpose (ex: dice-dev) | `string` | `null` | no | +| [vpc\_short\_name](#input\_vpc\_short\_name) | VPC short name component (vpc{index}) | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [vpn\_labels](#output\_vpn\_labels) | VPN Labels for Description field of Endpoint device (Cisco ASR) | +| [vpn\_tunnel\_endpoints](#output\_vpn\_tunnel\_endpoints) | VPN Tunnel Endpoint IP Addresses | diff --git a/vpn-transit-gateway/data.tf b/vpn-transit-gateway/data.tf new file mode 120000 index 0000000..995624d --- /dev/null +++ b/vpn-transit-gateway/data.tf @@ -0,0 +1 @@ +../common/data.tf \ No newline at end of file diff --git a/vpn-transit-gateway/defaults.tf b/vpn-transit-gateway/defaults.tf new file mode 120000 index 0000000..a5556ac --- /dev/null +++ b/vpn-transit-gateway/defaults.tf @@ -0,0 +1 @@ +../common/defaults.tf \ No newline at end of file diff --git a/vpn-transit-gateway/main.tf b/vpn-transit-gateway/main.tf new file mode 100644 index 0000000..8e98e9a --- /dev/null +++ b/vpn-transit-gateway/main.tf @@ -0,0 +1,212 @@ +/* +* # About aws-vpc-setup :: vpn-transit-gateway +* +* This sets up a VPN for the specified site (hq or bcc) and all the necessary related components: +* * customer gateway per site, environment and sequence +* * vpn connection to the transit gateway +* +* It generates a password for each site and uses the same one for each of the site's two tunnels. +* +* To download the configuration, follow these directions [page 24 from AWS docs](https://docs.aws.amazon.com/vpn/latest/s2svpn/s2s-vpn-user-guide.pdf): +* +* > To download the configuration file +* > 1. Open the Amazon VPC console at https://console.aws.amazon.com/vpc/. +* > 1. In the navigation pane, choose Site-to-Site VPN Connections. +* > 1. Select your VPN connection and choose Download Configuration. +* > 1. Select the vendor, platform, and software that corresponds to your customer gateway device or +* > 1oftware. If your device is not listed, choose Generic. Choose Download. +* > * Vendor: Cisco Systems, Inc. +* > * Platform: Cisco ASR 1000 +* > * Software: IOS 12.4+ +* +* # Usage +* +* ```hcl +* module "vpn_transit-gateway" { +* source = "git@github.e.it.census.gov:terraform-modules/aws-vpc-setup.git//vpn-transit-gateway" +* create = true +* vpc_id = "vpc-1234568" +* transit_gateway_id = "tgw-12345678" +* tgw_environment = "dev" +* vpn_settings = [ +* { site = "hq", environment = "dev", sequence = 1, "bgp_asn_id" = 65510, "ip_address" = "148.129.160.100" }, +* { site = "bcc", environment = "dev", sequence = 1, "bgp_asn_id" = 65511, "ip_address" = "148.129.90.100" }, +* ] +* tgw_route_table_association = "tgw-rtb-123123123123" +* tgw_route_table_propagation = [ "tgw-rtb-123123123123", "tgw-rtb-234234234234" ] +* tags = {} +* +* # optional +* # use_tgw_prefixes = true +* } +* ``` +*/ + +locals { + account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id + account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" + region = data.aws_region.current.name + + _vpn_settings = [for v in var.tgw_vpn_settings : merge(v, { + site = lower(v.site) + environment = lower(v.environment) + label = format("%v-%v-%v", lower(v.site), lower(v.environment), v.sequence) + is_valid = contains(local._defaults["transit-gateway-environments"], lower(v.environment)) + })] + vpn_settings = var.create ? { for v in local._vpn_settings : v.label => v if v.is_valid } : {} + tgw_route_table_propagation = length(var.tgw_route_table_propagation) > 0 && length(local.vpn_settings) > 0 ? { for p in setproduct(keys(local.vpn_settings), var.tgw_route_table_propagation) : format("%v:%v", p[0], p[1]) => { + label = format("%v:%v", p[0], p[1]) + vpn_label = p[0] + tgw_route_table = p[1] + } } : {} + + base_tags = { + "boc:tf_module_version" = local._module_version + "boc:created_by" = "terraform" + } + + # vpn_gateway = element(concat(aws_vpn_gateway.vpn[*].id, list("")), 0) +} + + +## #--- +## # vpn gateway (one per vpc) +## #--- +## resource "aws_vpn_gateway" "vpn" { +## count = var.create ? 1 : 0 +## vpc_id = var.vpc_id +## +## tags = merge( +## local.base_tags, +## var.tags, +## map("Name", format("%v%v", local._prefixes["vpn-gateway"], var.vpc_full_name)) +## ) +## } +## +## resource "aws_vpn_gateway_attachment" "vpn" { +## count = var.create ? 1 : 0 +## vpc_id = var.vpc_id +## vpn_gateway_id = local.vpn_gateway +## } + +#--- +# customer gateway, one per vpc per site +#--- +resource "aws_customer_gateway" "vpn" { + for_each = var.create ? local.vpn_settings : {} + bgp_asn = each.value.bgp_asn_id + ip_address = each.value.ip_address + type = "ipsec.1" + + tags = merge( + local.base_tags, + var.tags, + { + Name = format("%v%v%v", (var.use_tgw_prefixes ? local._prefixes["transit-gateway-vpn"] : ""), local._prefixes["customer-gateway"], each.key) + "boc:tgw_environment" = var.tgw_environment + }, + ) +} + +#--- +# vpn pre-shared key (same for each tunnel per site, one per site) +#--- +resource "random_string" "tunnel_preshared_key" { + for_each = var.create ? local.vpn_settings : {} + length = 32 + special = true + override_special = "._" +} + +#--- +# vpn connection, one per vpn endpoint +#--- +resource "aws_vpn_connection" "vpn" { + for_each = var.create ? local.vpn_settings : {} + type = aws_customer_gateway.vpn[each.key].type + + transit_gateway_id = var.transit_gateway_id + customer_gateway_id = aws_customer_gateway.vpn[each.key].id + enable_acceleration = false + + tunnel1_preshared_key = length(each.value.preshared_keys) == 0 ? random_string.tunnel_preshared_key[each.key].result : element(each.value.preshared_keys, 0) + tunnel2_preshared_key = length(each.value.preshared_keys) == 0 ? random_string.tunnel_preshared_key[each.key].result : element(each.value.preshared_keys, 1) + + tunnel1_inside_cidr = length(each.value.tunnel_ips) == 0 ? null : element(each.value.tunnel_ips, 0) + tunnel2_inside_cidr = length(each.value.tunnel_ips) == 0 ? null : element(each.value.tunnel_ips, 1) + + static_routes_only = false + + tags = merge( + local.base_tags, + var.tags, + { + Name = format("%v%v%v", (var.use_tgw_prefixes ? local._prefixes["transit-gateway-vpn"] : ""), local._prefixes["vpn-connection"], each.key) + "boc:tgw_environment" = var.tgw_environment + }, + ) +} + +# attachments are implicity. Use aws_ec2_tag to set the tags +# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_transit_gateway_vpn_attachment +# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag + +resource "aws_ec2_tag" "vpn_tag_created_by" { + for_each = var.create ? local.vpn_settings : {} + resource_id = aws_vpn_connection.vpn[each.key].transit_gateway_attachment_id + key = "boc:created_by" + value = local.base_tags["boc:created_by"] +} +resource "aws_ec2_tag" "vpn_tag_name" { + for_each = var.create ? local.vpn_settings : {} + resource_id = aws_vpn_connection.vpn[each.key].transit_gateway_attachment_id + key = "Name" + value = format("%v%v%v", (var.use_tgw_prefixes ? local._prefixes["transit-gateway-vpn"] : ""), local._prefixes["vpn-connection"], each.key) +} +resource "aws_ec2_tag" "vpn_tag_environment" { + for_each = var.create ? local.vpn_settings : {} + resource_id = aws_vpn_connection.vpn[each.key].transit_gateway_attachment_id + key = "boc:tgw_environment" + value = var.tgw_environment +} + +## #--- +## # vpn routes and propagation +## #--- +## # do not use connection routes for vpn bgp dynamic routing +## # assumes dynamic routing only, so this is commented out and will need to be re-worked if static is desired +## #resource "aws_vpn_connection_route" "vpn" { +## # count = var.vpc_vpn_dynamic_routing ? 0 : length(var.network_census) +## # destination_cidr_block = var.network_census[count.index] +## # vpn_connection_id = aws_vpn_connection.vpn.id +## #} +## +## locals { +## vpn_route_table_ids = [ +## for pair in setproduct(keys(local.vpn_settings), var.route_table_ids) : { +## site = pair[0] +## route_table_id = pair[1] +## } +## ] +## } +## +## # use this resource, do not use propagating_vgws on the route tables. Need this for one per route table ID +## resource "aws_vpn_gateway_route_propagation" "vpn" { +## for_each = var.create ? { for v in local.vpn_route_table_ids : "${v.site}.${v.route_table_id}" => v } : {} +## +## # vpn_gateway_id = aws_vpn_gateway.vpn.id +## vpn_gateway_id = local.vpn_gateway +## route_table_id = each.value.route_table_id +## } + +resource "aws_ec2_transit_gateway_route_table_association" "route_table" { + for_each = var.create ? local.vpn_settings : {} + transit_gateway_attachment_id = aws_vpn_connection.vpn[each.key].transit_gateway_attachment_id + transit_gateway_route_table_id = var.tgw_route_table_association +} + +resource "aws_ec2_transit_gateway_route_table_propagation" "propagate" { + for_each = var.create ? local.tgw_route_table_propagation : {} + transit_gateway_attachment_id = aws_vpn_connection.vpn[each.value.vpn_label].transit_gateway_attachment_id + transit_gateway_route_table_id = each.value.tgw_route_table +} diff --git a/vpn-transit-gateway/outputs.tf b/vpn-transit-gateway/outputs.tf new file mode 100644 index 0000000..0f94e0d --- /dev/null +++ b/vpn-transit-gateway/outputs.tf @@ -0,0 +1,28 @@ +output "vpn_tunnel_endpoints" { + description = "VPN Tunnel Endpoint IP Addresses" + value = { for k, v in local.vpn_settings : k => { + site = v.site + environment = v.environment + sequence = v.sequence + label = v.label + full_label = format("aws:%v:%v:%v:%v", local.region, local.account_id, aws_vpn_connection.vpn[k].id, v.label) + customer_address = aws_customer_gateway.vpn[k].ip_address + bgp_asn = aws_customer_gateway.vpn[k].bgp_asn + tunnel1_bgp_asn = aws_vpn_connection.vpn[k].tunnel1_bgp_asn + tunnel2_bgp_asn = aws_vpn_connection.vpn[k].tunnel2_bgp_asn + tunnel1_address = aws_vpn_connection.vpn[k].tunnel1_address + tunnel2_address = aws_vpn_connection.vpn[k].tunnel2_address + } + } +} + +output "vpn_labels" { + description = "VPN Labels for Description field of Endpoint device (Cisco ASR)" + value = { for k, v in local.vpn_settings : k => { + site = v.site + environment = v.environment + sequence = v.sequence + label = format("aws:%v:%v:%v:%v", local.region, local.account_id, aws_vpn_connection.vpn[k].id, v.label) + } + } +} diff --git a/vpn-transit-gateway/prefixes.tf b/vpn-transit-gateway/prefixes.tf new file mode 120000 index 0000000..7e265d5 --- /dev/null +++ b/vpn-transit-gateway/prefixes.tf @@ -0,0 +1 @@ +../common/prefixes.tf \ No newline at end of file diff --git a/vpn-transit-gateway/variables.common.tf b/vpn-transit-gateway/variables.common.tf new file mode 120000 index 0000000..7439ed8 --- /dev/null +++ b/vpn-transit-gateway/variables.common.tf @@ -0,0 +1 @@ +../common/variables.common.tf \ No newline at end of file diff --git a/vpn-transit-gateway/variables.common.vpc.tf b/vpn-transit-gateway/variables.common.vpc.tf new file mode 120000 index 0000000..5e77d37 --- /dev/null +++ b/vpn-transit-gateway/variables.common.vpc.tf @@ -0,0 +1 @@ +../common/variables.common.vpc.tf \ No newline at end of file diff --git a/vpn-transit-gateway/variables.common.vpc_id.tf b/vpn-transit-gateway/variables.common.vpc_id.tf new file mode 120000 index 0000000..bc2e061 --- /dev/null +++ b/vpn-transit-gateway/variables.common.vpc_id.tf @@ -0,0 +1 @@ +../common/variables.common.vpc_id.tf \ No newline at end of file diff --git a/vpn-transit-gateway/variables.create.tf b/vpn-transit-gateway/variables.create.tf new file mode 120000 index 0000000..de1275b --- /dev/null +++ b/vpn-transit-gateway/variables.create.tf @@ -0,0 +1 @@ +../common/variables.create.tf \ No newline at end of file diff --git a/vpn-transit-gateway/variables.tf b/vpn-transit-gateway/variables.tf new file mode 100644 index 0000000..abc2784 --- /dev/null +++ b/vpn-transit-gateway/variables.tf @@ -0,0 +1,53 @@ +variable "route_table_ids" { + description = "List of created route table IDs for privating routing to be used for VPN route propagation" + type = list(string) + default = [] +} + +# note these tunnel_ips are not permitted +# 169.254.0.0/30 169.254.1.0/30 169.254.2.0/30 169.254.3.0/30 169.254.4.0/30 169.254.5.0/30 169.254.169.252/30 +# example: site=hq, environment=services, sequence=1, bgp_asn_id=asn, ip_address=endpoint-ip-on-prem, tunnel_ips=169.254.x.1/30,169.254.x.2/30, shared_secrets=bob,alice +variable "tgw_vpn_settings" { + description = "Transit Gateway VPN Connection details array of objects" + type = list(object( + { + site = string + environment = string + sequence = number + bgp_asn_id = number + ip_address = string + tunnel_ips = list(string) + preshared_keys = list(string) + } + )) + default = [] +} + +variable "transit_gateway_id" { + description = "Transit Gateway ID" + type = string +} + +variable "use_tgw_prefixes" { + description = "Flag to enable or disable the use of Transit Gateway prefixes (default: false)" + type = bool + default = false +} + +variable "tgw_route_table_association" { + description = "Transit Gateway Route Table to associate the VPN attachments with. Only one route table may be associated with a VPN attachment." + type = string + default = null +} + +variable "tgw_route_table_propagation" { + description = "Transit Gateway Route Tables to propagate the VPN attachments. Multiple route tables may be selected." + type = list(string) + default = [] +} + +variable "tgw_environment" { + description = "Transit Gatewway environment purpose (services, dev, test, stage, prod, cre)" + type = string + default = null +} diff --git a/vpn-transit-gateway/version.tf b/vpn-transit-gateway/version.tf new file mode 120000 index 0000000..b83c5b7 --- /dev/null +++ b/vpn-transit-gateway/version.tf @@ -0,0 +1 @@ +../common/version.tf \ No newline at end of file diff --git a/vpn-transit-gateway/versions.tf b/vpn-transit-gateway/versions.tf new file mode 120000 index 0000000..41bb22f --- /dev/null +++ b/vpn-transit-gateway/versions.tf @@ -0,0 +1 @@ +../common/versions.tf \ No newline at end of file
{
site = string
environment = string
sequence = number
bgp_asn_id = number
ip_address = string
tunnel_ips = list(string)
preshared_keys = list(string)
}
))