AWS CDK (Python) How to Create EKS Cluster

In my previous post, I have discussed about how to create vpc, subnets, internet gateway, nat gateway using AWS CDK(Python). In this post, we will be discussing about how to create EKS (k8s) cluster. This is requested by many of my followers, so I would like to write a blog to help the community.

Create a new stack called EKSStack and use existing vpc from other stack (vpc: ec2.Vpc)

class EKSStack(core.Stack):

    def __init__(self, scope: core.Construct, construct_id: str, vpc: ec2.Vpc, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

Create an IAM role for worker groups and kubernetes RBAC configuration

eks_role = iam.Role(self, "eksadmin", assumed_by=iam.ServicePrincipal(service='ec2.amazonaws.com'),
                            role_name='eks-cluster-role', managed_policies=
                            [iam.ManagedPolicy.from_aws_managed_policy_name(managed_policy_name='AdministratorAccess')])
        eks_instance_profile = iam.CfnInstanceProfile(self, 'instanceprofile',
                                                      roles=[eks_role.role_name],
                                                      instance_profile_name='eks-cluster-role')

Once the role is created, let us create EKS Cluster and attach the role as masters_role.

 cluster = eks.Cluster(self, 'prod', cluster_name='eks-demo-cluster',
                              version=eks.KubernetesVersion.V1_19,
                              vpc=vpc,
                              vpc_subnets=[ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE)],
                              default_capacity=0,
                              masters_role=eks_role)

In the above code, you can see that I’m using version 1.9, cluster will use private subnets and the IAM role that was created will be used. I used default_capacity = 0 since, I do not want EKS to create default node group. I will be creating node groups separately and will use SPOT instances for worker nodes in this case. This is all about control plane definition.

Now, let us create node group.

nodegroup = cluster.add_nodegroup_capacity('eks-nodegroup',
                                                   instance_types=[ec2.InstanceType('t3.large'),
                                                                   ec2.InstanceType('m5.large'),
                                                                   ec2.InstanceType('c5.large')],
                                                   disk_size=50,
                                                   min_size=2,
                                                   max_size=2,
                                                   desired_size=2,
                                                   subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE),
                                                   remote_access=eks.NodegroupRemoteAccess(
                                                       ssh_key_name='eks-ssh-keypair'),
                                                   capacity_type=eks.CapacityType.SPOT)

I’ve used multiple instance types for SPOT for different worker nodes. Disk size for the nodes to set to 50GB and two nodes will be created. you can adjust these parameters based on your requirement.

Now, let’s call the stack.

from mycdkproject.eks_stack import EKSStack
app = core.App()
vpc_stack = VPCStack(app, "mycdkproject")
eks_stack = EKSStack(app,'eks',vpc=vpc_stack.vpc)
app.synth()

you need to update requirements.txt file to import modules for iam and eks. you can install these modules using pip install -r requirements.txt


aws-cdk.aws-iam
aws-cdk.aws-eks

now, let’s run cdk ls to see howmany stacks we can see. we should expect to see two stacks.

Now, let’s Synthesize an AWS CloudFormation template for the app, as follows.

(.venv) C:\Rama\MyProjects\mycdkproject>cdk synth
Successfully synthesized to C:\Rama\MyProjects\mycdkproject\cdk.out
Supply a stack id (mycdkproject, eks) to display its template.

Now, let’s deploy

cdk deploy eks --profile cdkprofile

if you have encountered an error as eks failed: Error: This stack uses assets, so the toolkit stack must be deployed to the environment (Run “cdk bootstrap aws://unknown-account/unknown-region”)

you can fix this by running cdk bootstrap aws://accountnumber/region

(.venv) C:\Rama\MyProjects\mycdkproject>cdk deploy eks --profile cdkprofile
Including dependency stacks: mycdkproject
mycdkproject
mycdkproject: deploying...

 ✅  mycdkproject (no changes)

Outputs:
mycdkproject.ExportsOutputRefdemovpcF2DCF540F486AA93 = vpc-0a28afc429ef12e7d
mycdkproject.ExportsOutputRefdemovpcPrivateSubnetSubnet1Subnet7F4868328AE74887 = subnet-01d19280e1eca62f5
mycdkproject.ExportsOutputRefdemovpcPrivateSubnetSubnet2Subnet4FD8659B8BB1175E = subnet-05cedf7ea3c9a2d1a

Stack ARN:
arn:aws:cloudformation:eu-west-1:604035856224:stack/mycdkproject/ced8f3a0-7791-11eb-8a02-02fbd2f362b9
eks
eks: deploying...
[0%] start: Publishing 50e10880d134a01b440991fc77d217f39f01c2d56945215ee9a3b81187c6f3b1:current
[14%] success: Published 50e10880d134a01b440991fc77d217f39f01c2d56945215ee9a3b81187c6f3b1:current
[14%] start: Publishing c691172cdeefa2c91b5a2907f9d81118e47597634943344795f1a844192dd49c:current
[28%] success: Published c691172cdeefa2c91b5a2907f9d81118e47597634943344795f1a844192dd49c:current
[28%] start: Publishing 299e5262386e9f084fcd72906b8282f5c3cb1885c39d0912db1670b472873fb5:current
[42%] success: Published 299e5262386e9f084fcd72906b8282f5c3cb1885c39d0912db1670b472873fb5:current
[42%] start: Publishing e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68:current
[57%] success: Published e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68:current
[57%] start: Publishing 844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0:current
[71%] success: Published 844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0:current
[71%] start: Publishing 7f9c09e9e3ebb8ac17932545378ebfc732075bc1529c3f5294d1220ab938c1a8:current
[85%] success: Published 7f9c09e9e3ebb8ac17932545378ebfc732075bc1529c3f5294d1220ab938c1a8:current
[85%] start: Publishing 53fdcf13d33580b64d5d493f823aa68fa304539df464fedc629ad48b949244ad:current
[100%] success: Published 53fdcf13d33580b64d5d493f823aa68fa304539df464fedc629ad48b949244ad:current
eks: creating CloudFormation changeset...
  0/15 | 12:50:35 PM | REVIEW_IN_PROGRESS   | AWS::CloudFormation::Stack            | eks User Initiated
  0/15 | 12:50:40 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | eks User Initiated
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroup               | prod/ControlPlaneSecurityGroup (prodControlPlaneSecurityGroup7CE46782)
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | eksadmin (eksadminBEE25D8E)
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | prod/Resource/CreationRole (prodCreationRole5E247585)
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                    | @aws-cdk--aws-eks.ClusterResourceProvider/CDKMetadata/Default (CDKMetadata)
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | prod/Role (prodRoleD997707D)
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | prod/Nodegroupeks-nodegroup/NodeGroupRole (prodNodegroupeksnodegroupNodeGroupRoleB635EB43)
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | prod/Resource/CreationRole (prodCreationRole5E247585) Resource creation Initiated
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | prod/Role (prodRoleD997707D) Resource creation Initiated
  0/15 | 12:51:09 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | prod/Nodegroupeks-nodegroup/NodeGroupRole (prodNodegroupeksnodegroupNodeGroupRoleB635EB43)
Resource creation Initiated
  0/15 | 12:51:10 PM | CREATE_IN_PROGRESS   | AWS::IAM::Role                        | eksadmin (eksadminBEE25D8E) Resource creation Initiated
  2/15 | 12:51:11 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                    | @aws-cdk--aws-eks.ClusterResourceProvider/CDKMetadata/Default (CDKMetadata) Resource creati
on Initiated
  2/15 | 12:51:12 PM | CREATE_COMPLETE      | AWS::CDK::Metadata                    | @aws-cdk--aws-eks.ClusterResourceProvider/CDKMetadata/Default (CDKMetadata)
  2/15 | 12:51:13 PM | CREATE_IN_PROGRESS   | AWS::EC2::SecurityGroup               | prod/ControlPlaneSecurityGroup (prodControlPlaneSecurityGroup7CE46782) Resource creation In
itiated
  2/15 | 12:51:15 PM | CREATE_COMPLETE      | AWS::EC2::SecurityGroup               | prod/ControlPlaneSecurityGroup (prodControlPlaneSecurityGroup7CE46782)
  6/15 | 12:51:26 PM | CREATE_COMPLETE      | AWS::IAM::Role                        | prod/Resource/CreationRole (prodCreationRole5E247585)
  6/15 | 12:51:26 PM | CREATE_COMPLETE      | AWS::IAM::Role                        | prod/Role (prodRoleD997707D)
  6/15 | 12:51:27 PM | CREATE_COMPLETE      | AWS::IAM::Role                        | prod/Nodegroupeks-nodegroup/NodeGroupRole (prodNodegroupeksnodegroupNodeGroupRoleB635EB43)
  6/15 | 12:51:27 PM | CREATE_COMPLETE      | AWS::IAM::Role                        | eksadmin (eksadminBEE25D8E)
  6/15 | 12:51:30 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | @aws-cdk--aws-eks.ClusterResourceProvider.NestedStack/@aws-cdk--aws-eks.ClusterResourceProv
ider.NestedStackResource (awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454) 
  6/15 | 12:51:30 PM | CREATE_IN_PROGRESS   | AWS::IAM::InstanceProfile             | instanceprofile
  6/15 | 12:51:31 PM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                      | prod/Resource/CreationRole/DefaultPolicy (prodCreationRoleDefaultPolicy46633E70)
  6/15 | 12:51:31 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | @aws-cdk--aws-eks.ClusterResourceProvider.NestedStack/@aws-cdk--aws-eks.ClusterResourceProv
ider.NestedStackResource (awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454) Resource creation Initiated
  6/15 | 12:51:31 PM | CREATE_IN_PROGRESS   | AWS::IAM::InstanceProfile             | instanceprofile Resource creation Initiated
  6/15 | 12:51:32 PM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                      | prod/Resource/CreationRole/DefaultPolicy (prodCreationRoleDefaultPolicy46633E70) Resource c
reation Initiated
  7/15 | 12:51:48 PM | CREATE_COMPLETE      | AWS::IAM::Policy                      | prod/Resource/CreationRole/DefaultPolicy (prodCreationRoleDefaultPolicy46633E70)
 7/15 Currently in progress: eks, awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454, instanceprofile
  8/15 | 12:53:32 PM | CREATE_COMPLETE      | AWS::IAM::InstanceProfile             | instanceprofile
 8/15 Currently in progress: eks, awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454
  9/15 | 12:54:09 PM | CREATE_COMPLETE      | AWS::CloudFormation::Stack            | @aws-cdk--aws-eks.ClusterResourceProvider.NestedStack/@aws-cdk--aws-eks.ClusterResourceProv
ider.NestedStackResource (awscdkawseksClusterResourceProviderNestedStackawscdkawseksClusterResourceProviderNestedStackResource9827C454) 
  9/15 | 12:54:13 PM | CREATE_IN_PROGRESS   | Custom::AWSCDK-EKS-Cluster            | prod/Resource/Resource/Default (prod3363F4D9)
 9/15 Currently in progress: eks, prod3363F4D9
 10/15 | 1:07:36 PM | CREATE_IN_PROGRESS   | Custom::AWSCDK-EKS-Cluster            | prod/Resource/Resource/Default (prod3363F4D9) Resource creation Initiated
 10/15 | 1:07:37 PM | CREATE_COMPLETE      | Custom::AWSCDK-EKS-Cluster            | prod/Resource/Resource/Default (prod3363F4D9)
 11/15 | 1:07:41 PM | CREATE_IN_PROGRESS   | AWS::SSM::Parameter                   | prod/KubectlReadyBarrier (prodKubectlReadyBarrier3183289D)
 11/15 | 1:07:41 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | @aws-cdk--aws-eks.KubectlProvider.NestedStack/@aws-cdk--aws-eks.KubectlProvider.NestedStackR
esource (awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B) 
 11/15 | 1:07:42 PM | CREATE_IN_PROGRESS   | AWS::EKS::Nodegroup                   | prod/Nodegroupeks-nodegroup (prodNodegroupeksnodegroupE8147B13)
 11/15 | 1:07:42 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | @aws-cdk--aws-eks.KubectlProvider.NestedStack/@aws-cdk--aws-eks.KubectlProvider.NestedStackR
esource (awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B) Resource creation Initiated
 11/15 | 1:07:42 PM | CREATE_IN_PROGRESS   | AWS::SSM::Parameter                   | prod/KubectlReadyBarrier (prodKubectlReadyBarrier3183289D) Resource creation Initiated
 11/15 | 1:07:43 PM | CREATE_COMPLETE      | AWS::SSM::Parameter                   | prod/KubectlReadyBarrier (prodKubectlReadyBarrier3183289D)
 11/15 | 1:07:46 PM | CREATE_IN_PROGRESS   | AWS::EKS::Nodegroup                   | prod/Nodegroupeks-nodegroup (prodNodegroupeksnodegroupE8147B13) Resource creation Initiated
11/15 Currently in progress: eks, awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B, prodNodegroupeksnodegroupE8147B13
 12/15 | 1:10:13 PM | CREATE_COMPLETE      | AWS::EKS::Nodegroup                   | prod/Nodegroupeks-nodegroup (prodNodegroupeksnodegroupE8147B13)
12/15 Currently in progress: eks, awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B
 13/15 | 1:12:57 PM | CREATE_COMPLETE      | AWS::CloudFormation::Stack            | @aws-cdk--aws-eks.KubectlProvider.NestedStack/@aws-cdk--aws-eks.KubectlProvider.NestedStackR
esource (awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B) 
 13/15 | 1:13:02 PM | CREATE_IN_PROGRESS   | Custom::AWSCDK-EKS-KubernetesResource | prod/AwsAuth/manifest/Resource/Default (prodAwsAuthmanifest0B7F1A5F)
 15/15 | 1:13:10 PM | CREATE_IN_PROGRESS   | Custom::AWSCDK-EKS-KubernetesResource | prod/AwsAuth/manifest/Resource/Default (prodAwsAuthmanifest0B7F1A5F) Resource creation Initi
ated
 15/15 | 1:13:10 PM | CREATE_COMPLETE      | Custom::AWSCDK-EKS-KubernetesResource | prod/AwsAuth/manifest/Resource/Default (prodAwsAuthmanifest0B7F1A5F)
 15/15 | 1:13:13 PM | CREATE_COMPLETE      | AWS::CloudFormation::Stack            | eks

 ✅  eks

Outputs:
eks.prodConfigCommand1B086551 = aws eks update-kubeconfig --name eks-cluster-demo --region eu-west-1 --role-arn arn:aws:iam::accountnumber:role/eks-cluster-role
eks.prodGetTokenCommand0CE8FF77 = aws eks get-token --cluster-name eks-cluster-demo --region eu-west-1 --role-arn arn:aws:iam::accountnumber:role/eks-cluster-role

Stack ARN:
arn:aws:cloudformation:eu-west-1:accountnumber:stack/eks/57cd8dd0-779a-11eb-9605-06cacdbbe755

That’s it. You can see that EKS cluster has been setup using AWS CDK (Python). You can find the EKSStack on my github repository here.

Hope you enjoyed the post.

Cheers

Ramasankar Molleti

LinkedIn

Published by Ramasankar

Hi. I’m Ramasankar Molleti. I’m a passionate IT professional with over 14 years of experience on providing solutions for customers who are looking on cloud computing, Database Migration, Development, and Big Data. I love learning new technologies and share my knowledge to community. I am currently working as Sr Cloud Architect with focus on Cloud Infrastructure, Big Data. I work with developers to architect, build, and manage cloud infrastructure, and services. I have deeep knowledge and experience on working with various database platforms such as MS SQL Server, PostgeSQL, Oracle, MongoDB, Redshift, Dyanamodb, Amazon Aurora. I worked as Database Engineer, Database Administrator, BI Developer and successfully transit myself into Cloud Architect with focus on Cloud infranstructure and Big Data. I live in USA and put my thoughts down on this blog. If you want to get in touch with me, contact me on my Linkedin here: https://www.linkedin.com/in/ramasankar-molleti-23b13218/ My Certifications: Amazon: AWS Certified Solutions Architect – Professional AWS Certified DevOps Engineer – Professional certificate AWS Certified Big Data – Specialty AWS Certified Security – Specialty certificate AWS Certified Advanced Networking – Specialty certificate AWS Certified Solutions Architect – Associate Microsoft: Microsoft® Certified Solutions Associate: SQL Server 2012/2014 Microsoft Certified Professional Microsoft® Certified IT Professional: Database Administrator 2008 Microsoft® Certified Technology Specialist: SQL Server 2008, Implementation and Maintenance

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: