Niranjan
Niranjan

Reputation: 2229

Unable to import VPC in AWS cdk

Hi I am working on AWS cdk. I am trying to create few resources like ECS, SG,LB etc. I want to use default VPC in the resources. Below is my code.

app.py

     from aws_cdk import core
        from cdk_python.cdk_python_stack import CdkPythonStack
        app = core.App()
        CdkPythonStack(app, "cdk-python-1", env={'region': 'ap-southeast-2'})
        app.synth()

cdk_python_stack.py

    from aws_cdk import (
        aws_ec2 as ec2,
        aws_ecs as ecs,
        aws_elasticloadbalancingv2 as elbv2,
        aws_ecr as ecr,
        core,
    )

    class CdkPythonStack(core.Stack):


        def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
            super().__init__(scope, id, **kwargs)

    vpc = ec2.Vpc.from_lookup(scope = core.Construct, vpc_id='vpc-d45072b3', is_default=True, id="test" )

    cluster = ecs.Cluster(
        stack, "EcsCluster",
        vpc=vpc
    )

    cluster.add_capacity("DefaultAutoScalingGroup",
                         instance_type=ec2.InstanceType("t2.micro"),
                         key_name="MyNewEC2KeyPair",
                         desired_capacity=1)


    # create SG
    sg_elb  = ec2.SecurityGroup(stack, "MerchWebServicesLoadBalancerSecurityGroup",
        description= "Allow ssh access to ec2 instances",
        security_group_name= "MerchWebServicesLoadBalancerSecurityGroup",
        vpc= vpc
    );

    sg_elb.add_ingress_rule(
    peer = ec2.Peer.any_ipv4(),
    connection = ec2.Port.tcp(22)
    )



    # Create a task definition with placement constraints
    task_definition = ecs.Ec2TaskDefinition(
        stack, "TaskDef",
        # placement_constraints=[
        #     ecs.PlacementConstraint.distinct_instances()
        # ]
    )

    container = task_definition.add_container(
        "web",
        image=ecs.ContainerImage.from_registry("nginx:latest"),
        memory_limit_mib=256,
    )
    port_mapping = ecs.PortMapping(
        container_port=80,
        host_port=8080,
        protocol=ecs.Protocol.TCP
    )
    container.add_port_mappings(port_mapping)

    # Create Service
    service = ecs.Ec2Service(
        stack, "Service",
        cluster=cluster,
        task_definition=task_definition,
        security_group=sg_elb
    )


    lb = elbv2.ApplicationLoadBalancer(
        stack, "LB",
        vpc = vpc,
        internet_facing= True
    )

    listener = lb.add_listener(
        "PublicListener",
        port = 80,
        open = True
    )

    health_check = elbv2.HealthCheck(
        interval=core.Duration.seconds(60),
        path="/",
        timeout=core.Duration.seconds(5)
    )

    # Attach ALB to ECS Service
    listener.add_targets(
        "ECS",
        port=80,
        targets=[service],
        health_check=health_check,
    )

    service.add_placement_strategies(
        ecs.PlacementStrategy.packed_by(ecs.BinPackResource.MEMORY))
    service.add_placement_strategies(
        ecs.PlacementStrategy.spread_across(
            ecs.BuiltInAttributes.AVAILABILITY_ZONE))
    app.synth()

When I do cdk synth I get below error.

File "app.py", line 5, in <module>
    from cdk_python.cdk_python_stack import CdkPythonStack
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\cdk_python\cdk_python_stack.py", line 21, in <module>
    vpc = ec2.Vpc.from_lookup(scope = core.Construct, vpc_id='vpc-d45072b3', is_default=True, id="test" )
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\.env\lib\site-packages\aws_cdk\aws_ec2\__init__.py", line 21474, in from_lookup
    return jsii.sinvoke(cls, "fromLookup", [scope, id, options])
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\.env\lib\site-packages\jsii\_kernel\__init__.py", line 105, in wrapped
    return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\.env\lib\site-packages\jsii\_kernel\__init__.py", line 292, in sinvoke
    args=_make_reference_for_native(self, args),
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\.env\lib\site-packages\jsii\_kernel\providers\process.py", line 349, in sinvoke
    return self._process.send(request, InvokeResponse)
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\.env\lib\site-packages\jsii\_kernel\providers\process.py", line 301, in send
    data = json.dumps(req_dict, default=jdefault).encode("utf8")
  File "C:\Program Files (x86)\Python37-32\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "C:\Program Files (x86)\Python37-32\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files (x86)\Python37-32\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\ngodbole\Documents\MerchWebServices\CDKPython\.env\lib\site-packages\jsii\_kernel\providers\process.py", line 144, in jdefault
    raise TypeError("Don't know how to convert object to JSON: %r" % obj)
TypeError: Don't know how to convert object to JSON: <class 'aws_cdk.core.Construct'>

In constructor I changed to

def init(self, app: core.Construct, id: str, **kwargs) -> None:

Now I started getting error

NameError: name 'self' is not defined

(.env) C:\Users\ngodbole\Documents\MerchWebServices\LocationCDK\LocationCDK>cdk synth
Traceback (most recent call last):
  File "app.py", line 5, in <module>
    from location_cdk.location_cdk_stack import LocationCdkStack
  File "C:\Users\ngodbole\Documents\MerchWebServices\LocationCDK\LocationCDK\location_cdk\location_cdk_stack.py", line 9, in <module>
    class LocationCdkStack(core.Stack):
  File "C:\Users\ngodbole\Documents\MerchWebServices\LocationCDK\LocationCDK\location_cdk\location_cdk_stack.py", line 15, in LocationCdkStack
    vpc = ec2.Vpc.from_lookup(self, "", is_default=True)
NameError: name 'self' is not defined
Subprocess exited with error 1

I am trying to get default VPC which is existing in my account. I want to use the same VPC in all my resources created during my python cdk scrips. Can someone help me to figure out the issue? Any help would be greatly appreciated. Thanks

Upvotes: 2

Views: 3577

Answers (2)

Nobe&#39;s
Nobe&#39;s

Reputation: 166

In JS here's how I define the VPC I want to use...

in this file... rootProject/lib/applicationName.js

#!/usr/bin/env node

const cdk = require('@aws-cdk/core');
const { PrerenderInfrasctutureStack } = require('../lib/applicationName-stack');

const app = new cdk.App();

const DEVapSouthEast2Env = {account: 'xxx', region: 'ap-southeast-2'};
const PRODapSouthEast2Env = {account: 'xxx', region: 'ap-southeast-2'};

// change the env to define where the app will be deployed
new applicationName(app, 'applicationName', {env: DEVapSouthEast2Env});

And then in this file...

rootProject/lib/applicationName-stack.js:

const myVPC = ec2.Vpc.fromLookup(this, 'publicVpc', {
vpcId:'vpc-xxx'
});

So basically, pass the account details and then for'ec2.Vpc.fromLookup' pass in the vpcID

Upvotes: 0

Vikyol
Vikyol

Reputation: 5645

It is enough to set is_default parameter to True to fetch the default VPC.

stack.py

class CdkPythonStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        vpc = ec2.Vpc.from_lookup(self, "default_vpc", is_default=True)

        cluster = ecs.Cluster(
            self, "EcsCluster",
            vpc=vpc
        )
        ...

You also need to explicitly set account and region in your stack configuration as stated in this issue. So whenever you perform resource lookups, you have to specify the account.

app.py

CdkPythonStack(
  app=app, 
  id="cdk-python-1", 
  env={
    'account': os.environ['CDK_DEFAULT_ACCOUNT'], 
    'region': os.environ['CDK_DEFAULT_REGION']
  }
)

Upvotes: 0

Related Questions