最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to configure AWS CDK Account and Region to look up a VPC - Stack Overflow

programmeradmin0浏览0评论

I am learning the AWS CDK, and this is a problem I can't seem to figure out. JS/Node are not languages I use often, so if there is some obvious native thing that I am missing, please don't be too harsh. I'm trying to deploy a container to an existing VPC / new ECS Cluster. The following code isn't my whole script but is an important part. Hopefully, it gives the idea of what I'm trying to do.

//import everything first

stack_name = "frontend";

class Frontend extends core.Stack {
constructor(scope, id, props = {}) {
    super(scope, id);

    console.log("env variable " + JSON.stringify(props));
    
    const base_platform = new BasePlatform(this, id, props);

    //this bit doesn't matter, I'm just showing the functions I'm calling to set everything up

    const fargate_load_balanced_service = ecs_patterns.ApplicationLoadBalancedFargateService();
    this.fargate_load_balanced_service.taskDefinition.addToTaskRolePolicy();
    this.fargate_load_balanced_service.service.connections.allowTo();
    const autoscale = this.fargate_load_balanced_service.service.autoScaleTaskCount({});
    this.autoscale.scale_on_cpu_utilization();
    }
}

class BasePlatform extends core.Construct {
constructor(scope, id, props = {}) {
    super(scope, id);
    this.environment_name="frontend";
    
    console.log("environment variables " + JSON.stringify(process.env));

    //This bit is my problem child

    const vpc = ec2.Vpc.fromLookup(
        this, "VPC",{
        vpcId: 'vpc-##########'
    });

    //this bit doesn't matter, I'm just showing the functions I'm calling to set everything up

    const sd_namespace = service_discovery.PrivateDnsNamespace.from_private_dns_namespace_attributes();
    const ecs_cluster = ecs.Cluster.from_cluster_attributes();
    const services_sec_grp = ec2.SecurityGroup.from_security_group_id();
    }
}

const app = new core.App();

_env = {account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION };

new Frontend(app, stack_name, {env: _env});

app.synth();

When I run CDK synth, it spits out:

Error: Cannot retrieve the value from context provider vpc-provider since the account/region is not specified at the stack level. Either configure "env" with explicit account and region when you define your stack or use the environment variables "CDK_DEFAULT_ACCOUNT" and "CDK_DEFAULT_REGION" to inherit environment information from the CLI (not recommended for production stacks)

But I don't know why. My usage here fits several other Stackoverflow answers to similar questions, it loos like the examples in the AWS docs, and when I console.log(process.env), it spits out the correct/expected values of CDK_DEFAULT_REGION and CDK_DEFAULT_ACCOUNT. When I log "env" it spits out the expected values as well.

So my question is, how do I configure my environment so ec2.Vpc.fromLookup knows my account info, or how do I pass the values properly to "env"?

I am learning the AWS CDK, and this is a problem I can't seem to figure out. JS/Node are not languages I use often, so if there is some obvious native thing that I am missing, please don't be too harsh. I'm trying to deploy a container to an existing VPC / new ECS Cluster. The following code isn't my whole script but is an important part. Hopefully, it gives the idea of what I'm trying to do.

//import everything first

stack_name = "frontend";

class Frontend extends core.Stack {
constructor(scope, id, props = {}) {
    super(scope, id);

    console.log("env variable " + JSON.stringify(props));
    
    const base_platform = new BasePlatform(this, id, props);

    //this bit doesn't matter, I'm just showing the functions I'm calling to set everything up

    const fargate_load_balanced_service = ecs_patterns.ApplicationLoadBalancedFargateService();
    this.fargate_load_balanced_service.taskDefinition.addToTaskRolePolicy();
    this.fargate_load_balanced_service.service.connections.allowTo();
    const autoscale = this.fargate_load_balanced_service.service.autoScaleTaskCount({});
    this.autoscale.scale_on_cpu_utilization();
    }
}

class BasePlatform extends core.Construct {
constructor(scope, id, props = {}) {
    super(scope, id);
    this.environment_name="frontend";
    
    console.log("environment variables " + JSON.stringify(process.env));

    //This bit is my problem child

    const vpc = ec2.Vpc.fromLookup(
        this, "VPC",{
        vpcId: 'vpc-##########'
    });

    //this bit doesn't matter, I'm just showing the functions I'm calling to set everything up

    const sd_namespace = service_discovery.PrivateDnsNamespace.from_private_dns_namespace_attributes();
    const ecs_cluster = ecs.Cluster.from_cluster_attributes();
    const services_sec_grp = ec2.SecurityGroup.from_security_group_id();
    }
}

const app = new core.App();

_env = {account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION };

new Frontend(app, stack_name, {env: _env});

app.synth();

When I run CDK synth, it spits out:

Error: Cannot retrieve the value from context provider vpc-provider since the account/region is not specified at the stack level. Either configure "env" with explicit account and region when you define your stack or use the environment variables "CDK_DEFAULT_ACCOUNT" and "CDK_DEFAULT_REGION" to inherit environment information from the CLI (not recommended for production stacks)

But I don't know why. My usage here fits several other Stackoverflow answers to similar questions, it loos like the examples in the AWS docs, and when I console.log(process.env), it spits out the correct/expected values of CDK_DEFAULT_REGION and CDK_DEFAULT_ACCOUNT. When I log "env" it spits out the expected values as well.

So my question is, how do I configure my environment so ec2.Vpc.fromLookup knows my account info, or how do I pass the values properly to "env"?

Share Improve this question edited Dec 28, 2020 at 8:05 Vadim Kotov 8,2848 gold badges50 silver badges63 bronze badges asked Oct 23, 2020 at 20:44 WingdomWingdom 4492 gold badges11 silver badges24 bronze badges 2
  • This might be useful docs.aws.amazon.com/cli/latest/userguide/… – Mithilesh_Kunal Commented Oct 24, 2020 at 1:00
  • 1 @Mithilesh_Kunal the environment variables are set though. When I log out process.env, they are there. So why does ec2.Vpc.fromLookup throw an error complaining about them? They are set. – Wingdom Commented Oct 26, 2020 at 19:03
Add a comment  | 

6 Answers 6

Reset to default 6

As I understand, it you must specify an environment explicitly if you want to use environment specifics at synth time.

The AWS CDK distinguishes between not specifying the env property at all and specifying it using CDK_DEFAULT_ACCOUNT and CDK_DEFAULT_REGION. The former implies that the stack should synthesize an environment-agnostic template. Constructs that are defined in such a stack cannot use any information about their environment. For example, you can't write code like if (stack.region === 'us-east-1') or use framework facilities like Vpc.fromLookup (Python: from_lookup), which need to query your AWS account. These features do not work at all without an explicit environment specified; to use them, you must specify env.

If you want to share environment variables with the cli you can do it like this:

new MyDevStack(app, 'dev', { 
  env: { 
    account: process.env.CDK_DEFAULT_ACCOUNT, 
    region: process.env.CDK_DEFAULT_REGION 
}});

Pass the props with env to the parent construct constructor explicitly as mentioned by Nick Cox

class BasePlatform extends core.Construct {
        constructor(scope, id, props = {}) {
            super(scope, id, props);

Since I was not able to comment, I am posting my query here.

From the look of it, there is just a single stack frontend. So I believe you can also try hard coding account-id and region in code, and see if it works. Also I am curious what is the output of

console.log("environment variables " + JSON.stringify(process.env));

Replace super(scope, id) with super(scope, id, props);

The props need to be passed to super for the vpc-provider to use it.

I went searching for this, and while the 'props' helped, it wasn't the fix.

With cdk 2.114.1 this is the correct code:

What I had:

class ChatUIStack(Stack):
    def __init__(self, scope: Construct, construct_id: str):
        super().__init__(scope, construct_id)

What is correct and worked:

class ChatUIStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs):
        super().__init__(scope, construct_id, **kwargs)

Also need to set your env vars as shown:

app = App()
ChatUIStack(app, stack_name, env=cdk.Environment(account="1234567890", region="us-east-1"))
app.synth()

Easiest way is to use aws cli(aws configure).

You will need to have programmatic access for your user and generate access keys from aws console. AWS CDK documentation

发布评论

评论列表(0)

  1. 暂无评论