Git Product home page Git Product logo

terraform-aws-transit-gateway's Introduction

AWS Transit Gateway Terraform module

Terraform module which creates Transit Gateway resources on AWS.

Usage with VPC module

module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.0"

  name        = "my-tgw"
  description = "My TGW shared with several other AWS accounts"

  enable_auto_accept_shared_attachments = true

  vpc_attachments = {
    vpc = {
      vpc_id       = module.vpc.vpc_id
      subnet_ids   = module.vpc.private_subnets
      dns_support  = true
      ipv6_support = true

      tgw_routes = [
        {
          destination_cidr_block = "30.0.0.0/16"
        },
        {
          blackhole = true
          destination_cidr_block = "40.0.0.0/20"
        }
      ]
    }
  }

  ram_allow_external_principals = true
  ram_principals = [307990089504]

  tags = {
    Purpose = "tgw-complete-example"
  }
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"

  name = "my-vpc"

  cidr = "10.10.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"]

  enable_ipv6                                    = true
  private_subnet_assign_ipv6_address_on_creation = true
  private_subnet_ipv6_prefixes                   = [0, 1, 2]
}

Examples

Requirements

Name Version
terraform >= 0.13.1
aws >= 4.4

Providers

Name Version
aws >= 4.4

Modules

No modules.

Resources

Name Type
aws_ec2_tag.this resource
aws_ec2_transit_gateway.this resource
aws_ec2_transit_gateway_route.this resource
aws_ec2_transit_gateway_route_table.this resource
aws_ec2_transit_gateway_route_table_association.this resource
aws_ec2_transit_gateway_route_table_propagation.this resource
aws_ec2_transit_gateway_vpc_attachment.this resource
aws_ram_principal_association.this resource
aws_ram_resource_association.this resource
aws_ram_resource_share.this resource
aws_ram_resource_share_accepter.this resource
aws_route.this resource

Inputs

Name Description Type Default Required
amazon_side_asn The Autonomous System Number (ASN) for the Amazon side of the gateway. By default the TGW is created with the current default Amazon ASN. string null no
create_tgw Controls if TGW should be created (it affects almost all resources) bool true no
create_tgw_routes Controls if TGW Route Table / Routes should be created bool true no
description Description of the EC2 Transit Gateway string null no
enable_auto_accept_shared_attachments Whether resource attachment requests are automatically accepted bool false no
enable_default_route_table_association Whether resource attachments are automatically associated with the default association route table bool true no
enable_default_route_table_propagation Whether resource attachments automatically propagate routes to the default propagation route table bool true no
enable_dns_support Should be true to enable DNS support in the TGW bool true no
enable_multicast_support Whether multicast support is enabled bool false no
enable_vpn_ecmp_support Whether VPN Equal Cost Multipath Protocol support is enabled bool true no
name Name to be used on all the resources as identifier string "" no
ram_allow_external_principals Indicates whether principals outside your organization can be associated with a resource share. bool false no
ram_name The name of the resource share of TGW string "" no
ram_principals A list of principals to share TGW with. Possible values are an AWS account ID, an AWS Organizations Organization ARN, or an AWS Organizations Organization Unit ARN list(string) [] no
ram_resource_share_arn ARN of RAM resource share string "" no
ram_tags Additional tags for the RAM map(string) {} no
share_tgw Whether to share your transit gateway with other accounts bool true no
tags A map of tags to add to all resources map(string) {} no
tgw_default_route_table_tags Additional tags for the Default TGW route table map(string) {} no
tgw_route_table_tags Additional tags for the TGW route table map(string) {} no
tgw_tags Additional tags for the TGW map(string) {} no
tgw_vpc_attachment_tags Additional tags for VPC attachments map(string) {} no
timeouts Create, update, and delete timeout configurations for the transit gateway map(string) {} no
transit_gateway_cidr_blocks One or more IPv4 or IPv6 CIDR blocks for the transit gateway. Must be a size /24 CIDR block or larger for IPv4, or a size /64 CIDR block or larger for IPv6 list(string) [] no
transit_gateway_route_table_id Identifier of EC2 Transit Gateway Route Table to use with the Target Gateway when reusing it between multiple TGWs string null no
vpc_attachments Maps of maps of VPC details to attach to TGW. Type 'any' to disable type validation by Terraform. any {} no

Outputs

Name Description
ec2_transit_gateway_arn EC2 Transit Gateway Amazon Resource Name (ARN)
ec2_transit_gateway_association_default_route_table_id Identifier of the default association route table
ec2_transit_gateway_id EC2 Transit Gateway identifier
ec2_transit_gateway_owner_id Identifier of the AWS account that owns the EC2 Transit Gateway
ec2_transit_gateway_propagation_default_route_table_id Identifier of the default propagation route table
ec2_transit_gateway_route_ids List of EC2 Transit Gateway Route Table identifier combined with destination
ec2_transit_gateway_route_table_association Map of EC2 Transit Gateway Route Table Association attributes
ec2_transit_gateway_route_table_association_ids List of EC2 Transit Gateway Route Table Association identifiers
ec2_transit_gateway_route_table_default_association_route_table Boolean whether this is the default association route table for the EC2 Transit Gateway
ec2_transit_gateway_route_table_default_propagation_route_table Boolean whether this is the default propagation route table for the EC2 Transit Gateway
ec2_transit_gateway_route_table_id EC2 Transit Gateway Route Table identifier
ec2_transit_gateway_route_table_propagation Map of EC2 Transit Gateway Route Table Propagation attributes
ec2_transit_gateway_route_table_propagation_ids List of EC2 Transit Gateway Route Table Propagation identifiers
ec2_transit_gateway_vpc_attachment Map of EC2 Transit Gateway VPC Attachment attributes
ec2_transit_gateway_vpc_attachment_ids List of EC2 Transit Gateway VPC Attachment identifiers
ram_principal_association_id The Amazon Resource Name (ARN) of the Resource Share and the principal, separated by a comma
ram_resource_share_id The Amazon Resource Name (ARN) of the resource share

Authors

Module is maintained by Anton Babenko with help from these awesome contributors.

License

Apache 2 Licensed. See LICENSE for full details.

terraform-aws-transit-gateway's People

Contributors

alimakki avatar antonbabenko avatar betajobot avatar bryantbiggs avatar da3mon-01 avatar dev-slatto avatar jmcorallo avatar jurgenweber avatar kamilhristov avatar l13t avatar matthewrkrieger avatar michelzanini avatar semantic-release-bot avatar swibrow avatar szpuni avatar tfhartmann avatar vitalis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-aws-transit-gateway's Issues

Error: "transit_gateway_route_table_id": required field is not set

I get the following error even when I was uncommented the transit_gateway_route_table_id line and add my tgw route table id.

Error: "transit_gateway_route_table_id": required field is not set on .terraform/modules/dev_bi_dw_infra_prod_tgw/main.tf line 54, in resource "aws_ec2_transit_gateway_route" "this": 54: resource "aws_ec2_transit_gateway_route" "this" {

Thanks

RAM resource association fails (in the same account).

Hi,

module failed to create the aws_ram_resource_association for tgw. I was trying to do a VPC attachement in the same account as the transit gateway.
I
Error: error associating RAM Resource Share: OperationNotPermittedException: The resource you are attempting to share can only be shared within your AWS Organization. This error may also occur if you have not enabled sharing with your AWS organization, or that onboarding process is still in progress.

PS: we don't want to allow the RAM share on the AWS Org.

Thanks

The example doesnt create VPC attachments nor TGW routes

It seems that the complete example provided doesnt create some core TGW resources that it should. Below is the plan ive got directly using the complete example, but in nowhere does it specify the following that should be created...

  • aws_ec2_transit_gateway_vpc_attachment
  • aws_ec2_transit_gateway_route
  • aws_ec2_transit_gateway_route_table_association
  • aws_ec2_transit_gateway_route_table_propagation

Am i missing anything here?

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.aws_vpc.default: Refreshing state...
data.aws_subnet_ids.this: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.vpc1.aws_egress_only_internet_gateway.this[0] will be created
  + resource "aws_egress_only_internet_gateway" "this" {
      + id     = (known after apply)
      + tags   = {
          + "Name" = "vpc1"
        }
      + vpc_id = (known after apply)
    }

  # module.vpc1.aws_route.private_ipv6_egress[0] will be created
  + resource "aws_route" "private_ipv6_egress" {
      + destination_ipv6_cidr_block = "::/0"
      + destination_prefix_list_id  = (known after apply)
      + egress_only_gateway_id      = (known after apply)
      + gateway_id                  = (known after apply)
      + id                          = (known after apply)
      + instance_id                 = (known after apply)
      + instance_owner_id           = (known after apply)
      + nat_gateway_id              = (known after apply)
      + network_interface_id        = (known after apply)
      + origin                      = (known after apply)
      + route_table_id              = (known after apply)
      + state                       = (known after apply)
    }

  # module.vpc1.aws_route.private_ipv6_egress[1] will be created
  + resource "aws_route" "private_ipv6_egress" {
      + destination_ipv6_cidr_block = "::/0"
      + destination_prefix_list_id  = (known after apply)
      + egress_only_gateway_id      = (known after apply)
      + gateway_id                  = (known after apply)
      + id                          = (known after apply)
      + instance_id                 = (known after apply)
      + instance_owner_id           = (known after apply)
      + nat_gateway_id              = (known after apply)
      + network_interface_id        = (known after apply)
      + origin                      = (known after apply)
      + route_table_id              = (known after apply)
      + state                       = (known after apply)
    }

  # module.vpc1.aws_route.private_ipv6_egress[2] will be created
  + resource "aws_route" "private_ipv6_egress" {
      + destination_ipv6_cidr_block = "::/0"
      + destination_prefix_list_id  = (known after apply)
      + egress_only_gateway_id      = (known after apply)
      + gateway_id                  = (known after apply)
      + id                          = (known after apply)
      + instance_id                 = (known after apply)
      + instance_owner_id           = (known after apply)
      + nat_gateway_id              = (known after apply)
      + network_interface_id        = (known after apply)
      + origin                      = (known after apply)
      + route_table_id              = (known after apply)
      + state                       = (known after apply)
    }

  # module.vpc1.aws_route_table.private[0] will be created
  + resource "aws_route_table" "private" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + tags             = {
          + "Name" = "vpc1-private-eu-west-1a"
        }
      + vpc_id           = (known after apply)
    }

  # module.vpc1.aws_route_table.private[1] will be created
  + resource "aws_route_table" "private" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + tags             = {
          + "Name" = "vpc1-private-eu-west-1b"
        }
      + vpc_id           = (known after apply)
    }

  # module.vpc1.aws_route_table.private[2] will be created
  + resource "aws_route_table" "private" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + tags             = {
          + "Name" = "vpc1-private-eu-west-1c"
        }
      + vpc_id           = (known after apply)
    }

  # module.vpc1.aws_route_table_association.private[0] will be created
  + resource "aws_route_table_association" "private" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc1.aws_route_table_association.private[1] will be created
  + resource "aws_route_table_association" "private" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc1.aws_route_table_association.private[2] will be created
  + resource "aws_route_table_association" "private" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc1.aws_subnet.private[0] will be created
  + resource "aws_subnet" "private" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = true
      + availability_zone               = "eu-west-1a"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "10.10.1.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = false
      + owner_id                        = (known after apply)
      + tags                            = {
          + "Name" = "vpc1-private-eu-west-1a"
        }
      + vpc_id                          = (known after apply)
    }

  # module.vpc1.aws_subnet.private[1] will be created
  + resource "aws_subnet" "private" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = true
      + availability_zone               = "eu-west-1b"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "10.10.2.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = false
      + owner_id                        = (known after apply)
      + tags                            = {
          + "Name" = "vpc1-private-eu-west-1b"
        }
      + vpc_id                          = (known after apply)
    }

  # module.vpc1.aws_subnet.private[2] will be created
  + resource "aws_subnet" "private" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = true
      + availability_zone               = "eu-west-1c"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "10.10.3.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = false
      + owner_id                        = (known after apply)
      + tags                            = {
          + "Name" = "vpc1-private-eu-west-1c"
        }
      + vpc_id                          = (known after apply)
    }

  # module.vpc1.aws_vpc.this[0] will be created
  + resource "aws_vpc" "this" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = true
      + cidr_block                       = "10.10.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = (known after apply)
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = false
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name" = "vpc1"
        }
    }

  # module.vpc2.aws_route_table.private[0] will be created
  + resource "aws_route_table" "private" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + tags             = {
          + "Name" = "vpc2-private-eu-west-1a"
        }
      + vpc_id           = (known after apply)
    }

  # module.vpc2.aws_route_table.private[1] will be created
  + resource "aws_route_table" "private" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + tags             = {
          + "Name" = "vpc2-private-eu-west-1b"
        }
      + vpc_id           = (known after apply)
    }

  # module.vpc2.aws_route_table.private[2] will be created
  + resource "aws_route_table" "private" {
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = (known after apply)
      + tags             = {
          + "Name" = "vpc2-private-eu-west-1c"
        }
      + vpc_id           = (known after apply)
    }

  # module.vpc2.aws_route_table_association.private[0] will be created
  + resource "aws_route_table_association" "private" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc2.aws_route_table_association.private[1] will be created
  + resource "aws_route_table_association" "private" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc2.aws_route_table_association.private[2] will be created
  + resource "aws_route_table_association" "private" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # module.vpc2.aws_subnet.private[0] will be created
  + resource "aws_subnet" "private" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = "eu-west-1a"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "10.20.1.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = false
      + owner_id                        = (known after apply)
      + tags                            = {
          + "Name" = "vpc2-private-eu-west-1a"
        }
      + vpc_id                          = (known after apply)
    }

  # module.vpc2.aws_subnet.private[1] will be created
  + resource "aws_subnet" "private" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = "eu-west-1b"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "10.20.2.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = false
      + owner_id                        = (known after apply)
      + tags                            = {
          + "Name" = "vpc2-private-eu-west-1b"
        }
      + vpc_id                          = (known after apply)
    }

  # module.vpc2.aws_subnet.private[2] will be created
  + resource "aws_subnet" "private" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = "eu-west-1c"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "10.20.3.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block                 = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)
      + map_public_ip_on_launch         = false
      + owner_id                        = (known after apply)
      + tags                            = {
          + "Name" = "vpc2-private-eu-west-1c"
        }
      + vpc_id                          = (known after apply)
    }

  # module.vpc2.aws_vpc.this[0] will be created
  + resource "aws_vpc" "this" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "10.20.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = (known after apply)
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = false
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name" = "vpc2"
        }
    }

  # module.tgw.module.tgw.aws_ec2_transit_gateway.this[0] will be created
  + resource "aws_ec2_transit_gateway" "this" {
      + amazon_side_asn                    = 64532
      + arn                                = (known after apply)
      + association_default_route_table_id = (known after apply)
      + auto_accept_shared_attachments     = "enable"
      + default_route_table_association    = "enable"
      + default_route_table_propagation    = "enable"
      + description                        = "My TGW shared with several other AWS accounts"
      + dns_support                        = "enable"
      + id                                 = (known after apply)
      + owner_id                           = (known after apply)
      + propagation_default_route_table_id = (known after apply)
      + tags                               = {
          + "Name"    = "my-tgw"
          + "Purpose" = "tgw-complete-example"
        }
      + vpn_ecmp_support                   = "enable"
    }

  # module.tgw.module.tgw.aws_ec2_transit_gateway_route_table.this[0] will be created
  + resource "aws_ec2_transit_gateway_route_table" "this" {
      + default_association_route_table = (known after apply)
      + default_propagation_route_table = (known after apply)
      + id                              = (known after apply)
      + tags                            = {
          + "Name"    = "my-tgw"
          + "Purpose" = "tgw-complete-example"
        }
      + transit_gateway_id              = (known after apply)
    }

Plan: 26 to add, 0 to change, 0 to destroy.

Can't associate VPCs in second account with non-default route table

Versions

terraform = v0.13.5
aws provider = v3.2.0
transit-gateway module = 1.3.0

Module settings

Account A

create_tgw = true 
share_tgw = true
ram_allow_external_principals = true
ram_principals = [<account_b>]
enable_default_route_table_association = false
enable_default_route_table_propagation = false

Account B

create_tgw = false 
share_tgw = true

vpc_attachments = {
  vpc-1 = {
    <snip>
    tgw_id = module.account_a.this_ec2_transit_gateway_id
    transit_gateway_route_table_id = module.account_a.this_ec2_transit_gateway_route_table_id
    transit_gateway_default_route_table_association = false
    transit_gateway_default_route_table_propagation = false
  }
}

For this to work, the VPC attachment needs to be created in Account B but the association/propagation or routes need to be created in Account A. The module tries to create all resources in Account B and fails.

module.account_b.aws_ec2_transit_gateway_route_table_association.this["vpc-1"]  will be created
module.account_b.aws_ec2_transit_gateway_route_table_propagation.this["vpc-1"] will be created
module.account_b.aws_ec2_transit_gateway_vpc_attachment.this["vpc-1"] will be created

Error messages;

Error: error associating EC2 Transit Gateway Route Table (tgw-rtb-<id>) association (tgw-attach-<id>): InvalidRouteTableID.NotFound: Transit Gateway Route Table tgw-rtb-<id> was deleted or does not exist.
        status code: 400, request id: <id>

Error: error associating EC2 Transit Gateway Route Table (tgw-rtb-<id>) association (tgw-attach-<id>): InvalidRouteTableID.NotFound: Transit Gateway Route Table tgw-rtb-<id> was deleted or does not exist.
        status code: 400, request id: <id>

always diff on transit_gateway_default_route_table_association = false -> true

Description

I'm using this module to provision TGW & TGW attachments in multiaccount environment.
Everything works however on every terraform plan I see a diff for
transit_gateway_default_route_table_association = true -> false

There is a related issue with a workaround provided here but lifecycle can be used only inside the resource which means that only the owner of the module can implement it or I have to pull the code into my repo which is undesired.

  transit_gateway_default_route_table_association = false
  transit_gateway_default_route_table_propagation = false

  lifecycle {
    ignore_changes = [
      transit_gateway_default_route_table_association,
      transit_gateway_default_route_table_propagation
    ]
  }

Versions

  • Module version [Required]: 2.8.1

  • Terraform version: 1.3.4

  • Terragrunt version: 0.40.2

  • Provider version(s):

  • provider registry.terraform.io/hashicorp/aws v4.38.0
  • provider registry.terraform.io/hashicorp/local v2.2.2
  • provider registry.terraform.io/hashicorp/null v3.1.1
  • provider registry.terraform.io/hashicorp/random v3.4.3
  • provider registry.terraform.io/hashicorp/template v2.2.0

Reproduction Code [Required]

module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "= 2.8.1"

  name        = local.name
  description = "TGW shared with several other AWS accounts"

  create_tgw = var.create_tgw
  share_tgw  = var.share_tgw

  amazon_side_asn = 64532
  enable_auto_accept_shared_attachments = var.enable_auto_accept_shared_attachments

  enable_mutlicast_support = var.enable_mutlicast_support
  ram_resource_share_arn   = var.ram_resource_share_arn

  enable_default_route_table_association = false
  enable_default_route_table_propagation = true

  vpc_attachments = {
    "${var.env}-vpc" = {
      vpc_id       = module.vpc.vpc_id
      tgw_id       = var.tgw_id
      subnet_ids   = module.vpc.private_subnets
      dns_support  = var.enable_dns_support_tgw
      ipv6_support = false

      transit_gateway_default_route_table_association = var.create_tgw ? true : false
      transit_gateway_default_route_table_propagation = var.create_tgw ? false : true
    }
  }

  ram_allow_external_principals = true
  ram_principals                = var.ram_principals
  tags = {
    topology = var.create_tgw ? "hub" : "spoke"
  }
}

locals {
  subaccount_vpc_attachments = var.create_tgw ? compact([for x in tolist(data.aws_ec2_transit_gateway_vpc_attachments.filtered[0].ids) : x == module.tgw.ec2_transit_gateway_vpc_attachment_ids[0] ? "" : x]) : []
}

data "aws_ec2_transit_gateway_vpc_attachments" "filtered" {
  count = var.create_tgw ? 1 : 0

  filter {
    name   = "transit-gateway-id"
    values = [module.tgw.ec2_transit_gateway_id]
  }
}

resource "aws_ec2_transit_gateway_route" "spoke_routes" {
  count = var.create_tgw ? 1 : 0

  destination_cidr_block         = module.vpc.vpc_cidr_block
  transit_gateway_attachment_id  = module.tgw.ec2_transit_gateway_vpc_attachment_ids[0]
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.spoke_route_table[0].id
}

resource "aws_ec2_transit_gateway_route_table" "spoke_route_table" {
  count = var.create_tgw ? 1 : 0

  transit_gateway_id = module.tgw.ec2_transit_gateway_id
}

resource "aws_ec2_transit_gateway_route_table_association" "spoke_route_table_association" {
  for_each = toset(local.subaccount_vpc_attachments)

  transit_gateway_attachment_id  = each.key
  transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.spoke_route_table[0].id
}

resource "aws_ec2_transit_gateway_route_table_association" "hub_route_table_association" {
  count = var.create_tgw ? 1 : 0

  transit_gateway_attachment_id  = module.tgw.ec2_transit_gateway_vpc_attachment_ids[0]
  transit_gateway_route_table_id = module.tgw.ec2_transit_gateway_propagation_default_route_table_id
}

resource "aws_route" "this_public" {
  count = length(var.routes_destination_cidr_blocks)

  route_table_id         = module.vpc.public_route_table_ids[0]
  destination_cidr_block = element(var.routes_destination_cidr_blocks, count.index)
  transit_gateway_id     = var.create_tgw ? module.tgw.ec2_transit_gateway_id : var.tgw_id
}

resource "aws_route" "this_private" {
  count = length(var.routes_destination_cidr_blocks)

  route_table_id         = module.vpc.private_route_table_ids[0]
  destination_cidr_block = element(var.routes_destination_cidr_blocks, count.index)
  transit_gateway_id     = var.create_tgw ? module.tgw.ec2_transit_gateway_id : var.tgw_id
}

Steps to reproduce the behavior:

No.
Using terragrunt.

Yes

terrafomr/terragrunt plan

Expected behavior

no diff

Actual behavior

There is always a diff regardless if the account has a TGW or only attachment.
Example:

  # module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["staging-vpc"] will be updated in-place
  ~ resource "aws_ec2_transit_gateway_vpc_attachment" "this" {
        id                                              = "tgw-attach-0408540f40c2c1646"
        tags                                            = {
            "Name"     = "staging-tgw"
            "topology" = "spoke"
        }
      ~ transit_gateway_default_route_table_association = true -> false
        # (9 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Bug when creating a VPC attachment into the TGW shared from different account

Description

Hi There!

I trying to create a TGW in an account and shared it with another account, let's call them "Account A" and "Account B" respectively.

Both "aws_ec2_transit_gateway_route_table_association.this" and "aws_ec2_transit_gateway_route_table_propagation.this" were failed to create in "Account B" module.

Error: Invalid index

  on .terraform/modules/shared_tgw/main.tf line 93, in resource "aws_ec2_transit_gateway_route_table_association" "this":
  93:   transit_gateway_route_table_id = coalesce(lookup(each.value, "transit_gateway_route_table_id", null), var.transit_gateway_route_table_id, aws_ec2_transit_gateway_route_table.this[0].id)
    |----------------
    | aws_ec2_transit_gateway_route_table.this is empty tuple

The given key does not identify an element in this collection value.


Error: Invalid index

  on .terraform/modules/shared_tgw/main.tf line 101, in resource "`aws_ec2_transit_gateway_route_table_propagation`" "this":
 101:   transit_gateway_route_table_id = coalesce(lookup(each.value, "transit_gateway_route_table_id", null), var.transit_gateway_route_table_id, aws_ec2_transit_gateway_route_table.this[0].id)
    |----------------
    | aws_ec2_transit_gateway_route_table.this is empty tuple

The given key does not identify an element in this collection value.

It seems like bugs in these lines:

The "Account B" module is trying to provision with create_tgw = false, hence "aws_ec2_transit_gateway_route_table.this" will not be created. I guess the lines above failed because it trying to references aws_ec2_transit_gateway_route_table.this[0].id which is a null object, hence getting Invalid index error.

Versions

  • Terraform: v0.12.31
  • Provider(s): v3.40.0
  • Module: 2.1.0

Reproduction

Steps to reproduce the behavior:

  • Create a module that will create TGW and enable sharing
  • Create another module that not create TGW, but referencing the Shared TGW and TGW Routing table populate by the first module.

Code Snippet to Reproduce

Account A

module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.1.0"

  name            = "internal-it-tgw"
  description     = "Account A"
  share_tgw       = true
  create_tgw      = true
  ram_principals  = var.ram_shared_tgw_principals

  ram_allow_external_principals         = true
  enable_auto_accept_shared_attachments = true

  providers = {
    aws = aws.account-a
  }
}

Account B (shared)

module "shared_tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.1.0"

  name        = "shared-tgw"
  share_tgw   = true
  create_tgw  = false

  ram_resource_share_arn         = module.tgw.ram_resource_share_id
  transit_gateway_route_table_id = module.tgw.ec2_transit_gateway_route_table_id

  vpc_attachments = {
    vpc = {
      vpc_id      = var.aws_vpc_id
      subnet_ids  = var.aws_subnets_ids
      tgw_id      = module.tgw.ec2_transit_gateway_id
      dns_support = true

      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false

      tgw_routes = [
        {
            destination_cidr_block = var.cidr_block
        },
        {
            blackhole              = true
            destination_cidr_block = "0.0.0.0/0"
        }
      ]
    }
  }


  providers = {
    aws = aws.account-b
  }
}

Expected behavior

Able to associate the routing table to Account B VPC attachment.

Actual behavior

Failed due to the suspected bug mentioned above.

Terminal Output Screenshot(s)

Refer to the output above.

Default Transit Gateway Route Table tags

When setting enable_default_route_table_association=true or enable_default_route_table_propagation=true and passing in tgw_route_table_tags, 2 route tables get created. 1 that is set as the default route table that has the associations and/or propagations with no tags and another route table that is empty that is tagged correctly.

[feature request] - Module not yet support to update routes in attachment VPCs

Hi guys.
Seem currently I see the modules not yet support to add routes (tgw) into VPC Route Tables
.....
My TF file
`
module "tgw" {
source = "./terraform-aws-transit-gateway"

name = "tgw"
description = "My TGW shared with several other AWS accounts"

vpc_attachments = {
vpc = {
vpc_id = module.my_vpc.vpc_id
subnet_ids = module.my_vpc.vpc_id.private_subnets
dns_support = true
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
vpc1 = {
vpc_id = module.my_vpc_01.vpc_id
subnet_ids = module.my_vpc_01.private_subnets
dns_support = true
},
}

tags = {
Purpose = "tgw-complete-example"
}
}
`
Thanks so much

Please provide (add) additional example

Hello, i'm relatively new to Terraform and usage of Terraform modules such as "terraform-aws-transit-gateway" and "terraform-aws-vpc".
I would like to ask you to provide (add) additional example :-)
In my case i have multiple AWS Accounts, but to make it simpler I have:

  • account A (production account, created long time ago, fully manual)
  • account B (newly added account)
    In account A in us-west-1 we have TGW which shared with multiple AWS Accounts. In account A in us-west-1 I went ahead created manually RAM resource share for TGW. In Account B I accepted shared resource (TGW).
    I wanted to research "terraform-aws-vpc" module to create VPCs / Subnets / NATGW / IGW etc. And then I found out that "terraform-aws-transit-gateway" module can also manage TGW and Transit gateway attachments and Transit gateway route tables.
    I would like to try to manage Transit gateway attachment and Transit gateway route table in Account B via "terraform-aws-transit-gateway" module.
    In examples (https://github.com/terraform-aws-modules/terraform-aws-transit-gateway/tree/master/examples) I see two options, but I was not able to understand how to use "terraform-aws-transit-gateway" module for my use case.

Could you please create additional example?
Thank you.

Additional vpc_attachment tags for "each" objects

Is your request related to a problem? Please describe.

resource "aws_ec2_transit_gateway_vpc_attachment" "this" {
  for_each = var.vpc_attachments
  ...
  .
  ...

  tags = merge(
    var.tags,
    { Name = var.name },
    var.tgw_vpc_attachment_tags,
  )
}

Describe the solution you'd like.

resource "aws_ec2_transit_gateway_vpc_attachment" "this" {
  for_each = var.vpc_attachments
  ...
  .
  ...

  tags = merge(
    var.tags,
    { Name = var.name },
    var.tgw_vpc_attachment_tags,
    each.value.tags
  )
}

Describe alternatives you've considered.

Additional context

VPC routes are not added, causing traffic not to flow through TGW

Description

This might be operator error, but I can't get the module to add routes for the TGW in each VPC, which causes VPCs not to route to each other through the TGW.

Is the TGW module intended to do this? If not, could the examples include code showing how to add the routes in Terraform, using TGW and VPC module outputs?

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]:
$ terraform modules -version
Terraform v1.2.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.22.0
  • Terraform version:
$ terraform version
Terraform v1.2.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.22.0
  • Provider version(s):
$ terraform providers -version
Terraform v1.2.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v4.22.0

Reproduction Code [Required]

locals {
  region = "us-east-1"
  name   = "wolf-test"
}

provider "aws" {
  region = local.region
}

module "tgw" {
  source    = "terraform-aws-modules/transit-gateway/aws"
  version   = "~> 2.0"
  name      = "${local.name}-tgw"
  share_tgw = false

  vpc_attachments = {
    vpc1 = {
      vpc_id       = module.vpc1.vpc_id
      subnet_ids   = module.vpc1.public_subnets
      dns_support  = true
      ipv6_support = false
      tgw_routes = [{ destination_cidr_block = "10.20.0.0/16" }]
    },
    vpc2 = {
      vpc_id       = module.vpc2.vpc_id
      subnet_ids   = module.vpc2.public_subnets
      dns_support  = true
      ipv6_support = false
      tgw_routes = [{ destination_cidr_block = "10.21.0.0/16" }]
    }
  }
}

module "vpc1" {
  source         = "terraform-aws-modules/vpc/aws"
  version        = "~> 3.0"
  name           = "${local.name}-vpc1"
  cidr           = "10.20.0.0/16"
  azs            = ["${local.region}a", "${local.region}b", "${local.region}c"]
  public_subnets = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"]
  enable_ipv6    = false
}

module "vpc2" {
  source         = "terraform-aws-modules/vpc/aws"
  version        = "~> 3.0"
  name           = "${local.name}-vpc2"
  cidr           = "10.21.0.0/16"
  azs            = ["${local.region}a", "${local.region}b", "${local.region}c"]
  public_subnets = ["10.21.1.0/24", "10.21.2.0/24", "10.21.3.0/24"]
  enable_ipv6    = false
}

I've tried various combinations of VPC attachment tgw_routes lists, transit_gateway_default_route_table_association, and transit_gateway_default_route_table_propagation but the module never adds the VPC routes required for instances to connect to each other through the TGW.

Steps to reproduce the behavior:

terraform init
terraform apply

Are you using workspaces?
No

Have you cleared the local cache (see Notice section above)?
Yes

Expected behavior

I expected a TGW module to add routes to the VPCs which are required for routing to work. If the TGW module isn't intended to do that, it would be helpful for the included examples to show Terraform code to add the routes using the TGW and VPC module outputs.

Actual behavior

VPC routes aren't added by the TGW module. Hosts on each VPC can't reach each other until I manually add the VPC routes.

Terminal Output Screenshot(s)

Additional context

mutlicast??

Module has mutlicast not multicast ?! typo!?

Making VPC Attachments without creating TGW fails

My simple use case is:

Account 1 (networking) hosts TGW

include {
  path = find_in_parent_folders()
}

terraform {
  source  = "[email protected]:TierMobility/terraform-aws-transit-gateway.git?ref=bb1a74673f26a807a195e5ea4648d8078db61ec1" # I'm using TierMobility's branch because of the default route addition.
}

inputs = {
  name = "my-tgw"
  ram_principals = [
    "arn:aws:organizations::1111222233334444:organization/o-organization_id"
  ]
}

Account 2 (shared services) hosts a VPC with resources that will be connected to TGW

VPC:

include {
  path = find_in_parent_folders()
}

terraform {
  source = "[email protected]:terraform-aws-modules/terraform-aws-vpc.git?ref=v2.33.0"
}

inputs = {
  name = "dev_databases"
  cidr = "10.135.0.0/16"

  azs = [
    "us-west-2a",
    "us-west-2b",
    "us-west-2c",
    "us-west-2d",
  ]

  database_subnets = [
    "10.135.0.0/22",
    "10.135.4.0/22",
    "10.135.8.0/22",
    "10.135.12.0/22",
  ]

  private_subnets = [
    "10.135.254.0/24",
    "10.135.255.0/24",
  ]
}

TGW:

include {
  path = find_in_parent_folders()
}

terraform {
  source  = "[email protected]:TierMobility/terraform-aws-transit-gateway.git?ref=bb1a74673f26a807a195e5ea4648d8078db61ec1"
}

dependency "vpc" {
  config_path = "../dev_databases/vpc"
}

dependency "root-tgw" {
  config_path = "../../networking-acc-1234/tgw"
}

inputs = {
  create_tgw = false
  vpc_attachments = {
    s = {
      tgw_id =  dependency.root-tgw.outputs.this_ec2_transit_gateway_id
      vpc_id = dependency.vpc.outputs.vpc_id
      subnet_ids = concat(
        dependency.vpc.outputs.database_subnets,
      )
    }
  }
  transit_gateway_route_table_id = dependency.root-tgw.outputs.this_ec2_transit_gateway_route_table_id
}

Error

Error: Invalid index

  on main.tf line 70, in resource "aws_ec2_transit_gateway_vpc_attachment" "this":
  70:   transit_gateway_id = lookup(each.value, "tgw_id", aws_ec2_transit_gateway.this[0].id)
    |----------------
    | aws_ec2_transit_gateway.this is empty tuple

The given key does not identify an element in this collection value.

Releasing state lock. This may take a few moments...
[terragrunt] 2020/04/21 17:21:31 Hit multiple errors:
exit status 1

My solution here was to simply change line 70 to transit_gateway_id = lookup(each.value, "tgw_id", try(aws_ec2_transit_gateway.this[0].id, null)), which I'm going to PR.

TGW with VPCs from other accounts

Hi, thanks for this module, looks awesome!

Question, does this module support creating the TGW in one account and attaching the VPCs from different accounts?

I've been trying to do that by following the multi account example but I can't seem to figure how to achieve this. For example:

provider "aws" {
  region = var.aws_region

  # Only these AWS Account IDs may be operated on by this template
  allowed_account_ids = [var.aws_account_id]
}

terraform {
  backend "s3" {}

  required_version = "= 0.13.7"

  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.26"
    }
  }
}

provider "aws" {
  alias  = "dev"

  region = var.aws_region

  assume_role {
    role_arn     = "arn:aws:iam::xxxxxxxx:role/allow-full-access-from-other-accounts"
  }
}

provider "aws" {
  alias  = "staging"

  region = var.aws_region

  assume_role {
    role_arn     = "arn:aws:iam::zzzzzz:role/allow-full-access-from-other-accounts"
  }
}

provider "aws" {
  alias  = "prod"

  region = var.aws_region

  assume_role {
    role_arn     = "arn:aws:iam::wwwww:role/allow-full-access-from-other-accounts"
  }
}


module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.1.0"

  create_tgw  = true
  name        = var.name
  description = var.description

  enable_default_route_table_association = var.enable_default_route_table_association
  enable_default_route_table_propagation = var.enable_default_route_table_propagation
  enable_auto_accept_shared_attachments = var.enable_auto_accept_shared_attachments
  enable_vpn_ecmp_support = var.enable_vpn_ecmp_support
  enable_dns_support = var.enable_dns_support

  tags = var.tags
}

module "tgw_dev" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.1.0"

  providers = {
    aws = aws.dev
  }

  name        = "${var.name}-tgw-dev"
  description = "${var.description} Dev attachment"

  share_tgw   = true
  create_tgw  = false
  ram_resource_share_arn = module.tgw.ram_resource_share_id
  enable_auto_accept_shared_attachments = var.enable_auto_accept_shared_attachments

  enable_dns_support = var.enable_dns_support

  enable_default_route_table_association = var.enable_default_route_table_association
  enable_default_route_table_propagation = var.enable_default_route_table_propagation
  enable_vpn_ecmp_support = var.enable_vpn_ecmp_support

  ram_allow_external_principals = var.ram_allow_external_principals
  ram_principals = var.ram_principals

  vpc_attachments = {
    dev_vpc = {
      tgw_id       = module.tgw.ec2_transit_gateway_id
      vpc_id       = var.dev_vpc_id
      subnet_ids   = var.dev_vpc_private_app_subnet_ids
      dns_support  = true
      ipv6_support = false
      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false

      tgw_routes = [
        {
          destination_cidr_block = var.dev_destination_cidr_block
        },
      ]
    }
  }
}

Error creating EC2 tags when default route table association is false

Description

Raised as a separate issue based on comments from #23 after closing.

Errors like the following are thrown when tags are set and enable_default_route_table_association is false.

Error: error creating EC2 Tag (ops.company.cloud/provisioner) for resource (): error tagging resource (): InvalidParameterValue: Value ( null ) for parameter resourceId is invalid. Null/empty value for resourceId is invalid
	status code: 400, request id: 42192f9f-1546-4714-b9b2-b5b4e948ef64

  on .terraform/modules/tgw/main.tf line 44, in resource "aws_ec2_tag" "this":
  44: resource "aws_ec2_tag" "this" {

Versions

  • Module: >=2.3.0 (introduced in #49)

Reproduction

Steps to reproduce the behavior:
Try to configure a transit gateway with tags set, but enable_default_route_table_association is false.

Expected behavior

EC2 tags are not set on the non-existant default route table association.

Actual behavior

Errors like the ones @stevie- posted here

for_each value depends on resource.... error

I am trying to use this module to manage our TGW attachments, but am getting the following error during the plan phase.

Terraform version:

$ terraform -v
Terraform v0.12.20
+ provider.aws v2.47.0

Code:

module "vpc" {
  source = "git::ssh://[email protected]/systems/terraform-aws-vpc.git"
  # Local copy of master branch of https://github.com/terraform-aws-modules/terraform-aws-vpc

  name = var.environment
  create_vpc = true

  cidr                 = "10.${var.network_number}.0.0/16"
  private_subnets     = ["10.${var.network_number}.0.0/24","10.${var.network_number}.1.0/24","10.${var.network_number}.2.0/24"]
  public_subnets      = ["10.${var.network_number}.10.0/24","10.${var.network_number}.11.0/24","10.${var.network_number}.12.0/24"]

  enable_nat_gateway       = "true"
  single_nat_gateway       = "false"
  enable_s3_endpoint       = "true"
  enable_dynamodb_endpoint = "false"

  enable_dns_hostnames = "true"
  enable_dns_support   = "true"

  azs = var.azs

  tags = {
    "Environment" = var.environment
  }
}

module "tgw" {
  source = "git::ssh://[email protected]:systems/terraform-aws-transit-gateway.git"
   # Local copy of Master branch of https://github.com/terraform-aws-modules/terraform-aws-transit-gateway

  name = "Our-tgw"
  description = "Our transit gateway to datacenters"

  vpc_attachments = {
    vpc = {
      vpc_id = module.vpc.vpc_id
      subnet_ids = module.vpc.private_subnets
      tgw_id       = data.terraform_remote_state.region_infrastructure.outputs.transit_gw_id
      dns_support = true
      ipv6_support = true

      tgw_routes = [
        "208.1.0.0/22", "207.1.0.0/22"
      ]
    }
  }

  ram_allow_external_principals = false

  tags = {
        Name        = "${var.environment} TGW"
        Environment = "${var.environment}"
  }
}

Errors:

Error: Invalid for_each argument

  on .terraform/modules/tgw/main.tf line 89, in resource "aws_ec2_transit_gateway_route_table_association" "this":
  89:   for_each = local.vpc_attachments_without_default_route_table_association

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.


Error: Invalid for_each argument

  on .terraform/modules/tgw/main.tf line 97, in resource "aws_ec2_transit_gateway_route_table_propagation" "this":
  97:   for_each = local.vpc_attachments_without_default_route_table_association

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.

Releasing state lock. This may take a few moments...

Multiple Route Tables possibility

Is your request related to a problem? Please describe.

Need to create more than one Transit Gateway Route Table per Transit Gateway.
Looking into examples and git repo code I cannot see that this is possible.

Describe the solution you'd like.

Create more than one Transit Gateway Route Table per Transit Gateway.

Describe alternatives you've considered.

Using native terraform resources (aws_ec2_transit_gateway_route_table) to augment this module's functionality.

Execution fails when using `vpc_attachments[].vpc_route_table_ids`

Description

Trying to add routes to Route Tables provided via vpc_attachments[].vpc_route_table_ids results in Terraform failing with an error message.

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]: 2.8.2
  • Terraform version:
    Terraform v1.3.7
    on darwin_arm64
    
  • Provider version(s):
    provider registry.terraform.io/hashicorp/aws v4.46.0
    

Reproduction Code [Required]

Everything it needs is to configure IPv6 and provide VPC Route Tables:

module "my_vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"

  name = "my-vpc"
  cidr = "10.1.0.0/16"

  azs             = ["${local.region}a", "${local.region}b"]
  private_subnets = ["10.1.1.0/24", "10.1.2.0/24"]
  public_subnets  = ["10.1.101.0/24", "10.1.102.0/24"]

  enable_nat_gateway = false
}

module "my_tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.0"

  name = "my-tgw"

  vpc_attachments = {
    vpc = {
      vpc_id     = module.my_vpc.vpc_id
      subnet_ids = module.my_vpc.private_subnets

      tgw_destination_cidr = "0.0.0.0/0"
      vpc_route_table_ids  = module.my_vpc.private_route_table_ids
    },
  }
}

Expected behavior

The code runs and routes are being created.

Actual behavior

The code fails with

β•·
β”‚ Error: Invalid for_each argument
β”‚ 
β”‚   on .terraform/modules/my_tgw/main.tf line 112, in resource "aws_route" "this":
β”‚  112:   for_each = { for x in local.vpc_route_table_destination_cidr : x.rtb_id => x.cidr }
β”‚     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚     β”‚ local.vpc_route_table_destination_cidr will be known only after apply
β”‚ 
β”‚ The "for_each" map includes keys derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.
β”‚ 
β”‚ When working with unknown values in for_each, it's better to define the map keys statically in your configuration and place apply-time results only in the map values.
β”‚ 
β”‚ Alternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge.
β•΅

attach multiple vpc to TGW

Is your request related to a new offering from AWS?

NO

Describe the solution you'd like.

I want to create a TGW and attach multiple VPC to it

Same CIDR can't be use in tgw route table

Description

Please provide a clear and concise description of the issue you are encountering, and a reproduction of your configuration (see the examples/* directory for references that you can copy+paste and tailor to match your configs if you are unable to copy your exact configuration). The reproduction MUST be executable by running terraform init && terraform apply without any further changes.

If your request is for a new feature, please use the Feature request template.

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Module version [Required]:

  • Terraform version:
    0.14.4

  • Provider version(s):
    4.4.0

Reproduction Code [Required]

within tgw module:

  vpc_attachments = {
    456_vpc = {
      vpc_id       = 456
      subnet_ids   =789
      dns_support  = true
      ipv6_support = false

      tgw_routes = [
        {
          destination_cidr_block = "10.0.0.0/16"
        }
      ]
    }
    123_vpc = {
      vpc_id       = 123
      subnet_ids   = 456
      dns_support  = true
      ipv6_support = false

      tgw_routes = [
        {
          destination_cidr_block = "10.0.0.0/16"
        }
      ]
    }
  }

Steps to reproduce the behavior:

use the same cidr for destination block between two vpc, the route entry will be keep flip each time you plan and apply.

Expected behavior

Two unique entry in tgw route table.

Actual behavior

The route entry in tgw keep flip between 2 entry

Terminal Output Screenshot(s)

Additional context

Flow Log Support

Is your request related to a new offering from AWS?

Is this functionality available in the AWS provider for Terraform? See CHANGELOG.md, too.

  • Yes βœ…: please list the AWS provider version which introduced this functionality

Is your request related to a problem? Please describe.

Describe the solution you'd like.

  • Toggle for TGW Flow Log and Supporting Resources.

Describe alternatives you've considered.

  • This could be created outside of this module but since the VPC Module supports this and the functionality is nearly identical I see no reason not to support this within the TGW Module as well.

Additional context

  • This request is targeting the TGW itself, while Flow Logs also support TGW-Attachments this feature is not targeting those required changes.

`vpc_attachments.my-vpc.transit_gateway_default_route_table_association` doesn't agree with output `module.my-tgw.ec2_transit_gateway_route_table_default_association_route_table`

Description

The module's output variable ec2_transit_gateway_route_table_default_association_route_table doesn't seem to be computed correctly. It doesn't agree with the module's input variable/sub-attribute transit_gateway_default_route_table_association.

Versions

  • Terraform:
$ terraform version
Terraform v1.0.10
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.64.0

Reproduction

Code Snippet to Reproduce

module "my-tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.5.0"
  ...
  vpc_attachments = {
    jump-vpc = {
      vpc_id = ...
      ...
      transit_gateway_default_route_table_association = true # This is the default value anyway
    }
  }
}

output "my-tgw-ec2_transit_gateway_route_table_default_association_route_table" {
  value = module.my-tgw.ec2_transit_gateway_route_table_default_association_route_table
}

Expected behavior

I expect that the output variable should agree with the input attribute transit_gateway_default_route_table_association which is true.

$ terraform output
my-tgw-ec2_transit_gateway_route_table_default_association_route_table = ture

Actual behavior

But the actual result is the opposite, i.e., false:

$ terraform output
my-tgw-ec2_transit_gateway_route_table_default_association_route_table = false

As an aside, the official snippet in Terraform Registry and the complete sample code contain no explanation of how that flag affects the behaviour of the module. I'm not sure whether I understand the intention of that flag correctly even after reading the module's source code.

Furthermore, based on all the open Github issues for this repo as of today, there're almost a year's accumulation of numerous issues still open about various aspects of routing tables, most of which without responses from code authors. Is this module's handling of routing tables solid?

Invalid index

I see that the module can create routes in the VPC to redirect traffic to the TG.
But I don’t understand what variables he needs.

`Error: Invalid index

on .terraform/modules/tgw/main.tf line 93, in resource "aws_route" "this":
93: transit_gateway_id = aws_ec2_transit_gateway.this[0].id
|----------------
| aws_ec2_transit_gateway.this is empty tuple

The given key does not identify an element in this collection value.`

Error creating transit gateway attachments between shared accounts. Error: No RAM Resource Share () invitation found

Description

I'm having an issue with sharing a tgw between accounts in the same organization with autoaccept enabled.

Both accounts are in the same organization and auto accept is enabled. The resources (vpc, subnets) in the client account are not terraform created.

Error received:

β”‚ Error: No RAM Resource Share () invitation found
β”‚ 
β”‚ NOTE: If both AWS accounts are in the same AWS Organization and RAM Sharing with AWS Organizations is enabled, this resource is not necessary
β”‚ 
β”‚   with module.tgw_peer.aws_ram_resource_share_accepter.this[0],
β”‚   on .terraform/modules/tgw_peer/main.tf line 170, in resource "aws_ram_resource_share_accepter" "this":
β”‚  170: resource "aws_ram_resource_share_accepter" "this" {
β”‚ 

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Module version [Required]:

  • Terraform version:

Terraform v1.3.6
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v4.46.0
  • Provider version(s):
Terraform v1.3.6
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v4.46.0

Reproduction Code [Required]

#Providers, versions and additional prerequisites.
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.46.0"
    }
  }
}


provider "aws" {
  region  = var.vpcRegion
  profile = "ent"
}
provider "aws" {
  alias = "dev"
  region  = var.vpcRegion
  shared_config_files = [<credentials>]
  profile = "dev"
}

#VPC declaration
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.18.1"

  name = "ent-core-infrastructure"
  cidr = "10.5.0.0/16"

  azs                                  = ["${var.vpcRegion}a", "${var.vpcRegion}b", "${var.vpcRegion}c"]
  public_subnets                       = ["10.5.1.0/24", "10.5.2.0/24", "10.5.3.0/24"]
  private_subnets                      = ["10.5.4.0/24", "10.5.5.0/24", "10.5.6.0/24"]
  intra_subnets                        = ["10.5.7.0/24", "10.5.8.0/24", "10.5.9.0/24"]
  single_nat_gateway                   = true
  enable_nat_gateway                   = true
  enable_flow_log                      = false
  create_flow_log_cloudwatch_iam_role  = false
  create_flow_log_cloudwatch_log_group = false
}

#Transit gateway declaration
module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.8.1"

  name = "e2-ent-tgw-001"
  description = "Enterprise Transit Gateway. Provisioned using Terraform. Acts as the central interface between offices and AWS."

  enable_auto_accept_shared_attachments = true
  enable_mutlicast_support = true



  vpc_attachments = {
    ent-core-infrastructure = {
      vpc_id      = module.vpc.vpc_id
      subnet_ids  = module.vpc.private_subnets
      dns_support = true

      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false

    }
  }

  #share_tgw = true
  ram_name = "enterprise-transit-gateway-share"
  ram_allow_external_principals = true
  ram_principals = [
    635757009592
  ]
}

module "tgw_peer" {
  source = "terraform-aws-modules/transit-gateway/aws"

  providers = {
    aws = aws.dev
  }

  name = "test-peer"
  description = "test dev peering using a module"

  create_tgw = false
  #share_tgw = true
  #ram_resource_share_arn = module.tgw.ram_resource_share_id
  enable_auto_accept_shared_attachments = true

  vpc_attachments = {
    dev_vpc = {
#existing vpc
      vpc_id = "vpc-xxxxxxxxxxxxxxxxx"
      tgw_id = module.tgw.ec2_transit_gateway_id
      subnet_ids = ["subnet-xxxxxxxx", "subnet-xxxxxxxx"]
      dns_support = true

      transit_gateway_default_route_table_propagation = false
      transit_gateway_default_route_table_association = false

      tgw_routes = [
        {
          destination_cidr_block = "10.5.0.0/16"
        },
        {
          destination_cidr_block = "10.20.0.0/16"
        }
      ]
    }
  }

  depends_on = [module.tgw]
}

Steps to reproduce the behavior:

no

yes

simply running a terraform apply on this will produce this error

Expected behavior

Create a transit gateway in the master account, create an attachment to it in a vpc in the sub-account. Resulting in a clean run.

Actual behavior

module.tgw.aws_ram_resource_share.this[0]: Creating...
module.vpc.aws_eip.nat[0]: Creating...
module.tgw.aws_ec2_transit_gateway.this[0]: Creating...
module.vpc.aws_vpc.this[0]: Creating...
module.vpc.aws_eip.nat[0]: Creation complete after 1s [id=eipalloc-0fa702f441bc91b2a]
module.tgw.aws_ram_resource_share.this[0]: Creation complete after 1s [id=arn:aws:ram:us-east-2:845940089308:resource-share/836a1157-d934-4cc0-8ab4-97121919b482]
module.tgw.aws_ram_principal_association.this[0]: Creating...
module.tgw.aws_ram_principal_association.this[1]: Creating...
module.vpc.aws_vpc.this[0]: Creation complete after 1s [id=vpc-0539a16057343bbb8]
module.vpc.aws_subnet.private[1]: Creating...
module.vpc.aws_route_table.private[0]: Creating...
module.vpc.aws_route_table.public[0]: Creating...
module.vpc.aws_subnet.public[1]: Creating...
module.vpc.aws_route_table.intra[0]: Creating...
module.vpc.aws_subnet.public[0]: Creating...
module.vpc.aws_subnet.intra[2]: Creating...
module.tgw.aws_ram_principal_association.this[1]: Creation complete after 0s [id=arn:aws:ram:us-east-2:845940089308:resource-share/836a1157-d934-4cc0-8ab4-97121919b482,635757009592]
module.vpc.aws_subnet.public[2]: Creating...
module.tgw.aws_ram_principal_association.this[0]: Creation complete after 1s [id=arn:aws:ram:us-east-2:845940089308:resource-share/836a1157-d934-4cc0-8ab4-97121919b482,778348368122]
module.vpc.aws_route_table.intra[0]: Creation complete after 1s [id=rtb-0fff5ea3f40b2a838]
module.vpc.aws_internet_gateway.this[0]: Creating...
module.vpc.aws_subnet.private[0]: Creating...
module.vpc.aws_route_table.public[0]: Creation complete after 1s [id=rtb-070441310eab3c9f1]
module.vpc.aws_subnet.private[2]: Creating...
module.vpc.aws_subnet.private[1]: Creation complete after 1s [id=subnet-03a9cbe89ee0cdc90]
module.vpc.aws_subnet.intra[0]: Creating...
module.vpc.aws_route_table.private[0]: Creation complete after 1s [id=rtb-00836f2861fae2e6f]
module.vpc.aws_subnet.intra[1]: Creating...
module.vpc.aws_subnet.intra[2]: Creation complete after 1s [id=subnet-07e5fcc661f2f60f3]
module.vpc.aws_internet_gateway.this[0]: Creation complete after 0s [id=igw-055a18a645f1e0e6c]
module.vpc.aws_route.public_internet_gateway[0]: Creating...
module.vpc.aws_subnet.private[0]: Creation complete after 0s [id=subnet-0fe23728ddb5d593b]
module.vpc.aws_subnet.private[2]: Creation complete after 0s [id=subnet-0a6f760a35a1d9346]
module.vpc.aws_route_table_association.private[1]: Creating...
module.vpc.aws_route_table_association.private[2]: Creating...
module.vpc.aws_route_table_association.private[0]: Creating...
module.vpc.aws_subnet.intra[1]: Creation complete after 0s [id=subnet-0cb91956aba2196d1]
module.vpc.aws_subnet.intra[0]: Creation complete after 0s [id=subnet-0489db9d27a054fd9]
module.vpc.aws_route_table_association.intra[2]: Creating...
module.vpc.aws_route_table_association.intra[0]: Creating...
module.vpc.aws_route_table_association.private[0]: Creation complete after 0s [id=rtbassoc-00dbe883fbb176716]
module.vpc.aws_route_table_association.private[2]: Creation complete after 0s [id=rtbassoc-02dc25805f57efd6d]
module.vpc.aws_route.public_internet_gateway[0]: Creation complete after 0s [id=r-rtb-070441310eab3c9f11080289494]
module.vpc.aws_route_table_association.intra[1]: Creating...
module.vpc.aws_route_table_association.private[1]: Creation complete after 1s [id=rtbassoc-02bebc6b166aaf31d]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [10s elapsed]
module.vpc.aws_subnet.public[1]: Still creating... [10s elapsed]
module.vpc.aws_subnet.public[0]: Still creating... [10s elapsed]
module.vpc.aws_subnet.public[2]: Still creating... [10s elapsed]
module.vpc.aws_subnet.public[0]: Creation complete after 11s [id=subnet-0a9be6c77de83df75]
module.vpc.aws_subnet.public[1]: Creation complete after 11s [id=subnet-02745b5cecd95fa65]
module.vpc.aws_subnet.public[2]: Creation complete after 11s [id=subnet-027bd5f23ad037261]
module.vpc.aws_route_table_association.public[0]: Creating...
module.vpc.aws_route_table_association.public[2]: Creating...
module.vpc.aws_nat_gateway.this[0]: Creating...
module.vpc.aws_route_table_association.public[1]: Creating...
module.vpc.aws_route_table_association.intra[2]: Still creating... [10s elapsed]
module.vpc.aws_route_table_association.intra[0]: Still creating... [10s elapsed]
module.vpc.aws_route_table_association.intra[1]: Still creating... [10s elapsed]
module.vpc.aws_route_table_association.public[2]: Creation complete after 1s [id=rtbassoc-04c6693b368430990]
module.vpc.aws_route_table_association.public[1]: Creation complete after 1s [id=rtbassoc-0b46b314f4b47a9c9]
module.vpc.aws_route_table_association.public[0]: Creation complete after 1s [id=rtbassoc-031641231e978e0b9]
module.vpc.aws_route_table_association.intra[2]: Creation complete after 14s [id=rtbassoc-0c7440b293d4cd8ae]
module.vpc.aws_route_table_association.intra[0]: Creation complete after 14s [id=rtbassoc-0eb3200d83c16ded5]
module.vpc.aws_route_table_association.intra[1]: Creation complete after 14s [id=rtbassoc-0f5f539a71ab7c679]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [20s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [10s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [30s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [20s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [40s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [30s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [50s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [40s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [1m0s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [50s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [1m10s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [1m0s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Still creating... [1m20s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [1m10s elapsed]
module.tgw.aws_ec2_transit_gateway.this[0]: Creation complete after 1m24s [id=tgw-0f09c208839fab7a3]
module.tgw.aws_ec2_tag.this["Name"]: Creating...
module.tgw.aws_ram_resource_association.this[0]: Creating...
module.tgw.aws_ec2_transit_gateway_route_table.this[0]: Creating...
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Creating...
module.tgw.aws_ec2_tag.this["Name"]: Creation complete after 0s [id=tgw-rtb-0c433b1024a8f3a91,Name]
module.tgw.aws_ram_resource_association.this[0]: Creation complete after 1s [id=arn:aws:ram:us-east-2:845940089308:resource-share/836a1157-d934-4cc0-8ab4-97121919b482,arn:aws:ec2:us-east-2:845940089308:transit-gateway/tgw-0f09c208839fab7a3]
module.vpc.aws_nat_gateway.this[0]: Still creating... [1m20s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table.this[0]: Still creating... [10s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [10s elapsed]
module.vpc.aws_nat_gateway.this[0]: Still creating... [1m30s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [20s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table.this[0]: Still creating... [20s elapsed]
module.vpc.aws_nat_gateway.this[0]: Creation complete after 1m34s [id=nat-0579642299de8f17c]
module.vpc.aws_route.private_nat_gateway[0]: Creating...
module.vpc.aws_route.private_nat_gateway[0]: Creation complete after 1s [id=r-rtb-00836f2861fae2e6f1080289494]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [30s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table.this[0]: Still creating... [30s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table.this[0]: Still creating... [40s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [40s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table.this[0]: Creation complete after 43s [id=tgw-rtb-0070fb2694306cc38]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [50s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [1m0s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [1m10s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [1m20s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [1m30s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Still creating... [1m40s elapsed]
module.tgw.aws_ec2_transit_gateway_vpc_attachment.this["ent-core-infrastructure"]: Creation complete after 1m49s [id=tgw-attach-0cc73f35c75659b8e]
module.tgw.aws_ec2_transit_gateway_route_table_propagation.this["ent-core-infrastructure"]: Creating...
module.tgw.aws_ec2_transit_gateway_route_table_association.this["ent-core-infrastructure"]: Creating...
module.tgw.aws_ec2_transit_gateway_route_table_propagation.this["ent-core-infrastructure"]: Creation complete after 0s [id=tgw-rtb-0070fb2694306cc38_tgw-attach-0cc73f35c75659b8e]
module.tgw.aws_ec2_transit_gateway_route_table_association.this["ent-core-infrastructure"]: Still creating... [10s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table_association.this["ent-core-infrastructure"]: Still creating... [20s elapsed]
module.tgw.aws_ec2_transit_gateway_route_table_association.this["ent-core-infrastructure"]: Creation complete after 23s [id=tgw-rtb-0070fb2694306cc38_tgw-attach-0cc73f35c75659b8e]
module.tgw_peer.aws_ram_resource_share_accepter.this[0]: Creating...
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Creating...
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Still creating... [10s elapsed]
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Still creating... [20s elapsed]
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Still creating... [30s elapsed]
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Still creating... [40s elapsed]
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Still creating... [50s elapsed]
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Still creating... [1m0s elapsed]
module.tgw_peer.aws_ec2_transit_gateway_vpc_attachment.this["dev_vpc"]: Creation complete after 1m5s [id=tgw-attach-054cc1181d65d5b1e]
β•·
β”‚ Error: No RAM Resource Share () invitation found
β”‚ 
β”‚ NOTE: If both AWS accounts are in the same AWS Organization and RAM Sharing with AWS Organizations is enabled, this resource is not necessary
β”‚ 
β”‚   with module.tgw_peer.aws_ram_resource_share_accepter.this[0],
β”‚   on .terraform/modules/tgw_peer/main.tf line 170, in resource "aws_ram_resource_share_accepter" "this":
β”‚  170: resource "aws_ram_resource_share_accepter" "this" {
β”‚ 
β•΅

Additional context

example from the module

provider "aws" {
  region = local.region
}

# This provider is required for attachment only installation in another AWS Account
provider "aws" {
  region = local.region
  alias  = "peer"
}

locals {
  name   = "ex-tgw-${replace(basename(path.cwd), "_", "-")}"
  region = "eu-west-1"

  tags = {
    Example    = local.name
    GithubRepo = "terraform-aws-eks"
    GithubOrg  = "terraform-aws-transit-gateway"
  }
}

################################################################################
# Transit Gateway Module
################################################################################

module "tgw" {
  source = "../../"

  name            = local.name
  description     = "My TGW shared with several other AWS accounts"
  amazon_side_asn = 64532

  # When "true" there is no need for RAM resources if using multiple AWS accounts
  enable_auto_accept_shared_attachments = true

  vpc_attachments = {
    vpc1 = {
      vpc_id       = module.vpc1.vpc_id
      subnet_ids   = module.vpc1.private_subnets
      dns_support  = true
      ipv6_support = true

      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false

      tgw_routes = [
        {
          destination_cidr_block = "30.0.0.0/16"
        },
        {
          blackhole              = true
          destination_cidr_block = "0.0.0.0/0"
        }
      ]
    },
    vpc2 = {
      vpc_id     = module.vpc2.vpc_id
      subnet_ids = module.vpc2.private_subnets

      tgw_routes = [
        {
          destination_cidr_block = "50.0.0.0/16"
        },
        {
          blackhole              = true
          destination_cidr_block = "10.10.10.10/32"
        }
      ]
    },
  }

  ram_allow_external_principals = true
  ram_principals                = [307990089504]

  tags = local.tags
}

module "tgw_peer" {
  # This is optional and connects to another account. Meaning you need to be authenticated with 2 separate AWS Accounts
  source = "../../"

  providers = {
    aws = aws.peer
  }

  name            = "${local.name}-peer"
  description     = "My TGW shared with several other AWS accounts"
  amazon_side_asn = 64532

  create_tgw             = false
  share_tgw              = true
  ram_resource_share_arn = module.tgw.ram_resource_share_id
  # When "true" there is no need for RAM resources if using multiple AWS accounts
  enable_auto_accept_shared_attachments = true

  vpc_attachments = {
    vpc1 = {
      tgw_id       = module.tgw.ec2_transit_gateway_id
      vpc_id       = module.vpc1.vpc_id
      subnet_ids   = module.vpc1.private_subnets
      dns_support  = true
      ipv6_support = true

      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false

      tgw_routes = [
        {
          destination_cidr_block = "30.0.0.0/16"
        },
        {
          blackhole              = true
          destination_cidr_block = "0.0.0.0/0"
        }
      ]
    },
  }

  ram_allow_external_principals = true
  ram_principals                = [307990089504]

  tags = local.tags
}

################################################################################
# Supporting resources
################################################################################

module "vpc1" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"

  name = "${local.name}-vpc1"
  cidr = "10.10.0.0/16"

  azs             = ["${local.region}a", "${local.region}b", "${local.region}c"]
  private_subnets = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"]

  enable_ipv6                                    = true
  private_subnet_assign_ipv6_address_on_creation = true
  private_subnet_ipv6_prefixes                   = [0, 1, 2]

  tags = local.tags
}


module "vpc2" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"

  providers = {
    aws = aws.peer
  }

  name = "${local.name}-vpc2"
  cidr = "10.20.0.0/16"

  azs             = ["${local.region}a", "${local.region}b", "${local.region}c"]
  private_subnets = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"]

  enable_ipv6 = false

  tags = local.tags
}

Using IPv6 with `vpc_attachments[].vpc_route_table_ids` fails

Description

The module generally supports the use of IPv6. But when adding routes to the tables provided via vpc_attachments[].vpc_route_table_ids, it always tries to assign the vpc_attachments[].tgw_destination_cidr to the IPv4 aws_route.destination_cidr_block argument. Correct would be using aws_route.destination_cidr_block for IPv4 and aws_route.destination_ipv6_cidr_block for IPv6.

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]: 2.8.2
  • Terraform version:
    Terraform v1.3.7
    on darwin_arm64
    
  • Provider version(s):
    provider registry.terraform.io/hashicorp/aws v4.46.0
    

Reproduction Code [Required]

Everything it needs is to configure IPv6 and provide VPC Route Tables:

module "my_vpc_ipv6" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"

  name = "my-vpc-ipv6"
  cidr = "10.1.0.0/16"

  azs             = ["${local.region}a", "${local.region}b"]
  private_subnets = ["10.1.1.0/24", "10.1.2.0/24"]
  public_subnets  = ["10.1.101.0/24", "10.1.102.0/24"]

  enable_nat_gateway = false

  enable_ipv6                     = true
  assign_ipv6_address_on_creation = true

  private_subnet_assign_ipv6_address_on_creation = false

  public_subnet_ipv6_prefixes  = [0, 1]
  private_subnet_ipv6_prefixes = [2, 3]
}

module "my_tgw_ipv6" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.0"

  name = "my-tgw-ipv6"

  vpc_attachments = {
    vpc = {
      vpc_id     = module.my_vpc_ipv6.vpc_id
      subnet_ids = module.my_vpc_ipv6.private_subnets

      ipv6_support         = true
      tgw_destination_cidr = "::/0"
      vpc_route_table_ids  = module.my_vpc_ipv6.private_route_table_ids
    },
  }
}

Expected behavior

The code runs and IPv6 routes are being created.

Actual behavior

The code would fails because of issue #100, but else it would fail, trying to assign an IPv6 CIDR to the IPv4 aws_route.destination_cidr_block instead of using its IPv6 counterpart aws_route.destination_ipv6_cidr_block.

Making VPC Attachments without creating TGW fails Re-open

It seems that as long as issue #11 remains unfixed the only thing that could happen when var.create_tgw is false is perhaps a little bit of routing. The PR #12 did not explain why it was closed properly, and the issue remains. If this module is not meant to be used to attach the tgw without creating it that should be added to the README.md as it limits the use cases severely in some work flows.

Referenced issue:

My simple use case is:

Account 1 (networking) hosts TGW

include {
  path = find_in_parent_folders()
}

terraform {
  source  = "[email protected]:TierMobility/terraform-aws-transit-gateway.git?ref=bb1a74673f26a807a195e5ea4648d8078db61ec1" # I'm using TierMobility's branch because of the default route addition.
}

inputs = {
  name = "my-tgw"
  ram_principals = [
    "arn:aws:organizations::1111222233334444:organization/o-organization_id"
  ]
}

Account 2 (shared services) hosts a VPC with resources that will be connected to TGW

VPC:

include {
  path = find_in_parent_folders()
}

terraform {
  source = "[email protected]:terraform-aws-modules/terraform-aws-vpc.git?ref=v2.33.0"
}

inputs = {
  name = "dev_databases"
  cidr = "10.135.0.0/16"

  azs = [
    "us-west-2a",
    "us-west-2b",
    "us-west-2c",
    "us-west-2d",
  ]

  database_subnets = [
    "10.135.0.0/22",
    "10.135.4.0/22",
    "10.135.8.0/22",
    "10.135.12.0/22",
  ]

  private_subnets = [
    "10.135.254.0/24",
    "10.135.255.0/24",
  ]
}

TGW:

include {
  path = find_in_parent_folders()
}

terraform {
  source  = "[email protected]:TierMobility/terraform-aws-transit-gateway.git?ref=bb1a74673f26a807a195e5ea4648d8078db61ec1"
}

dependency "vpc" {
  config_path = "../dev_databases/vpc"
}

dependency "root-tgw" {
  config_path = "../../networking-acc-1234/tgw"
}

inputs = {
  create_tgw = false
  vpc_attachments = {
    s = {
      tgw_id =  dependency.root-tgw.outputs.this_ec2_transit_gateway_id
      vpc_id = dependency.vpc.outputs.vpc_id
      subnet_ids = concat(
        dependency.vpc.outputs.database_subnets,
      )
    }
  }
  transit_gateway_route_table_id = dependency.root-tgw.outputs.this_ec2_transit_gateway_route_table_id
}

Error

Error: Invalid index

  on main.tf line 70, in resource "aws_ec2_transit_gateway_vpc_attachment" "this":
  70:   transit_gateway_id = lookup(each.value, "tgw_id", aws_ec2_transit_gateway.this[0].id)
    |----------------
    | aws_ec2_transit_gateway.this is empty tuple

The given key does not identify an element in this collection value.

Releasing state lock. This may take a few moments...
[terragrunt] 2020/04/21 17:21:31 Hit multiple errors:
exit status 1

My solution here was to simply change line 70 to transit_gateway_id = lookup(each.value, "tgw_id", try(aws_ec2_transit_gateway.this[0].id, null)), which I'm going to PR.

Significant refactor

Is your request related to a problem? Please describe.

This module was missing quite a few features that are necessary for true multi-account operation, as well as operational concerns like logging.

Describe the solution you'd like.

I have a large refactor of the module that I can submit as a PR, which adds the following features:

  • Add an "accepter" resource for VPC attachments, to avoid the "auto accept shared attachments" feature when using Resource Access Manager (RAM)
  • Add support for TGW Peering attachments
  • Add Flow Logs for whole-TGW and/or individual TGW Peering/VPC attachments, publishing to S3 and/or CloudWatch Logs
  • Convert tgw_routes from a list of maps to a map of maps, to avoid potential downtime associated with destroying routes when adding new ones
  • Enable multiple TGW route tables to allow for more granular network segmentation
  • Allow for adding multiple CIDR blocks to VPC route tables per-attachment, and rename the parameter from tgw_destination_cidrs to vpc_route_table_destination_cidrs to reflect its true purpose
  • Add parameters to help transform implementation steps into a more cohesive order of operations
  • Convert TGW route destination CIDR block to list, to allow multiple CIDR blocks per attachment
  • Allow for disabling non-default route table propagation, to ensure VPC CIDR block can be left out of TGW route table when only certain subnets should be routable

Describe alternatives you've considered.

I considered using different modules or writing my own from scratch, but I thought the best approach would be to perform this refactor and give it back to the community.

Additional context

I am running my refactor in production currently, using one AWS account as the hub, and several other AWS accounts as the spokes.

Would you like me to open a PR? This was a massive effort and I would love for the community to benefit from it.

Cross region support using aws_ec2_transit_gateway_peering_attachment

We already have support for aws_ec2_transit_gateway_vpc_attachment, is this the correct module to request the addition of the aws_ec2_transit_gateway_peering_attachment resource too ?

module "tgw_oregon_public" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 1.0"
  
  name        = "us-west-2_public"
  description = "us-west-2 public transit gateway"
  
  amazon_side_asn = "64512" # should be unique

  enable_auto_accept_shared_attachments = false

  vpc_attachments = {
    oregon = {
      ...
    },
  }

  # example
  peering_attachments = {
    oregon = {
      vpc_id = ""
      subnet_ids = []
    },
  }
}

Module do not accept RAM Resource in remote AWS Account

Currently transit gateway module implementation do not work correctly if used to deploy it multiple account.

Transit Gateway is correctly created in one account but RAM requires that we accept resources from remote account before Transit Gateway is visible in shared AWS Account.
If share is not visible code deploys another Transit Gateway which is not what you would expect to happen.

Module should be able to create just VPC attachment in separate account and should be able to auto accept RAM Share in another AWS Account.

Creating a shared TGW across multiple AWS accounts fails

Description

Using this module to create a shared TGW across multiple AWS account fails.

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Terraform: 1.0.10
  • Provider(s): 3.64.1
  • Module: v2.5.0

Reproduction

Steps to reproduce the behavior:

  • Use the module to create a TGW in account A
  • Use the module to associate a VPC in account B with the TGW in account A
    All per the multi-account example

Expected behavior

A TGW is created in account A and we get a successful association with VPC in account B

Actual behavior

Routes and resources are not created

Probably related to:
#47

This may not strictly be a bug and needs some clarity of intended behaviour.
Our common set up would be to create the TGW resource in Account A using terraform to call in the module and be held in its own state file e.g.

Account A

module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"

  name            = "account-a-tgw"
  description     = "account-a-tgw"
  amazon_side_asn = 66666
  enable_auto_accept_shared_attachments = true

  vpc_attachments = {
    vpc1 = {
      vpc_id                                              = data.aws_vpc.default.id 
      subnet_ids                                       = data.aws_subnet_ids.this.ids
      dns_support                                    = true
      ipv6_support                                    = false
      transit_gateway_default_route_table_association = true
      transit_gateway_default_route_table_propagation = true
      vpc_route_table_ids                         = data.aws_route_tables.rts.ids
      # Route all internal traffic across TGW
      tgw_destination_cidr                  = "172.0.0.0/8"
      # Add TGW route for account A VPC
      tgw_routes = [
        {
          destination_cidr_block = "172.16.0.0/16"
        }
      ]
    }
  }
  ram_allow_external_principals = false
  ram_principals                = ["xxxxxxxxxx"]

  tags = {
    Purpose = "tgw-complete-example"
  }
}

Account B

## Lookup Account A TGW
data "aws_ec2_transit_gateway" "tgw" {
  filter {
    name   = "owner-id"
    values = ["50000000000"]
  }
  filter {
    name   = "options.amazon-side-asn"
    values = ["6666666"]
  }
  tags = {
    Name = "account-a-tgw"
    description = "account-a-tgw"
  }
}


## Use tgw module to set up tgw
module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  name            = "account-b-tgw-association"
  description     = "account-b-tgw-association"
  amazon_side_asn = 66666
  create_tgw  = false
  share_tgw   = false
  transit_gateway_id = data.aws_ec2_transit_gateway.tgw.id
  vpc_attachments = {
    vpc1 = {
      vpc_id                                              = data.aws_vpc.default.id 
      subnet_ids                                       = data.aws_subnet_ids.this.ids
      dns_support                                    = true
      ipv6_support                                    = false
      vpc_route_table_ids                         = data.aws_route_tables.rts.ids
      # Route all internal traffic across TGW
      tgw_destination_cidr                  = "172.0.0.0/8"
    }
 }
}

Route Table tags circular use on each apply

Description

When tgw_tags and tgw_route_table_tags are both defined, the tgw route table tags will be replaced on each apply with a circular use between tgw_tags and tgw_route_table_tags

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Terraform: 1.0.1
  • Provider(s): AWS 3.47.0
  • Module: 2.5.0

Reproduction

Steps to reproduce the behavior:

Cleared local cache, updated module version on each apply the transit gateway route table tags will updated rotating between the values set in tgw_tags and tgw_route_table_tags

Code Snippet to Reproduce

  tgw_tags = {
    "Name"                = "tgw-${var.environment}-${var.aws_account_short}-${var.region}"
    "upt:applicationrole" = "transit gateway"
  }

  tgw_route_table_tags = {
    "Name"                = "rt-tgw-${var.environment}-dx-${var.region}"
    "upt:applicationrole" = "transit gateway"
  }

Yields on first apply (two Transit Gateway modules are defined for different regions):

Terraform will perform the following actions:

  # module.tgw_east.aws_ec2_tag.this["Name"] will be updated in-place
  ~ resource "aws_ec2_tag" "this" {
        id          = "tgw-rtb-0d398c6b8fc7248c7,Name"
      ~ value       = "rt-tgw-p-dx-useast1" -> "tgw-p-upt-sharedservices-useast1"
        # (2 unchanged attributes hidden)
    }

  # module.tgw_japan.aws_ec2_tag.this["Name"] will be updated in-place
  ~ resource "aws_ec2_tag" "this" {
        id          = "tgw-rtb-0ccbafe954a31456d,Name"
      ~ value       = "rt-tgw-p-dx-apnortheast1" -> "tgw-p-upt-sharedservices-apnortheast1"
        # (2 unchanged attributes hidden)
    }

Plan: 0 to add, 2 to change, 0 to destroy.

On second apply:

Terraform will perform the following actions:

  # module.tgw_east.aws_ec2_transit_gateway_route_table.this[0] will be updated in-place
  ~ resource "aws_ec2_transit_gateway_route_table" "this" {
        id                              = "tgw-rtb-0d398c6b8fc7248c7"
      ~ tags                            = {
          ~ "Name"                = "tgw-p-upt-sharedservices-useast1" -> "rt-tgw-p-dx-useast1"
            # (1 unchanged element hidden)
        }
      ~ tags_all                        = {
          ~ "Name"                = "tgw-p-upt-sharedservices-useast1" -> "rt-tgw-p-dx-useast1"
            # (8 unchanged elements hidden)
        }
        # (4 unchanged attributes hidden)
    }

  # module.tgw_japan.aws_ec2_transit_gateway_route_table.this[0] will be updated in-place
  ~ resource "aws_ec2_transit_gateway_route_table" "this" {
        id                              = "tgw-rtb-0ccbafe954a31456d"
      ~ tags                            = {
          ~ "Name"                = "tgw-p-upt-sharedservices-apnortheast1" -> "rt-tgw-p-dx-apnortheast1"
            # (1 unchanged element hidden)
        }
      ~ tags_all                        = {
          ~ "Name"                = "tgw-p-upt-sharedservices-apnortheast1" -> "rt-tgw-p-dx-apnortheast1"
            # (8 unchanged elements hidden)
        }
        # (4 unchanged attributes hidden)
    }

Plan: 0 to add, 2 to change, 0 to destroy.

Expected behavior

No updates to tags on subsequent applies

Actual behavior

Tags are updated on every apply

Terminal Output Screenshot(s)

See above

Additional context

Error: creating EC2 Transit Gateway VPC Attachment: InvalidTransitGatewayID.NotFound: Transit Gateway tgw-xxx was deleted or does not exist.

Description

I've got

Error: creating EC2 Transit Gateway VPC Attachment: InvalidTransitGatewayID.NotFound: Transit Gateway tgw-xxx was deleted or does not exist.

error when I use this module and Transit Gateway attachments are made for 2 different AWS accounts and one is shared with Resource Access Manager.

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

⚠️ Note

Before you submit an issue, please perform the following first:

  1. Remove the local .terraform directory (! ONLY if state is stored remotely, which hopefully you are following that best practice!): rm -rf .terraform/
  2. Re-initialize the project root to pull down modules: terraform init
  3. Re-attempt your terraform plan or apply and check if the issue still persists

Versions

  • Module version [Required]: 2.8.1

  • Terraform version:
    1.3.3

  • Provider version(s):
    hashicorp/aws 4.37.0

Reproduction Code [Required]

Steps to reproduce the behavior:

locals {
  account_id = 111111111
  vpn_account_id = 22222222
  region = "us-east-1"
  vpc_region = "us-east-1"
}

provider "aws" {
  allowed_account_ids = [tostring(local.account_id)]
  region              = local.region
}

provider "aws" {
  alias = "vpn"

  allowed_account_ids = [tostring(local.vpn_account_id)]
  region              = local.vpn_region
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.18.1"

  name = "vpc"
  cidr = var.vpc_cidr

  azs = var.azs

  database_subnets = local.database_subnets
  private_subnets  = local.private_subnets
  public_subnets   = local.public_subnets

  create_database_subnet_group       = true
  create_database_subnet_route_table = true

  enable_nat_gateway     = true
  single_nat_gateway     = true
  one_nat_gateway_per_az = false

  enable_dns_hostnames = true

  manage_default_network_acl    = true
  manage_default_route_table    = true
  manage_default_security_group = true
}

module "vpn_tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.8.1"

  name = "vpn"

  vpc_attachments = merge(
    {
      database = {
        vpc_id       = module.vpc.vpc_id
        subnet_ids   = module.vpc.database_subnets
        dns_support  = true
        ipv6_support = false
      }
    },
  )

  create_tgw = true
  share_tgw  = true

  enable_auto_accept_shared_attachments = true

  ram_allow_external_principals = true
  ram_principals                = [local.vpn_account_id]

  depends_on = [
    module.vpc,
  ]
}

module "vpn_tgw_shared" {
  providers = {
    aws = aws.vpn
  }

  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "2.8.1"

  name = "vpn"

  vpc_attachments = {
    vpn = {
      tgw_id       = module.vpn_tgw.ec2_transit_gateway_id
      vpc_id       = local.vpn_vpc_id
      subnet_ids   = local.vpn_subnets
      dns_support  = true
      ipv6_support = false
    }
  }

  create_tgw             = false
  share_tgw              = true
  ram_resource_share_arn = module.vpn_tgw.ram_resource_share_id

  enable_auto_accept_shared_attachments = true

  ram_allow_external_principals = true
  ram_principals                = [local.account_id]

  depends_on = [
    module.vpc,
    module.vpn_tgw,
  ]
}

Expected behavior

Clean run.

Actual behavior

module.vpn_tgw[0].aws_ram_resource_share.this[0]: Creating...
module.vpn_tgw[0].aws_ram_resource_share.this[0]: Creation complete after 2s [id=arn:aws:ram:us-east-1:111111111111:resource-share/11111111-1111-1111-1111-111111111111]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [10s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [20s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [30s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [40s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [50s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [1m0s elapsed]
module.vpn_tgw[0].aws_ram_principal_association.this[0]: Creating...
module.vpn_tgw[0].aws_ram_principal_association.this[0]: Creation complete after 1s [id=arn:aws:ram:us-east-1:111111111111:resource-share/11111111-1111-1111-1111-111111111111,111111111111]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Still creating... [1m20s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway.this[0]: Creation complete after 1m25s [id=tgw-11111111111111111]
module.vpn_tgw[0].aws_ram_resource_association.this[0]: Creating...
module.vpn_tgw[0].aws_ec2_transit_gateway_route_table.this[0]: Creating...
module.vpn_tgw[0].aws_ram_resource_association.this[0]: Creation complete after 2s [id=arn:aws:ram:us-east-1:11111111111111111:resource-share/11111111-1111-1111-1111-111111111111,arn:aws:ec2:us-east-1:11111111111111111:transit-gateway/tgw-11111111111111111]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Creating...
module.vpn_tgw[0].aws_ec2_transit_gateway_route_table.this[0]: Still creating... [10s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Still creating... [10s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway_route_table.this[0]: Creation complete after 14s [id=tgw-rtb-11111111111111111]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Still creating... [20s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Still creating... [30s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Still creating... [40s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Still creating... [50s elapsed]
module.vpn_tgw[0].aws_ec2_transit_gateway_vpc_attachment.this["database"]: Creation complete after 55s [id=tgw-attach-11111111111111111]
module.vpn_tgw_shared[0].aws_ec2_transit_gateway_vpc_attachment.this["vpn"]: Creating...
module.vpn_tgw_shared[0].aws_ram_resource_share_accepter.this[0]: Creating...
module.vpn_tgw_shared[0].aws_ram_resource_share_accepter.this[0]: Creation complete after 4s [id=arn:aws:ram:us-east-1:11111111:resource-share/11111111-1111-1111-1111-111111111111]
β•·
β”‚ Error: creating EC2 Transit Gateway VPC Attachment: InvalidTransitGatewayID.NotFound: Transit Gateway tgw-11111111111111111 was deleted or does not exist.
β”‚       status code: 400, request id: 11111111-1111-1111-1111-111111111111
β”‚ 
β”‚   with module.vpn_tgw_shared[0].aws_ec2_transit_gateway_vpc_attachment.this["vpn"],
β”‚   on .terraform/modules/goby.vpn_tgw_shared/main.tf line 65, in resource "aws_ec2_transit_gateway_vpc_attachment" "this":
β”‚   65: resource "aws_ec2_transit_gateway_vpc_attachment" "this" {
β”‚ 
β•΅

Additional context

Example in https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep:

resource "aws_ram_resource_association" "example" {
  resource_arn       = aws_subnet.example.arn
  resource_share_arn = aws_ram_resource_share.example.arn
}

# AWS resources shared via Resource Access Manager can take a few seconds to
# propagate across AWS accounts after RAM returns a successful association.
resource "time_sleep" "ram_resource_propagation" {
  create_duration = "60s"

  triggers = {
    # This sets up a proper dependency on the RAM association
    subnet_arn = aws_ram_resource_association.example.resource_arn
    subnet_id  = aws_subnet.example.id
  }
}

resource "aws_db_subnet_group" "example" {
  name = "example"

  # Read the Subnet identifier "through" the time_sleep resource to ensure a
  # proper dependency and that both will change together.
  subnet_ids = [time_sleep.ram_resource_propagation.triggers["subnet_id"]]
}

So this is our exact use case! Propagation of shared resources takes some time and most likely https://github.com/hashicorp/terraform-provider-time should be used here.

FQ: VPC flow logging for TGW

Is your request related to a new offering from AWS? No

Is this functionality available in the AWS provider for Terraform? Yes, via aws_flow_log

Is your request related to a problem? No

Describe the solution you'd like.

enable_flow_logging = (bool)
flow_log_group = (string)

Describe alternatives you've considered.

Currently using the aws_flow_log resource directly.

Additional context

Great effort Cloud Posse. Your a life saver.

vpc_attachment map lacks description

Is your request related to a new offering from AWS?

Is this functionality available in the AWS provider for Terraform? See CHANGELOG.md, too.

  • No πŸ›‘: please wait to file a request until the functionality is available in the AWS provider
  • Yes βœ…: please list the AWS provider version which introduced this functionality

Is your request related to a problem? Please describe.

The vpc_attachment map lacks description of the attributes that you can specify. More specifically vpc_route_table_ids and tgw_destination_cidr are not mentioned anywhere.

Describe the solution you'd like.

Include a description of the vpc_attachment map attributes.

Describe alternatives you've considered.

None

Additional context

Deprecated Function Call

Description

map function was deprecated in Terraform 0.12. This function call now fails in Terraform 0.15.

Versions

$ terraform version
Terraform v0.15.0
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.37.0
  source = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.0"

Reproduction

Steps to reproduce the behavior:
Use the module to create any TGW

Code Snippet to Reproduce

module "tgw" {
  source = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.0"

  name            = local.tgw_name
  description     = "Regional core TGW"
  amazon_side_asn = var.asn

  enable_auto_accept_shared_attachments = true 

  vpc_attachments = {
    shared_services_vpc = {
      vpc_id                                          = module.vpc.vpc_id
      subnet_ids                                      = module.vpc.private_subnets
      dns_support                                     = true
      ipv6_support                                    = true
      transit_gateway_default_route_table_association = true
      transit_gateway_default_route_table_propagation = true
    },
  }

  ram_allow_external_principals = true
  ram_principals                = [data.aws_organizations_organization.this.arn]
}

Expected behavior

Successful plan

Actual behavior

β•·
β”‚ Error: Error in function call
β”‚ 
β”‚   on .terraform/modules/sandbox.us_east_2_net.tgw/main.tf line 12, in locals:
β”‚   12:     for k, v in var.vpc_attachments : setproduct([map("key", k)], v["tgw_routes"]) if length(lookup(v, "tgw_routes", {})) > 0
β”‚ 
β”‚ Call to function "map" failed: the "map" function was deprecated in Terraform v0.12 and is no longer available; use tomap({ ... }) syntax to write a literal map.
β•΅

Additional context

PR coming shortly

Creating only one Transit Gateway route Table

Description

Currently the module creates a Transit Gateway route table when the create_tgw variable is set to true. However, when we indicate to the transit gateway that we want a default route table (enable_default_route_table_association and enable_default_route_table_propagation), the route table resource aws_ec2_transit_gateway_route_table is no longer used since AWS will automatically create a routing table (by the way, it is tagged here, since it is not created by Terraform).

The idea is not to create this Transit Gateway Route table not used. When we want to use the default Route Table.

  • βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]: 2.9.0

  • Terraform version: v1.4.2

  • Provider version(s): 4.60.0

Reproduction Code [Required]

I only want to create a TransitGateway and a default TransitGateway Route Table.

module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.0"

  name        = "production-transit-gateway"
  description = "My TGW"

  create_tgw            = true
  amazon_side_asn = 64513

  enable_auto_accept_shared_attachments = true

  enable_default_route_table_association  = true
  enable_default_route_table_propagation = true
}

Expected behavior

The resource aws_ec2_transit_gateway_route_table is not created.
However the default Transit Gateway Route Table is created.

We can find the route table id in these outputs in ec2_transit_gateway_association_default_route_table_id and ec2_transit_gateway_propagation_default_route_table_id.

Actual behavior

Currently 2 routing tables are created and owned by the Transit Gateway.

  • the one created in the terraform stack
  • the one created automatically by AWS the default

[Feature Request] Optional Non-default Route Table

Is your request related to a problem? Please describe.

When I create a new TGW using this module, it creates an extra non-default TGW route table even if all my routes use the default TGW route table.

Describe the solution you'd like.

Non-default route table = false

Describe alternatives you've considered.

Right now, I am just manually deleting the extra table every time I run the Terraform since it's blank. It's not a huge deal, I just think it would be a nice feature - that is unless I'm doing something wrong? Code below:

module "tgw" {
  source = "terraform-aws-modules/transit-gateway/aws"
  name   = "TGW-Name"

  enable_auto_accept_shared_attachments = true
  
  vpc_attachments = {
    vpc = {
      vpc_id       = data.aws_vpc.vpc.id                                 
      subnet_ids   = var.subnets
      dns_support  = true
      ipv6_support = false
    }
  } 

  ram_allow_external_principals = true
  ram_principals                = ["##########"]
  
  tags = {
    Ticket = "######"
  }

  tgw_route_table_tags = {
    Name = "Non-default Route Table"
  }
}

Disable github-actions closing valid Issues and PRs

In this project valid issues and PRs are getting closed due to inactivity from the maintainers.

I understand the idea of closing issues if they are inactive but closing them automatically doesn't make sense if it is the maintainers who fail to respond in time. I see many issues/PRs closed while still waiting for a review.

With this setup, adding features or fixing bugs basically requires contributors to redo the work over and over again, until it finally gets some attention.

Describe the solution you'd like.

Either ensure that maintainers take are of contributions (issues or code) within the auto-stale period or disable the auto closing.

Describe alternatives you've considered.

Posting "keep alive" comments work, until you date to go to vacations or simply are busy. Also this "workaround" totally messes up with the purpose of the comments system.

Support for TF 0.14

The aws-vpc module supports TF 0.14, but this module restricts usage to 0.12 and 0.13. I assume there isn't anything specific in this module that would have any adverse affect based on the 0.14.x changelog. Can this module be updated to confirm support for 0.14?

➜ terraform init
Initializing modules...

Error: Unsupported Terraform Core version

  on .terraform/modules/transit-gateway/versions.tf line 2, in terraform:
   2:   required_version = ">= 0.12.7, < 0.14"

[feature request] module creates only single tgw route table

Hi
I'm trying to use this module to create different environment's vpcs that tgw should connect to the office using vpn connection. This module creates only single tgw route table without possibility to connect vpn to it.

Could you add to the module the following possibilities:

  • to create tgw route table per vpc attachment
  • to attach vpn to tgw route table(s)
  • (it should be more hardsome) to provide tgw route tables to create with custom configuration per each tgw route table.
  • to use list of route tables to update with the link to tgw and cidrs

I'm forking the module in order to make it by myself. If I'll succeed, I'll create a pull request with my changes.

Thank you in advance,
Ilya

Multi region errors

Does this module support multi account vpc associations and if yes, what is the proper way to pass the provider to the calling resource?

provider "aws" {
  region = "us-east-1"
  alias    = "one"
}
provider "aws" {
  region = "us-east-1"
  alias    = "two"
}

// See Notes in README.md for explanation regarding using data-sources and computed values
data "aws_vpc" "default" {
  default = true
}

data "aws_subnet_ids" "this" {
  vpc_id = data.aws_vpc.default.id
}

module "tgw" {
  **providers = {aws = "aws.one"}**
  source = "../../"
  name            = "my-tgw"
  description     = "My TGW shared with several other AWS accounts"
  amazon_side_asn = 64532
  enable_auto_accept_shared_attachments = true
  vpc_attachments = {
    vpc1 = {
      **providers = {aws = "aws.one"}**
      vpc_id                                          = data.aws_vpc.default.id      # module.vpc1.vpc_id
      subnet_ids                                      = data.aws_subnet_ids.this.ids # module.vpc1.private_subnets
      dns_support                                     = true
      ipv6_support                                    = true
      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false

      tgw_routes = [
        {
          destination_cidr_block = "30.0.0.0/16"
        },
        {
          blackhole              = true
          destination_cidr_block = "0.0.0.0/0"
        }
      ]
    },
    vpc2 = {
      **providers = {aws = "aws.two"}**
      vpc_id     = data.aws_vpc.default.id      # module.vpc2.vpc_id
      subnet_ids = data.aws_subnet_ids.this.ids # module.vpc2.private_subnets

      tgw_routes = [
        {
          destination_cidr_block = "50.0.0.0/16"
        },
        {
          blackhole              = true
          destination_cidr_block = "10.10.10.10/32"
        }
      ]
    },
  }

  ram_allow_external_principals = false
  ram_principals                = [************]

  tags = {
    Purpose = "tgw-complete-example"
  }
}

module "vpc1" {
  providers = {aws = "aws.one"}
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 2.0"
  name = "vpc1"
  cidr = "10.10.0.0/16"
  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"]
  enable_ipv6                                    = true
  private_subnet_assign_ipv6_address_on_creation = true
  private_subnet_ipv6_prefixes                   = [0, 1, 2]
}

module "vpc2" {
  providers = {aws = "aws.two"}
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 2.0"
  name = "vpc2"
  cidr = "10.20.0.0/16"
  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"]
  enable_ipv6 = false
}

Cross Region TGW Peering

Is your request related to a problem? Please describe.

I need to do multi region peering between transit gateway to achieve multi region communication

Describe the solution you'd like.

add support to the modules related to automatically accept the tgw regional sharing,
using aws_ec2_transit_gateway_peering_attachment and aws_ec2_transit_gateway_peering_attachment_accepter,
if possible add the aws_ec2_transit_gateway_route to the requester and acceptor.

Describe alternatives you've considered.

not sure, still didn't know

Additional context

if we can achieve that, its possible to automatically setup multi region network topology in AWS

Version 2.7.0 should be a breaking change

Description

Some of our terraform CI processes began failing over the weekend, this is because of the 2.7.0 release of this module which now explicitly requires AWS provider >= 4.4 as per this commit:

131ed50#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R72

Many of our terraform repos are still locked to V3 so a version constraint mismatch will be reported durng terraform init.

I would have thought, at the very least, this warrants a breaking change note in the release notes - nothing about the AWS provider upgrade is actually listed. Ideally I would suggest this release is re-tagged as v3.0.0

null_resource.wait_for_cluster can run for hours if the endpoint is resolve-able but not accessible

Description

The null_resource wait_for_cluster uses a for loop in the script provided by default via input variable wait_for_cluster_cmd.
The for loop calls both wget and curl without specifying maximum timeouts on their operations meaning that if the cluster endpoint is not accessible, but is DNS resolve-able, to let's say a private IP address because the cluster was configured with a private only endpoint the command will run for.. quite some time. Since for loop iterates a maximum of 60 times, and each command is relying on the default timeouts for wget (900 seconds) and curl (3600 seconds) the resource can sit there for upwards of 60+hrs waiting for the resource to be created. The commands should be altered to include an explicit maximum timeout period to ensure it doesn't sit there attempting to accelerate the heat death of the universe.

For wget this is achieved via the addition of the -t 60 CLI option, and for curl the --max-time 60 CLI option.

Versions

  • Terraform: 0.14.7

Reproduction

Steps to reproduce the behavior:

  • create a VPC with an RFC1918 address block
  • create the minimal EKS cluster as per the example and disable the public endpoint

Code Snippet to Reproduce

Expected behavior

The null_resource creation should fail after 60 (ish) minutes (or less if desired)

Actual behavior

The null_resource continues to try for hours if left to it

Terminal Output Screenshot(s)

module.eks.null_resource.wait_for_cluster: Still creating... [56m40s elapsed]
module.eks.null_resource.wait_for_cluster: Still creating... [56m50s elapsed]
module.eks.null_resource.wait_for_cluster: Still creating... [57m0s elapsed]
module.eks.null_resource.wait_for_cluster: Still creating... [57m10s elapsed]
module.eks.null_resource.wait_for_cluster: Still creating... [57m20s elapsed]

Additional context

RAM resource sharing between accounts fails

When sharing TGW between two accounts in AWS GovCloud, terraform apply has to be executed multiple times before resource sharing is created successfully.

Versions

terraform = v0.13.5
aws provider = v3.2.0
transit-gateway module = 1.3.0

Module settings

Account A

create_tgw = true 
share_tgw = true
ram_allow_external_principals = true
ram_principals = [<account_b>]

Account B

create_tgw = false 
share_tgw = true

First terraform apply shows the following in the output;

module.usgce_tgw.aws_ram_resource_share.this[0]: Creation complete after 1s [id=arn:aws-us-gov:ram:us-gov-east-1:<acct_id>:resource-share/<id>]
module.usgce_tgw_poclab_peer.aws_ram_resource_share_accepter.this[0]: Creating...
module.usgce_tgw.aws_ram_principal_association.this[0]: Creation complete after 1s [id=arn:aws-us-gov:ram:us-gov-east-1:<account_id>:resource-share/<id>]
module.usgce_tgw.aws_ram_resource_association.this[0]: Creation complete after 2s [id=arn:aws-us-gov:ram:us-gov-east-1:<account_id>:resource-share/<id>,arn:aws-us-gov:ec2:us-gov-east-1:<account_id>:transit-gateway/tgw-<id>]

But the apply fails with the following error;

Error: No RAM Resource Share (arn:aws-us-gov:ram:us-gov-east-1:<account_id>:resource-share/<id>) invitation found

Running terraform plan again shows that the resource still needs to be created;

# module.usgce_tgw_poclab_peer.aws_ram_resource_share_accepter.this[0] will be created

Running terraform apply again successfully accepts the pending resources share in the second account but the apply fails with the following error;

Error: error retrieving resource shares: UnknownResourceException: ResourceShare arn:aws-us-gov:ram:us-gov-east-1:<account_id>:resource-share/<id> could not be found.

After running terraform apply two more times the existing share/invitation is deleted and accepted successfully.
First run;

Error: No RAM Resource Share (arn:aws-us-gov:ram:us-gov-east-1:<account_id>:resource-share/<id>) invitation found

Second run;

module.usgce_tgw_poclab_peer.aws_ram_resource_share_accepter.this[0]: Creating...
module.usgce_tgw_poclab_peer.aws_ram_resource_share_accepter.this[0]: Creation complete after 2s [id=arn:aws-us-gov:ram:us-gov-east-1:<account_id>:resource-share/<id>]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Removing Account from "ram_principals" disrupts shared TGW with other accounts

Is your request related to a problem? Please describe.

When you remove an account from the ram_principals, the module will replace the associations and disrupt the current shared TGW by destroying and creating a new resource share.

This problem is related to how the module stores the aws_ram_principal_association in the state.
For example, you have:

module "tgw_use1" {
...
  ram_principals                = [
      "111111111111", #Acct1
      "222222222222", #Acct2
      "333333333333", #Acct3
      "444444444444", #Acct4
      "555555555555", #Acct4
  ]

and you remove the Acct3, the next plan/apply will return:

  # module.tgw_use1.aws_ram_principal_association.this[2] must be replaced
-/+ resource "aws_ram_principal_association" "this" {
      ~ id                 = "arn:aws:ram:us-east-1:<TGW_ACCT>:resource-share/<tgw_ram_resource_share_id>,333333333333" -> (known after apply)
      ~ principal          = "333333333333" -> "444444444444" # forces replacement
        # (1 unchanged attribute hidden)
    }

  # module.tgw_use1.aws_ram_principal_association.this[3] must be replaced
-/+ resource "aws_ram_principal_association" "this" {
      ~ id                 = "arn:aws:ram:us-east-1:<TGW_ACCT>:resource-share/<tgw_ram_resource_share_id>,444444444444" -> (known after apply)
      ~ principal          = "444444444444" -> "555555555555" # forces replacement
        # (1 unchanged attribute hidden)
    }

  # module.tgw_use1.aws_ram_principal_association.this[4] will be destroyed
  # (because index [8] is out of range for count)
  - resource "aws_ram_principal_association" "this" {
      - id                 = "arn:aws:ram:us-east-1:<TGW_ACCT>:resource-share/<tgw_ram_resource_share_id>,555555555555" -> null
      - principal          = "555555555555" -> null
      - resource_share_arn = "arn:aws:ram:us-east-1:<TGW_ACCT>:resource-share/<tgw_ram_resource_share_id>" -> null
    }

Describe the solution you'd like.

Maybe the list index could be replaced to the account number, so when the list is reordered it will nor remove existing shares.

Describe alternatives you've considered.

Manually edit the remote state removing the account and reordering the list.

Additional context

This will happen also if adding an account in the middle of the list.

Use in CDKTF?

Thank you for an outstanding work!

In terraform CDKTF when I create a VPC using, say, python, this results in terraform JSON, which essentially creates an invocation of the terraform VPC module.

In contrast to the above, when I create a TGW in CDKTF an AWS resource is created. Do you know of the plans to replace this with an invocation of this repo module?

Thanks again!

Support (and document) use case for using existing Transit Gateway

Is your request related to a new offering from AWS?

No.

Is your request related to a problem? Please describe.

var.create_tgw short-circuits creation of aws_ec2_transit_gateway_route and prevents using this module when a TGW already exists but the TGW routes should be created:

# List of maps with key and route values
vpc_attachments_with_routes = chunklist(flatten([
for k, v in var.vpc_attachments : setproduct([{ key = k }], v.tgw_routes) if var.create_tgw && can(v.tgw_routes)
]), 2)

This use case is relevant when the Transit Gateway is managed in one configuration / state, but the VPC attachments and their routes are managed elsewhere.

It is not clear if this use case is actually intended to be supported, hence why this issue is a feature request and not a bug report. For example, aws_ec2_transit_gateway_vpc_attachment is created even when var.create_tgw, but as mentioned above, aws_ec2_transit_gateway_route is not. Moreover, this use case is not documented.

transit_gateway_id = var.create_tgw ? aws_ec2_transit_gateway.this[0].id : each.value.tgw_id

Describe the solution you'd like.

Change this logic such that aws_ec2_transit_gateway_route when var.create_tgw is false

Describe alternatives you've considered.

None

Additional context

Tags not propagating

Description

When add a vpc from a different account to the shared transit Gateway there are no tags in the Transit Gateway Attachment

  • [ x] βœ‹ I have searched the open/closed issues and my issue is not listed.

Versions

  • Module version [Required]:
    version = "~> 2.6.0"
  • Terraform version:
    Terraform v1.1.9
  • Provider version(s):
    aws v3.75.2

Reproduction Code [Required]

Steps to reproduce the behavior:

Create tgw in Account A:


module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.6.0"

  name        = var.tgw.name
  description = var.tgw.description
  enable_auto_accept_shared_attachments = true

  # connect other vpcs in their own module
  vpc_attachments = {
    vpc_route = {
      vpc_id       = module.vpc.vpc_id
      subnet_ids   = module.vpc.private_subnets
      dns_support  = true
      ipv6_support = false

      tgw_routes = [
        for cidr in var.tgw.tgw_routes : {
          destination_cidr_block = cidr
        }
      ]
    },
  }

  ram_allow_external_principals = true
  ram_principals                = var.aws_account_id_list

  ram_tags                     = merge(var.tags, var.tgw.name_tags)
  tgw_default_route_table_tags = merge(var.tags, var.tgw.name_tags)
  tgw_route_table_tags         = merge(var.tags, var.tgw.name_tags)
  tgw_tags                     = merge(var.tags, var.tgw.name_tags)
  tgw_vpc_attachment_tags      = merge(var.tags, var.tgw.name_tags)
  tags                         = merge(var.tags, var.tgw.tags)
}

In account B add the vpc


module "tgw" {
  source  = "terraform-aws-modules/transit-gateway/aws"
  version = "~> 2.6.0"

  name = var.tgw.name

  create_tgw             = false
  share_tgw              = false

  vpc_attachments = {
    vpc = {
      tgw_id       = var.tgw.tgw_id
      vpc_id       = module.vpc.vpc_id
      subnet_ids   = module.vpc.private_subnets
      dns_support  = true
      ipv6_support = false

      # transit_gateway_default_route_table_association = false
      # transit_gateway_default_route_table_propagation = false

      tgw_routes = [
        for cidr in var.tgw.tgw_routes : {
          destination_cidr_block = cidr
        }
      ]
    }
  }

  ram_tags                     = merge(var.tags, var.tgw.name_tags)
  tgw_default_route_table_tags = merge(var.tags, var.tgw.name_tags)
  tgw_route_table_tags         = merge(var.tags, var.tgw.name_tags)
  tgw_tags                     = merge(var.tags, var.tgw.name_tags)
  tgw_vpc_attachment_tags      = merge(var.tags, var.tgw.name_tags)
  tags                         = merge(var.tags, var.tgw.tags)
}

common.tfvars

tgw = {
  name                   = "aws-logs-tgw"
  tgw_id                 = "tgw-0xxxxx6"
  tgw_routes             = ["10.40.0.0/16", "10.41.0.0/16", "10.42.0.0/16", "10.43.0.0/16", "10.44.0.0/16", "10.45.0.0/16", "10.46.0.0/16", "10.47.0.0/16"]
  tags = {
    "Name"    = "aws-logs-tgw"
  }
  name_tags = {
    "Name" = "aws-logs-tgw"
  }
}

Expected behavior

Tags to propagate both on account A and Account B

Actual behavior

Account A shows no tags
notags

Account B tags are exisiting
Screen Shot 2022-09-01 at 16 08 53

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.