3

I'm trying to set up a multi-account environment with VPC peering using AWS CDK (type script), but I'm facing some issues when trying to set up related routing tables.

I'm working on Account A which is the ops environment, that is trusted by target-environment Account B (trusted for both - deployment and lookup), as stated in CDK Bootstrap.

I've tried two approaches:

I) First Approach

1) stack executed on ops-env (Account A):

  • Create VPC A
  • Create peer role containing inter alia the following permissions: ec2:AcceptVpcPeeringConnection , ec2:ModifyVpcPeeringConnectionOptions, ec2:CreateRoute. The role can be assumed by target env Account B Principal.

2) stack executed on target-env (Account B):

  • Create VPC B
  • Create VPC Peering with peer role created in stack 1) so that it can be accepted
  • Create Route Table (using CfnRoute) on all subnets of VPC B with VPC A CIDR

3) stack executed on ops-env (Account A) again:

  • Create Route Table (using CfnRoute) on all subnets of VPC A with VPC B CIDR

This however won't even synth because of stack 3) - I have to pass resources created in stack 2) (mainly target-env VPC CIDR), which cannot be done because of:

Cross stack references are only supported for stacks deployed to the same account or between nested stacks and their parent stack

II) Second Approach

The main difference is that there's no stack 3, rather I use lambda functions in stack 2 (executed on Account B) to create route tables on Account A (cross-account lambda call):

1) stack executed on ops-env (Account A):

  • Create VPC A
  • Create peer role containing inter alia the following permissions: ec2:AcceptVpcPeeringConnection , ec2:ModifyVpcPeeringConnectionOptions, ec2:CreateRoute. The role can be assumed by target env Account B Principal.

2) stack executed on target-env (Account B):

  • Create VPC B
  • Create VPC Peering with peer role created in stack 1) so that it can be accepted
  • Create Route Table (using CfnRoute) on all subnets of VPC B with VPC A CIDR
  • Create CustomResource AwsSdkCall that executes EC2:createRoute with assumed peer role (the exact CDK construct below).

However, I get the following error from the Custom Resource:

Received response status [FAILED] from custom resource. Message returned: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1

If I do it without assuming the peer role, I get (which makes sense):

Received response status [FAILED] from custom resource. Message returned: User [ACCOUNT_B_ID] does not have permission to modify the accepter side peering options

What's the right approach here ?

CDK cross-account ec2.createRoute construct:

const onCreate: custom_resources.AwsSdkCall = {
            service: "EC2",
            action: "createRoute",
            assumedRoleArn: props.role?.roleArn,
            parameters: {
                RouteTableId: props.routeTableId,
                DestinationCidrBlock: props.destinationCidrBlock,
                VpcPeeringConnectionId: props.vpcPeeringConnectionId
            },
            physicalResourceId: custom_resources.PhysicalResourceId.of(`createRoute:${props.vpcPeeringConnectionId}`),
        };
        const onUpdate = onCreate;
        const onDelete: custom_resources.AwsSdkCall = {
            service: "EC2",
            action: "deleteRoute",
            assumedRoleArn: props.role?.roleArn,
            parameters: {
                RouteTableId: props.routeTableId,
                DestinationCidrBlock: props.destinationCidrBlock,
            },
        };
        const customResource = new custom_resources.AwsCustomResource(this, "create", {
            policy: custom_resources.AwsCustomResourcePolicy.fromStatements([
                new PolicyStatement({
                    effect: Effect.ALLOW,
                    resources: ["*"],
                    actions: [
                        "ec2:CreateRoute",
                        "ec2:DeleteRoute"
                    ]
                }),
            ]),
            logRetention: RetentionDays.ONE_DAY,
            onCreate,
            onUpdate,
            onDelete,
            installLatestAwsSdk: false
        });
qwertasek
  • 33
  • 3
  • For those coming to this question because of "Cross stack references are only supported for stacks deployed to the same account or between nested stacks and their parent stack", make sure you're setting the same environment/region to both stacks. I'm my case I was missing the `env` stack property on the dependent stack. – Rafael Leite Jun 24 '23 at 21:05

0 Answers0