Hello,
typescript. I have an existing stack (non CDK, provisioned via aws cli). The stack has VCP resource and it is exported so that other stacks could use it.
aws cloudformation describe-stacks --stack-name network --query 'Stacks[*].Outputs[?ExportName==`VPC`]'
[
[
{
"OutputKey": "VpcOutput",
"OutputValue": "vpc-0d9c4bf811814d8f7",
"Description": "The ID of VPC",
"ExportName": "VPC"
}
]
]
How can I import it and pass it to CDK so that it can be used as an input parameter to any construct that requires VPC?
thanks
You can import the VPC e.g. like:
const vpc = Vpc.fromVpcAttributes(this, 'VPC', {
vpcId: Fn.importValue('VPC'),
availabilityZones: ['eu-central-1a', 'eu-central-1b', 'eu-central-1c'],
publicSubnetIds: [
Fn.importValue('Public-SubnetA'),
Fn.importValue('Public-SubnetB'),
Fn.importValue('Public-SubnetC'),
],
});
@hoegertn
Thanks for the reply. I don't quite understand why would I ever need availibity zones or subnets. Isn't unique VPC id enough to target an existing VPC?
This is at least how https://docs.aws.amazon.com/cli/latest/reference/ec2/create-security-group.html (and all SDks I have worked with) and cloudformation work, where VPC id is all they need.
regards
@lkoniecz if you look at the VpcAttributes interface (source), it seems that vpcId and at least the availabilityZones are required fields. The azs聽are passed to ImportSubnetGroup in the ImportedVpc constructor used in the fromVpcAttributes you used. Now, in ImportSubnetGroup constructor (source) it seems no default are assigned to azs. So, if you remove them - by also modifying the interface accordingly - I think the check in the line after will throw an error. OTOH, an import method (source) seems to be already implemented to map subnets to azs. Still, you have to pass the subnets in this case, so you only shift the problem to another field.
Possible solution: if you move back to vpc.ts - source there's a method called fromLookup at line 676 that (quote) imports an existing VPC from by querying the AWS environment this stack is deployed to. I don't know if this fits your use case, but this method seems to accepts VpcLookupOptions that are passed to VpcNetworkProvider (source)... that seems to be the right resource to discover and import existing VPCs (not only by vpcId, but maybe even by name).
@lkoniecz the moment you want to do something meaningful with your VPC you need subnets too, like starting an EC2, Container, RDS, etc....
That is why the VPC object needs them too.
Maybe this could help as well #1429
Hi @lkoniecz!
I wanted to check in to see if you had your issue resolved? Since we are moving all guidance questions over to Stack Overflow, I would like to close out this issue.
@hoegertn - I am afraid I completely don't undestand your statement. Say, I have 1 VPC and 3 subnets within the VPC. What if I pass only 2 subnets to 'fromVpcAttributes'? Did I create a semi-constructed object? How does VPC imported with az1 and az2 differ from VPC with az3 and az4?
@NGL321 - I managed to reuse existing VPC, but I had to pass some meaningless attributes there were never used by the resource that needed the VPC. Go ahead and close it.
As I understand it, you should import the VPC with all available properties. So all public and private subnets. So the object behaves as if everything was created using CDK.
I am closing the issue, but please feel free to continue the conversation either here, in our Gitter, or on Stack Overflow!
@hoegertn may I ask how did you export the subnet IDs via CDK?
I tried
new CfnOutput(this, 'OutputIsolatedSubnet2Id', {
value: this.vpc.isolatedSubnets[1].subnetId,
exportName: 'IsolatedSubnet2Id',
})
But got error message Cannot read property 'subnetId' of undefined
Seems vpc.isolatedSubnets is only a placeholder on client side. And I am not sure how I could guarantee the order of the subnets.
I created the VPC and the exports using plain CloudFormation
Possible solution: if you move back to
vpc.ts- source there's a method calledfromLookupat line 676 that (quote) _imports an existing VPC from by querying the AWS environment this stack is deployed to._ I don't know if this fits your use case, but this method seems to acceptsVpcLookupOptionsthat are passed toVpcNetworkProvider(source)... that seems to be the right resource to discover and import existing VPCs (not only by _vpcId_, but maybe even by name).
fromLookup() won't work unless you hard-code the value as an actual String. This means you can't use the output of another stack (e.g. via SSM) with fromLookup().
If you attempt to use a Token (e.g. the result of an SSM lookup), you get the following error:
All arguments to Vpc.fromLookup() must be concrete (no Tokens)
Subprocess exited with error 1
Error: Subprocess exited with error 1
at ChildProcess.<anonymous> (/usr/local/lib/node_modules/aws-cdk/lib/api/cxapp/exec.ts:118:23)
at ChildProcess.emit (events.js:311:20)
at ChildProcess.EventEmitter.emit (domain.js:482:12)
at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
I am still at a loss as to how to create a Vpc in one stack and use it in an another - in particular a stack that is isolated. I cannot find a working example.
Most helpful comment
@hoegertn
Thanks for the reply. I don't quite understand why would I ever need availibity zones or subnets. Isn't unique VPC id enough to target an existing VPC?
This is at least how https://docs.aws.amazon.com/cli/latest/reference/ec2/create-security-group.html (and all SDks I have worked with) and cloudformation work, where VPC id is all they need.
regards