Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explain that Vpc.fromLookup cannot use deploy-time values #3600

Closed
1 of 5 tasks
lkoniecz opened this issue Aug 9, 2019 · 19 comments · Fixed by #3740
Closed
1 of 5 tasks

Explain that Vpc.fromLookup cannot use deploy-time values #3600

lkoniecz opened this issue Aug 9, 2019 · 19 comments · Fixed by #3740
Assignees
Labels
@aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud bug This issue is a bug. good first issue Related to contributions. See CONTRIBUTING.md

Comments

@lkoniecz
Copy link

lkoniecz commented Aug 9, 2019

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 ...

    • 🪲 bug report
    • 🚀 feature request
    • 📚 construct library gap
    • ☎️ security issue or vulnerability => Please see policy
    • ❓ support request => Please see note at the top of this template.
  • What is the current behavior?
    If the current behavior is a 🪲bug🪲: 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)

@lkoniecz lkoniecz added the needs-triage This issue or PR still needs to be triaged. label Aug 9, 2019
@eladb eladb added @aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud and removed needs-triage This issue or PR still needs to be triaged. labels Aug 12, 2019
@eladb
Copy link
Contributor

eladb commented Aug 12, 2019

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.

@eladb eladb changed the title Vpc.fromLookup cannot import vpc from stack output Explain that Vpc.fromLookup cannot use deploy-time values Aug 12, 2019
@eladb eladb added the bug This issue is a bug. label Aug 12, 2019
@rix0rrr rix0rrr added the good first issue Related to contributions. See CONTRIBUTING.md label Aug 19, 2019
rix0rrr added a commit that referenced this issue Aug 21, 2019
`fromLookup()` will not support lazy values. Throw a clear
error message when that is done, and update the documentation
to make it clear what should be done instead.

Fixes #3600.
@mergify mergify bot closed this as completed in #3740 Aug 21, 2019
mergify bot pushed a commit that referenced this issue Aug 21, 2019
`fromLookup()` will not support lazy values. Throw a clear
error message when that is done, and update the documentation
to make it clear what should be done instead.

Fixes #3600.
@corrjo
Copy link

corrjo commented May 1, 2020

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.

@trevorhileyrw
Copy link

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?

@thombergs
Copy link

thombergs commented Oct 4, 2020

@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).

@silversteez
Copy link

@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

@thombergs
Copy 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.

@AlJohri
Copy link

AlJohri commented Nov 13, 2020

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.

@vsetka
Copy link

vsetka commented Jan 6, 2021

Any update on this? I'm having the exact same issue as @thombergs

I have done the same type of reuse in other stacks (storing an IAM role arn, reading it in a different stack and creating the role from the arn).

@flabat
Copy link

flabat commented Jan 8, 2021

@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

I am still not able to use StringParameter, even when specifying region and account info

@mimozell
Copy link

I'm having the same issue with different modules when creating linked stacks. I tried to ask for guidance here but haven't gotten any responses so far.

@arpowers
Copy link

arpowers commented Jan 23, 2021

@eladb the need to cross-reference stacks forces us to run the entire set of stacks every single time we want to deploy. The use case here is we should be able to run a single stack (for example, to update an ECS image or deploy to an S3 bucket) without waiting for all the other stacks to run.

If there really is a technical reason for this, would it work to get SSM values via the SDK?

@alimeerutech
Copy link

alimeerutech commented Feb 22, 2021

the issue for me was cdk.context.json had beed .gitignored and cdk diff was not creating it a simple cdk synth solved the problem

@daniel-refahi
Copy link

my use case: there are some old env created via terraform and I'm adding new services using CDK. so I need to bring in VPC id as parameters.

@waterytowers
Copy link

Not sure why this has not moved? A standard way to deploy resources is to import a VPC from an existing cf deploy. This is a mandatory thing. I guess for now I will need to hard code the string using an if condition to select the relevant vpc id.

@namedgraph
Copy link

I have a CDK stack that I'm using to build a CF template for our AWS Marketplace product. Naturally I cannot hardcode a VPC ID, I can only receive it from the user via a CF parameter. So how do I use it to lookup a VPC instance if fromLookup() cannot be used with a parameter value?

@realugbun
Copy link

realugbun commented Jan 7, 2022

I have lambdas that need to be on the same VPC as an RDS but the VPC was created on another stack. Here is how I handled it.

Stack 1 with RDS:

const vpc = new ec2.Vpc();
cdk.Aspects.of(vpc).add(new cdk.Tag('rds-lambda-vpc', 'true'))

Stack 2 with Lambda:

export function GetRDSVPC(scope: cdk.Stack): ec2.IVpc {

    const vpc = ec2.Vpc.fromLookup(scope, 'ImportVPC',{
        isDefault: false,
        tags: {
            "rds-lambda-vpc": "true"
        },
        subnetGroupNameTag: "Private subnet"
    });

    return vpc;
}

@DavidArmendariz
Copy link

Thank you @raelugbun, that worked for me.

@vikramaditya234
Copy link

Can we get this fixed so we can use vpcId as import value? In the current form it does provide the same support as other CDK libraries does

@MazenAlkhatib
Copy link

For people who are using SSM, be sure to use the correct function so you don't run into the same error. According to CDK v2 docs:
https://docs.aws.amazon.com/cdk/v2/guide/get_ssm_value.html
For synth time we should use valueFromLookup but it has a downside that the values will be visible in the template in AWS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-ec2 Related to Amazon Elastic Compute Cloud bug This issue is a bug. good first issue Related to contributions. See CONTRIBUTING.md
Projects
None yet
Development

Successfully merging a pull request may close this issue.