Aws-cdk: Explain that Vpc.fromLookup cannot use deploy-time values

Created on 9 Aug 2019  路  7Comments  路  Source: aws/aws-cdk

Note: for support questions, please first reference our documentation, then use Stackoverflow. This repository's issues are intended for feature requests and bug reports.

  • I'm submitting a ...

    • [x] :beetle: bug report
    • [ ] :rocket: feature request
    • [ ] :books: construct library gap
    • [ ] :phone: security issue or vulnerability => Please see policy
    • [ ] :question: support request => Please see note at the top of this template.
  • What is the current behavior?
    If the current behavior is a :beetle:bug:beetle:: Please provide the steps to reproduce

class VpcStack(core.Stack):
    def __init__(self, app: core.App, id: str, **kwargs) -> None:
        super().__init__(app, id, **kwargs)
        vpc = aws_ec2.Vpc(scope=self, id='Vpc', cidr=some_cidr))
        core.CfnOutput(
            scope=self,
            id='VpcOutput',
            value=vpc.vpc_id,
            export_name='Vpc'
        )

class OtherStack(core.Stack):
    def __init__(self, app: core.App, id: str, **kwargs) -> None:
        super().__init__(app, id, **kwargs)
        vpc_id = core.Fn.import_value('Vpc')

        aws_s3.Bucket(
            scope=self,
            id='Bucket',
            bucket_name=vpc_id
        )

        vpc = aws_ec2.Vpc.from_lookup(
            scope=self,
            id='Vpc',
            vpc_id=vpc_id
        )

jsii.errors.JSIIError: Invalid context key "vpc-provider:account=***************:filter.vpc-id=${Token[TOKEN.99]}:region=eu-west-1". It contains unresolved tokens

Bucket resolves fine and inherits name from vpc_id. The vpc is not imported though.

  • What is the expected behavior (or behavior of feature suggested)?
    Vpc.from_lookup imports vpc from the output

  • What is the motivation / use case for changing the behavior or adding this feature?
    I cannot import existing vpc without hardcoding id

  • Please tell us about your environment:

    • CDK CLI Version: 1.1.0
    • Module Version: 1.1.0
    • OS: [all]
    • Language: [all]
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. associated pull-request, stackoverflow, gitter, etc)

@aws-cdaws-ec2 bug good first issue

Most helpful comment

Sorry to be calling attention to an old issue, but what is the recommended way of reusing a vpc without having to hard code the vpc id. It seems like a very common use case, and using name tags for fromLookup works, but also feels fragile since name tags don't have to be unique.

All 7 comments

This use case in currently not supported. It's not possible to use fromLookup with a VPCID that is not available during synthesis. Fn.importValue is only resolved during deployment and therefore it is represented as a token when you call fromLookup.

Since you define the VPC stack in the same app as your other stack, why do you even need to export/import the VPC. As long as these two stacks are deployed within the same account/region, you can freely cross-reference them, and the CDK will take care of exporting/import values as needed:

In your case:

class VpcStack(core.Stack):
    def __init__(self, app: core.App, id: str, **kwargs) -> None:
        super().__init__(app, id, **kwargs)
        vpc = aws_ec2.Vpc(scope=self, id='Vpc', cidr=some_cidr))

        self.vpc = vpc

class OtherStack(core.Stack):
    def __init__(self, app: core.App, id: str, vpc: aws_ec2.Vpc, **kwargs) -> None:
        super().__init__(app, id, **kwargs)

        aws_s3.Bucket(
            scope=self,
            id='Bucket',
            bucket_name=vpc.vpc_id
        )

# this is how you "wire" them
app = App()
vpc_stack = VpcStack(app, 'vpc-stack')
OtherStack(app, 'other-stack', vpc_stack.vpc)

@rix0rrr, let's add some more details in the documentation of fromVpc to make this clear and also provide this example.

Sorry to be calling attention to an old issue, but what is the recommended way of reusing a vpc without having to hard code the vpc id. It seems like a very common use case, and using name tags for fromLookup works, but also feels fragile since name tags don't have to be unique.

There's a similar vpc lookup in the apigateway cdk library that effectively works the way you would expect it to by supplying a vpcid and then getting the interface api gateway expects. Why doesn't this work for this ec2 library the same way?

I'm able to use a map lookup to get the vpc id for the environment I'm running. See code snippet below.

import { VpcLink } from '@aws-cdk/aws-apigateway';

VpcLink.fromVpcLinkId(this, 'vpcLink', stageNames.findInMap(stageParam.valueAsString, 'vpcLink'));

I'm trying to use this when creating an ecs cluster, but ecs expects the vpc interface from the EC2 library instead of apigateway, and as stated above I can't use something like a map to do this lookup using the ec2 version, it has to be a static value.

Question remains, why does this work the way you would expect using dynamic properties when using the api gateway version but not the EC2 version?

@eladb I'll add my voice to this request. My use case is the following:

  • create a VPC and some other infrastructure in one stack
  • create multiple stacks on top of that stack which put additional resources into the above VPC

I don't want to manually pass the VPC ID around and hard code it in any scripts to be as flexible as possible.

So, I would very much like to store the VPC ID in the SSM parameter store from the first stack and then retrieve it from the SSM parameter store in other stacks that need the VPC ID.

The storing and retrieval is actually not a problem, but I can't "hydrate" a VPC from the VPC ID alone, because of the error All arguments to Vpc.fromLookup() must be concrete (no Tokens).

@thombergs

I was able to get your use-case to work using StringParameter.valueFromLookup although this does require that "the stack must be synthesized with explicit account and region information" - link

@silversteez I'm passing around the VPC ID with StringParameters now, too. But when I'm trying calling Vpc.fromLookup() with the VPC ID loaded from the StringParameter, I get above error. My stacks do have a specific account and region.

This is all the more important now in 1.73.0 where there is a elbv2.ApplicationLoadBalancer.fromLookup function. To look up the ALB using the ARN it would be great to use the exported value.

Was this page helpful?
0 / 5 - 0 ratings