question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[aws-eks] Cluster is not able to use an existing VPC

See original GitHub issue

When trying to create an EKS Cluster and use an existing VPC, I get the error: There are no ‘Public’ subnet groups in this VPC. Available types.

The referenced VPC has been created using the following snippet:

 new ec2.Vpc(this, 'VPC1-Default', {
            cidr: '10.0.0.0/20',
            maxAzs: 3        
});

This creates a VPC with 2 public and 2 private subnets.

Now I tried the EKS example, where a vpc and an eks are created within the same stack. This works. Now I tried creating a second EKS cluster in a separate stack, referencing that same vpc that the other eks cluster is using and I’m getting the same error.

Reproduction Steps

const vpc = new ec2.Vpc(this, 'EKSVpc');
eksCluster = new eks.Cluster(this, 'Cluster1', {
            clusterName: `cluster1`,
            version: 1.14,
            vpc: vpc
}

This works fine. Then I create a second eks in a separate stack:

const vpc =  ec2.Vpc.fromVpcAttributes(this, 'EKSVPC', {
            vpcId: 'vpc-xxxxxxxxxx', // this is the vpc-id from the first stack
            availabilityZones: ['eu-central-1b', 'eu-central-1c']
        })
eksCluster = new eks.Cluster(this, 'Cluster2', {
            clusterName: `cluster2`,
            version: 1.14,
            vpc: vpc
}

This does not work!!!

What worked at the end was explicitly providing the subnet ids and route table Ids, like this:

const vpc =  ec2.Vpc.fromVpcAttributes(this, 'EKSVPC', {
            vpcId: 'vpc-xxxxxxxxxx', // this is the vpc-id from the first stack
            availabilityZones: ['eu-central-1b', 'eu-central-1c']
        })
eksCluster = new eks.Cluster(this, 'Cluster2', {
            clusterName: `cluster2`,
            version: 1.14,
            vpc: vpc,
           vpcSubnets: [
                {
                    subnets: [
                        ec2.Subnet.fromSubnetAttributes(this, 'PublicSubnet1a', {
                            availabilityZone: "eu-central-1a",
                            subnetId: cdk.Fn.importValue("VPC1PublicSubnet1a"),
                            routeTableId: cdk.Fn.importValue("VPC1PublicSubnet1aRouteTable")
                        }),
                .....
                   ]
             }]
}

Error Log

There are no ‘Public’ subnet groups in this VPC. Available types:

Environment

  • ** CLI Version: 1.17.7
  • ** Language: Typescript
  • ** aws-cdk: 1.22.0 (build 309ac1b)

Other

This seems like a bug to me, since providing a vpc id can (should) be the only thing I need to reference a VPC. In this case the user is saying just create it here and I don’t care where

This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:2
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

5reactions
skinny85commented, Jan 30, 2020

@skinny85 what finally worked like you said referencing the subnet and the routing table IDs. But this is far from optimal… If I’m providing the vpc id which is unique, I should actually be able to find and load those information…

OK. Now I understand what the confusion is 😃.

The CDK has 2 ways of referencing existing resources. The first one are methods like fromXyzName, fromXyzArn, fromXyzAttributes. Those simply assume the thing you’ve passed us exist, and don’t do any checks, nor any service calls. Vpc.fromVpcAttributes() that you used belongs to this family. That’s why you have to give us the subnet IDs. Another way of thinking about it is the information is strictly at compile time.

The other methods are those that are called fromLookup. How that works, is that the first time you use it, it will require AWS credentials to be present, and it will perform actual service calls to discover your resources. It will then cache that information in the cdk.context.json file, which you are expected to commit to version control. If the information is cached, no further network calls are required.

However, since you’re creating and using the VPC in the same app, that is not the best way to do that. You should simply pass the VPC object to the other stack.

Might I suggest simply passing the VPC object you have in the first stack to the second stack?

I am a TypeScript noob. Could you please show me a minimal example?

Sure:

import { App, Construct, Stack, StackProps } from '@aws-cdk/core';
import ec2 = require('@aws-cdk/aws-ec2');

class Stack1 extends Stack {
    public readonly vpc: ec2.IVpc;
    
    constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props);
        
        this.vpc = new ec2.Vpc(this, 'Vpc');
    }
}

interface Stack2Props extends StackProps {
    readonly vpc: ec2.IVpc;
}

class Stack2 extends Stack {
    constructor(scope: Construct, id: string, props: Stack2Props) {
        super(scope, id, props);

        // use props.vpc here...
    }
}

And you use them like so in your CDK entry point:

const app = new App();

const stack1 = new Stack1(app, 'Stack1');
new Stack2(app, 'Stack2', {
    vpc: stack1.vpc,
});

app.synth();

Hope this helps!

Thanks, Adam

0reactions
moatazelmasry2commented, Jan 30, 2020

ok. Thanks for the explanation. I’ll try to create some documentation PRs the next couple of days.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Deploy Amazon Elastic Kubernetes Service into an existing ...
Select Amazon EKS, select Deploy Amazon EKS into an existing VPC, then select Create deployment. You are prompted to enter the specifications for...
Read more >
Create EKS with an Existing VPC - Joaquín Menchaca (智裕)
Method 1: The Labor Intensive Way. The eksctl command line tool can create a cluster by either command-line options or using a eksctl...
Read more >
VPC Configuration - eksctl
eksctl provides some, but not complete, flexibility for custom VPC and subnet topologies. You can use an existing VPC by supplying private and/or...
Read more >
For Terraform's aws_eks_cluster, how can I use an existing ...
I have a YAML configuration file that I've used to create an AWS EKS cluster via eksctl that uses an existing VPC, like...
Read more >
EKS cluster using an existing VPC - Mandar Shinde
The eksctl command line tool can create a cluster by either command-line options or using a eksctl config file to define the infrastructure....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found