Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create VPC that can be shared across stacks?

Tags:

aws-cdk

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.

like image 514
alkesos Avatar asked Aug 23 '19 09:08

alkesos


People also ask

Can VPC be shared across accounts?

VPC sharing allows multiple AWS accounts to create their application resources, such as Amazon EC2 instances, Amazon Relational Database Service (RDS) databases, Amazon Redshift clusters, and AWS Lambda functions, into shared, centrally-managed virtual private clouds (VPCs).

Can AWS VPC span across regions?

Yes. Instances in one region can communicate with each other using Inter-Region VPC Peering, public IP addresses, NAT gateway, NAT instances, VPN Connections or Direct Connect connections.

Which is the most optimal way of privately sharing data between the two VPCs?

VPC Peering: This is probably the most common solution to something like this, I would set up two dedicated gateway EC2 instances in each VPC with VPC Peering. All communication is set up through these EC2 instances.

What is a shared service VPC?

Shared VPC allows an organization to connect resources from multiple projects to a common Virtual Private Cloud (VPC) network, so that they can communicate with each other securely and efficiently using internal IPs from that network.


1 Answers

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

like image 99
RicoChen Avatar answered Oct 02 '22 15:10

RicoChen