Skip to content

how to set up auto acceptance for the transit gateway peering attachment with CDK?

0

I'm working with CDK TypeScript to create an network setup that includes:

  • Two VPCs
  • Two Transit Gateways (TGWs)
  • TGW peering between these gateways

Even though I've set 'autoAcceptSharedAttachments' on the TGWs, the peering attachment still requires manual acceptance.

How can I implement automatic acceptance of Transit Gateway peering attachments using AWS CDK TypeScript? I've noticed that Pulumi offers this functionality through 'aws.ec2transitgateway.PeeringAttachmentAccepter', and I'm looking for an equivalent solution in CDK.

While AWS provides official sample code demonstrating TGW peering using CDK, but this solution still requires manual step for acceptance.

Below is my code snippet for reference:

    // Create VPC 1
    const vpc1 = new ec2.Vpc(this, 'VPC1', {
      maxAzs: 2,
      ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
        }
      ],
    });

    // Create VPC 2
    const vpc2 = new ec2.Vpc(this, 'VPC2', {
      maxAzs: 2,
      ipAddresses: ec2.IpAddresses.cidr('172.16.0.0/16'),
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
        }
      ],
    });

    // Create Transit Gateway 1
    const tgw1 = new ec2.CfnTransitGateway(this, 'TransitGateway1', {
      amazonSideAsn: 64512,
      autoAcceptSharedAttachments: 'enable',
      defaultRouteTableAssociation: 'enable',
      defaultRouteTablePropagation: 'enable',
      tags: [{ key: 'Name', value: 'TGW1' }],
    });

    // Create Transit Gateway 2
    const tgw2 = new ec2.CfnTransitGateway(this, 'TransitGateway2', {
      amazonSideAsn: 64513,
      autoAcceptSharedAttachments: 'enable',
      defaultRouteTableAssociation: 'enable',
      defaultRouteTablePropagation: 'enable',
      tags: [{ key: 'Name', value: 'TGW2' }],
    });

    // Attach VPC1 to TGW1
    const vpc1TgwAttachment = new ec2.CfnTransitGatewayAttachment(this, 'VPC1TGWAttachment', {
      transitGatewayId: tgw1.ref,
      vpcId: vpc1.vpcId,
      subnetIds: vpc1.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }).subnetIds,
      tags: [{ key: 'Name', value: 'VPC1-TGW1-Attachment' }],
    });

    // Attach VPC2 to TGW2
    const vpc2TgwAttachment = new ec2.CfnTransitGatewayAttachment(this, 'VPC2TGWAttachment', {
      transitGatewayId: tgw2.ref,
      vpcId: vpc2.vpcId,
      subnetIds: vpc2.selectSubnets({ subnetType: ec2.SubnetType.PUBLIC }).subnetIds,
      tags: [{ key: 'Name', value: 'VPC2-TGW2-Attachment' }],
    });

    // Create Transit Gateway Peering Connection
    const tgwPeering = new ec2.CfnTransitGatewayPeeringAttachment(this, 'TGWPeering', {
      transitGatewayId: tgw1.ref,
      peerTransitGatewayId: tgw2.ref,
      peerRegion: this.region,
      peerAccountId: this.account,
      tags: [{ key: 'Name', value: 'TGW1-TGW2-Peering' }],
    });
1 Answer
0

To set up automatic acceptance for transit gateway peering attachments using AWS CDK TypeScript, you'll need to implement a custom solution as there isn't a built-in CDK construct for this specific functionality. Here's an approach you can take:

  1. Create the transit gateway peering attachment as you've done in your existing code.

  2. Use a Custom Resource with a Lambda function to automatically accept the peering attachment. The Lambda function will use the AWS SDK to call the acceptTransitGatewayPeeringAttachment API.

  3. Add a dependency to ensure the Custom Resource is created after the peering attachment.

Here's how you can modify your existing code to implement this:

  1. First, create a Lambda function that will accept the peering attachment:
const acceptPeeringFunction = new lambda.Function(this, 'AcceptPeeringFunction', {
  runtime: lambda.Runtime.NODEJS_14_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('lambda'),
  timeout: Duration.seconds(30),
  role: new iam.Role(this, 'AcceptPeeringFunctionRole', {
    assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
    managedPolicies: [
      iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
    ],
  }),
});

acceptPeeringFunction.addToRolePolicy(new iam.PolicyStatement({
  actions: ['ec2:AcceptTransitGatewayPeeringAttachment'],
  resources: ['*'],
}));
  1. Create a Custom Resource that uses this Lambda function:
const acceptPeeringCustomResource = new CustomResource(this, 'AcceptPeeringCustomResource', {
  serviceToken: acceptPeeringFunction.functionArn,
  properties: {
    TransitGatewayAttachmentId: tgwPeering.attrTransitGatewayAttachmentId,
  },
});
  1. Add a dependency to ensure the Custom Resource is created after the peering attachment:
acceptPeeringCustomResource.node.addDependency(tgwPeering);
  1. Implement the Lambda function (in a separate file, e.g., 'lambda/index.js'):
const AWS = require('aws-sdk');

exports.handler = async (event, context) => {
  const ec2 = new AWS.EC2();
  const { TransitGatewayAttachmentId } = event.ResourceProperties;

  if (event.RequestType === 'Create' || event.RequestType === 'Update') {
    try {
      await ec2.acceptTransitGatewayPeeringAttachment({ TransitGatewayAttachmentId }).promise();
      return { PhysicalResourceId: TransitGatewayAttachmentId, Data: { Message: 'Peering attachment accepted' } };
    } catch (error) {
      throw new Error(`Failed to accept peering attachment: ${error.message}`);
    }
  } else if (event.RequestType === 'Delete') {
    // No action needed on delete
    return { PhysicalResourceId: TransitGatewayAttachmentId };
  }
};

This solution creates a Custom Resource that uses a Lambda function to automatically accept the transit gateway peering attachment. The Lambda function is triggered when the Custom Resource is created or updated, and it calls the acceptTransitGatewayPeeringAttachment API to accept the peering attachment.

Remember to handle error cases and ensure proper IAM permissions are set for the Lambda function to interact with EC2 services. Also, note that this approach assumes both transit gateways are in the same AWS account and region. If they're in different accounts or regions, you'll need to adjust the Lambda function accordingly.
Sources
Amazon EC2 examples using AWS CLI - AWS SDK Code Examples
AcceptTransitGatewayPeeringAttachment - Amazon Elastic Compute Cloud
interface CfnTransitGatewayPeeringAttachmentProps · AWS CDK

answered 2 years ago

EXPERT

reviewed 2 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.