Solve: When Your Transit Gateway Attachment Stalls—Solving the PendingAcceptance Trap in AWS CloudFormation


Solve: When Your Transit Gateway Attachment Stalls—Solving the PendingAcceptance Trap in AWS CloudFormation








The Mystery of the Stalled Attachment

Late one night, a cloud engineer ran into a frustrating issue: a VPC attachment to their AWS Transit Gateway (TGW) was stuck in the PendingAcceptance state. There was no obvious console option to accept it, and CloudTrail revealed a cryptic InvalidInputException linked to a duplicate AWSServiceRoleForVPCTransitGateway. If you've hit this combination of symptoms, you're not alone.

This article unpacks what went wrong, how to fix it, and how to future-proof your CloudFormation templates from encountering the same trap. Whether you're working across accounts or just running redeploys, this is a scenario worth preparing for.


Understanding the Root Cause

The error surfaced because the Transit Gateway had auto-accept disabled, meaning attachments must be accepted manually. That's fine in theory—but in this case, the expected "Accept Attachment" action never appeared in the AWS Console. Meanwhile, CloudTrail showed the real villain: a service-linked role conflict. AWS only allows one AWSServiceRoleForVPCTransitGateway per account, and CloudFormation doesn't always check before attempting to recreate it.

The result? CloudFormation stalls, the attachment gets stuck, and you're left scratching your head.


Two Fixes That Work

First, resolve the role conflict. Head to the IAM console and confirm whether the service-linked role exists. If it's orphaned, delete and let AWS recreate it naturally. You can also use CLI commands like aws iam list-roles to inspect what's there. Once the role situation is clean, the TGW logic can proceed as intended.

Second, manually accept the attachment—but use the AWS CLI instead of the console. Permissions or UI inconsistencies often block the action visually. Run this command from the TGW owner account:

Bash
aws ec2 accept-transit-gateway-vpc-attachment \
  --transit-gateway-attachment-id tgw-attach-xxxxxxxx \
  --region us-east-1   

That should move the attachment out of limbo.


CloudFormation Templates: Avoid the Role Altogether

To prevent this from happening again, keep your CloudFormation templates clean and minimal. There's no need to explicitly define the AWS::IAM::ServiceLinkedRole for TGW unless you have a custom need.

You can find the full template and companion CLI scripts in this GitHub Gist:

Here's a safe example that lets AWS handle the service-linked role creation implicitly:

Bash
Resources:
  MyTransitGateway:
    Type: AWS::EC2::TransitGateway
    Properties:
      AmazonSideAsn: 64512
      AutoAcceptSharedAttachments: disable
      DefaultRouteTableAssociation: enable
      DefaultRouteTablePropagation: enable
      Tags:
        - Key: Name
          Value: my-tgw

  MyTGWAttachment:
    Type: AWS::EC2::TransitGatewayAttachment
    Properties:
      TransitGatewayId: !Ref MyTransitGateway
      VpcId: !Ref MyVPC
      SubnetIds:
        - !Ref MySubnetA
        - !Ref MySubnetB
      Tags:
        - Key: Name
          Value: my-tgw-attachment   


Engineer’s Journal: How This Surfaced in the Wild

This issue came to light during a late-night troubleshooting exchange. The attachment was hanging, the console wasn’t offering an option to accept it, and CloudFormation was throwing vague errors. As we unpacked the problem, it became clear that it wasn’t just one misstep—it was the convergence of a missing service-linked role, a misleading UI, and unclear error messaging.

That kind of multi-layered trap is exactly why documenting the fix matters. This wasn’t a one-off blip—it’s the kind of edge case that can quietly wreck your deployment pipeline. The real win here was not just fixing it in the moment, but turning that experience into reusable knowledge for the rest of us.


Conclusion: A Hidden but Preventable Pitfall

This issue can be easy to miss—especially during off-hours troubleshooting or in cross-account setups—but it's fully resolvable with the right mix of role hygiene, CLI skills, and CloudFormation best practices. AWS will likely improve the developer experience over time, but until then, it's up to us to document these edge cases and build smarter IaC.

Bookmark this one, and share it with your teammates the next time TGW attachments misbehave.

If this helped you or someone on your team, we’d love to hear about it—drop a note or share the post to help others steer clear of this gotcha.


Need AWS Expertise?

We'd love to help you with your AWS projects.  Feel free to reach out to us at info@pacificw.com.


Written by Aaron Rose, software engineer and technology writer at Tech-Reader.blog.

Comments

Popular posts from this blog

The New ChatGPT Reason Feature: What It Is and Why You Should Use It

Raspberry Pi Connect vs. RealVNC: A Comprehensive Comparison

The Reasoning Chain in DeepSeek R1: A Glimpse into AI’s Thought Process