How to create VPC that can be shared across stacks?

霸气de小男生 提交于 2020-08-22 10:54:14

问题


I am trying to wrap my head around how to create a reusable VPC that can be used across multiple stacks using AWS CDK. I want to be able to create different stack per project and then be able to import the VPC that should be assigned to the different stacks. I also want to create this using a good structure where I can deploy different stacks at different times (meaning: I do not want to deploy all stacks at once).

I have tried the following approach but this will create a new VPC per stack which is not what I want to achieve, instead I would like to create my VPC once and then if it already exists it will simply reuse the previous created.

app.ts

import cdk = require('@aws-cdk/core');
import { Stack1 } from '../lib/stack1';
import { Stack2 } from '../lib/stack2';

const app = new cdk.App();

new Stack1(app, "Stack1");
new Stack2(app, "Stack2");

stack1.ts

import cdk = require('@aws-cdk/core');

import { Configurator } from './configurators/configurator'

export class Stack1 extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const configurator = new Configurator(scope, "Stack1");

    // later reuse vpc from configurator using configurator.vpc
  }
}

stack2.ts

import cdk = require('@aws-cdk/core');

import { Configurator } from './configurators/configurator'

export class Stack2 extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const configurator = new Configurator(scope, "Stack2");

    // later reuse vpc from configurator using configurator.vpc
  }
}

configurator.ts

import cdk = require('@aws-cdk/core');
import ec2 = require("@aws-cdk/aws-ec2");

export class Configurator {

  vpc: ec2.Vpc;

  constructor(scope: cdk.Construct, name: string) {
    this.vpc = new ec2.Vpc(scope, "MyVPC", {
      maxAzs: 3
    });
  }
}

After doing

cdk synth
cdk deploy Stack1
cdk deploy Stack2

This will create 2 VPCs and not reusing 1 VPC as I would like. I will deploy the stacks to same account and region.

How can I change my approach in order to achieve the output I am looking for? I want to be able to deploy my stacks independently of each other.


回答1:


If you intend to reuse the VPC in different stacks, I'd recommend placing it in a separate stack, since your VPC stack will have a different lifecycle than your application stacks.

Here's what I'd do. I hope you don't mind a bit of Python :)

First, define your VPC in VpcStack:

class VpcStack(core.Stack):
    def __init__(self, app: core.App, id: str, **kwargs) -> None:
        super().__init__(app, id, **kwargs)
        aws_ec2.Vpc(self, 'MyVPC', max_azs=3)

Then look it up in another stack:

class Stack1(core.Stack):
    def __init__(self, app: core.App, id: str, **kwargs) -> None:
        super().__init__(app, id, **kwargs)
        # Lookup the VPC named 'MyVPC' created in stack 'vpc-stack'
        my_vpc = aws_ec2.Vpc.from_lookup(self, 'MyVPC', vpc_name=f'vpc-stack/MyVPC')
        # You can now use the VPC in ECS cluster, etc.

And this would be your cdk_app.py:

app = core.App()
vpc = VpcStack(app, 'vpc-stack')
stack1 = Stack1(app, 'stack1')



回答2:


I tried 0x32e0edfb answer and got some problem. so I fix like this.

VPC Stack

class VpcStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        self.eks_vpc = ec2.Vpc(self, 'eks-vpc',
            cidr='10.1.0.0/16',
            max_azs=2
        )

share VPC to other Stack

class EksClusterStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, props: ec2.Vpc, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        cluster = eks.Cluster(self, 'eks-control-plane',
            vpc=props,
            default_capacity=0
        )

and then app.py file

app = core.App()

vpc_stack = VpcStack(app, 'vpc-stack')
eks_cluster_stack = EksClusterStack(app, 'eks-cluster', vpc_stack.eks_vpc)

eks_cluster_stack.add_dependency(vpc_stack)

app.synth()

from_lookup is much better used on already existing VPC.

so I choose to use share-vpcs to share VPC information.

from_lookup only does the API call once - then, the data is cached in the cdk.context.json file, which should be committed to source control

That problem was when I recreating the same VPC.

cdk.context.json didn't update to lasted version. So when I use from_lookup always get old vpc-id.

I need to use cdk context --clear command and then deploy again. cdk.context.json would get lasted version vpc-id.

Finally, it can work properly on from_lookup method.

ref: https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-eks/test/integ.eks-kubectl.lit.ts

https://docs.aws.amazon.com/cdk/latest/guide/context.html



来源:https://stackoverflow.com/questions/57623766/how-to-create-vpc-that-can-be-shared-across-stacks

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!