Package: aws-cdk.aws-eks-legacy
Amazon EKS Construct Library---This API may emit warnings. Backward compatibility is not guaranteed.**This module is available for backwards compatibility purposes only (details). It will
no longer be released with the CDK starting March 1st, 2020. See [issue5544](https://github.com/aws/aws-cdk/issues/5544) for upgrade instructions.**This construct library allows you to defineAmazon Elastic Container Service
for Kubernetes (EKS)clusters programmatically.
This library also supports programmatically defining Kubernetes resource
manifests within EKS clusters.This example defines an Amazon EKS cluster with the following configuration:2xm5.largeinstances (this instance type suits most common use-cases, and is good value for money)Dedicated VPC with default configuration (seeec2.Vpc)A Kubernetes pod with a container based on thepaulbouwer/hello-kubernetesimage.cluster=eks.Cluster(self,"hello-eks")cluster.add_resource("mypod",{"api_version":"v1","kind":"Pod","metadata":{"name":"mypod"},"spec":{"containers":[{"name":"hello","image":"paulbouwer/hello-kubernetes:1.5","ports":[{"container_port":8080}]}]}})Here is acomplete sample.CapacityBy default,eks.Clusteris created with x2m5.largeinstances.eks.Cluster(self,"cluster-two-m5-large")The quantity and instance type for the default capacity can be specified through
thedefaultCapacityanddefaultCapacityInstanceprops:eks.Cluster(self,"cluster",default_capacity=10,default_capacity_instance=ec2.InstanceType("m2.xlarge"))To disable the default capacity, simply setdefaultCapacityto0:eks.Cluster(self,"cluster-with-no-capacity",default_capacity=0)Thecluster.defaultCapacityproperty will reference theAutoScalingGroupresource for the default capacity. It will beundefinedifdefaultCapacityis set to0:cluster=eks.Cluster(self,"my-cluster")cluster.default_capacity.scale_on_cpu_utilization("up",target_utilization_percent=80)You can add customized capacity throughcluster.addCapacity()orcluster.addAutoScalingGroup():# cluster: eks.Clustercluster.add_capacity("frontend-nodes",instance_type=ec2.InstanceType("t2.medium"),desired_capacity=3,vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC))Spot CapacityIfspotPriceis specified, the capacity will be purchased from spot instances:# cluster: eks.Clustercluster.add_capacity("spot",spot_price="0.1094",instance_type=ec2.InstanceType("t3.large"),max_capacity=10)Spot instance nodes will be labeled withlifecycle=Ec2Spotand tainted withPreferNoSchedule.TheSpot Termination HandlerDaemonSet will be installed on these nodes. The termination handler leveragesEC2 Spot Instance Termination Noticesto gracefully stop all pods running on spot nodes that are about to be
terminated.BootstrappingWhen adding capacity, you can specify options for/etc/eks/boostrap.shwhich is responsible for associating the node to the EKS cluster. For example,
you can usekubeletExtraArgsto add custom node labels or taints.# up to ten spot instances# cluster: eks.Clustercluster.add_capacity("spot",instance_type=ec2.InstanceType("t3.large"),desired_capacity=2,bootstrap_options=eks.BootstrapOptions(kubelet_extra_args="--node-labels foo=bar,goo=far",aws_api_retry_attempts=5))To disable bootstrapping altogether (i.e. to fully customize user-data), setbootstrapEnabledtofalsewhen you add
the capacity.Masters RoleThe Amazon EKS construct library allows you to specify an IAM role that will be
grantedsystem:mastersprivileges on your cluster.Without specifying amastersRole, you will not be able to interact manually
with the cluster.The following example defines an IAM role that can be assumed by all users
in the account and shows how to use themastersRoleproperty to map this
role to the Kubernetessystem:mastersgroup:# first define the rolecluster_admin=iam.Role(self,"AdminRole",assumed_by=iam.AccountRootPrincipal())# now define the cluster and map role to "masters" RBAC groupeks.Cluster(self,"Cluster",masters_role=cluster_admin)When youcdk deploythis CDK app, you will notice that an output will be printed
with theupdate-kubeconfigcommand.Something like this:Outputs:
eks-integ-defaults.ClusterConfigCommand43AAE40F = aws eks update-kubeconfig --name cluster-ba7c166b-c4f3-421c-bf8a-6812e4036a33 --role-arn arn:aws:iam::112233445566:role/eks-integ-defaults-Role1ABCC5F0-1EFK2W5ZJD98YCopy & paste the "aws eks update-kubeconfig ..." command to your shell in
order to connect to your EKS cluster with the "masters" role.Now, givenAWS CLIis configured to use AWS
credentials for a user that is trusted by the masters role, you should be able
to interact with your cluster throughkubectl(the above example will trust
all users in the account).For example:$awseksupdate-kubeconfig--namecluster-ba7c166b-c4f3-421c-bf8a-6812e4036a33--role-arnarn:aws:iam::112233445566:role/eks-integ-defaults-Role1ABCC5F0-1EFK2W5ZJD98YAdded new context arn:aws:eks:eu-west-2:112233445566:cluster/cluster-ba7c166b-c4f3-421c-bf8a-6812e4036a33 to /Users/boom/.kube/config$kubectlgetnodes# list all nodesNAME                                         STATUS   ROLES    AGE   VERSIONip-10-0-147-66.eu-west-2.compute.internal    Ready    <none>   21m   v1.13.7-eks-c57ff8ip-10-0-169-151.eu-west-2.compute.internal   Ready    <none>   21m   v1.13.7-eks-c57ff8$kubectlgetall-nkube-systemNAME                           READY   STATUS    RESTARTS   AGEpod/aws-node-fpmwv             1/1     Running   0          21mpod/aws-node-m9htf             1/1     Running   0          21mpod/coredns-5cb4fb54c7-q222j   1/1     Running   0          23mpod/coredns-5cb4fb54c7-v9nxx   1/1     Running   0          23mpod/kube-proxy-d4jrh           1/1     Running   0          21mpod/kube-proxy-q7hh7           1/1     Running   0          21mNAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGEservice/kube-dns   ClusterIP   172.20.0.10   <none>        53/UDP,53/TCP   23mNAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGEdaemonset.apps/aws-node     2         2         2       2            2           <none>          23mdaemonset.apps/kube-proxy   2         2         2       2            2           <none>          23mNAME                      READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/coredns   2/2     2            2           23mNAME                                 DESIRED   CURRENT   READY   AGEreplicaset.apps/coredns-5cb4fb54c7   2         2         2       23mFor your convenience, an AWS CloudFormation output will automatically be
included in your template and will be printed when runningcdk deploy.NOTE: if the cluster is configured withkubectlEnabled: false, it
will be created with the role/user that created the AWS CloudFormation
stack. SeeKubectl Supportfor details.Kubernetes ResourcesTheKubernetesResourceconstruct orcluster.addResourcemethod can be used
to apply Kubernetes resource manifests to this cluster.The following examples will deploy thepaulbouwer/hello-kubernetesservice on the cluster:# cluster: eks.Clusterapp_label={"app":"hello-kubernetes"}deployment={"api_version":"apps/v1","kind":"Deployment","metadata":{"name":"hello-kubernetes"},"spec":{"replicas":3,"selector":{"match_labels":app_label},"template":{"metadata":{"labels":app_label},"spec":{"containers":[{"name":"hello-kubernetes","image":"paulbouwer/hello-kubernetes:1.5","ports":[{"container_port":8080}]}]}}}}service={"api_version":"v1","kind":"Service","metadata":{"name":"hello-kubernetes"},"spec":{"type":"LoadBalancer","ports":[{"port":80,"target_port":8080}],"selector":app_label}}# option 1: use a constructeks.KubernetesResource(self,"hello-kub",cluster=cluster,manifest=[deployment,service])# or, option2: use `addResource`cluster.add_resource("hello-kub",service,deployment)Since Kubernetes resources are implemented as CloudFormation resources in the
CDK. This means that if the resource is deleted from your code (or the stack is
deleted), the nextcdk deploywill issue akubectl deletecommand and the
Kubernetes resources will be deleted.AWS IAM MappingAs described in theAmazon EKS User Guide,
you can map AWS IAM users and roles toKubernetes Role-based access control (RBAC).The Amazon EKS construct manages theaws-auth ConfigMapKubernetes resource
on your behalf and exposes an API through thecluster.awsAuthfor mapping
users, roles and accounts.Furthermore, when auto-scaling capacity is added to the cluster (throughcluster.addCapacityorcluster.addAutoScalingGroup), the IAM instance role
of the auto-scaling group will be automatically mapped to RBAC so nodes can
connect to the cluster. No manual mapping is required any longer.NOTE:cluster.awsAuthwill throw an error if your cluster is created withkubectlEnabled: false.For example, let's say you want to grant an IAM user administrative privileges
on your cluster:# cluster: eks.Clusteradmin_user=iam.User(self,"Admin")cluster.aws_auth.add_user_mapping(admin_user,groups=["system:masters"])A convenience method for mapping a role to thesystem:mastersgroup is also available:# cluster: eks.Cluster# role: iam.Rolecluster.aws_auth.add_masters_role(role)Node ssh AccessIf you want to be able to SSH into your worker nodes, you must already
have an SSH key in the region you're connecting to and pass it, and you must
be able to connect to the hosts (meaning they must have a public IP and you
should be allowed to connect to them on port 22):asg=cluster.add_capacity("Nodes",instance_type=ec2.InstanceType("t2.medium"),vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),key_name="my-key-name")# Replace with desired IPasg.connections.allow_from(ec2.Peer.ipv4("1.2.3.4/32"),ec2.Port.tcp(22))If you want to SSH into nodes in a private subnet, you should set up a
bastion host in a public subnet. That setup is recommended, but is
unfortunately beyond the scope of this documentation.kubectl SupportWhen you create an Amazon EKS cluster, the IAM entity user or role, such as afederated userthat creates the cluster, is automatically grantedsystem:masterspermissions
in the cluster's RBAC configuration.In order to allow programmatically definingKubernetes resourcesin your AWS
CDK app and provisioning them through AWS CloudFormation, we will need to assume
this "masters" role every time we want to issuekubectloperations against your
cluster.At the moment, theAWS::EKS::ClusterAWS CloudFormation resource does not support this behavior, so in order to
support "programmatic kubectl", such as applying manifests
and mapping IAM roles from within your CDK application, the Amazon EKS
construct library uses a custom resource for provisioning the cluster.
This custom resource is executed with an IAM role that we can then use
to issuekubectlcommands.The default behavior of this library is to use this custom resource in order
to retain programmatic control over the cluster. In other words: to allow
you to define Kubernetes resources in your CDK code instead of having to
manage your Kubernetes applications through a separate system.One of the implications of this design is that, by default, the user who
provisioned the AWS CloudFormation stack (executedcdk deploy) will
not have administrative privileges on the EKS cluster.Additional resources will be synthesized into your template (the AWS Lambda
function, the role and policy).As described inInteracting with Your Cluster,
if you wish to be able to manually interact with your cluster, you will need
to map an IAM role or user to thesystem:mastersgroup. This can be either
done by specifying amastersRolewhen the cluster is defined, callingcluster.awsAuth.addMastersRoleor explicitly mapping an IAM role or IAM user to the
relevant Kubernetes RBAC groups usingcluster.addRoleMappingand/orcluster.addUserMapping.If you wish to disable the programmatic kubectl behavior and use the standard
AWS::EKS::Cluster resource, you can specifykubectlEnabled: falsewhen you define
the cluster:eks.Cluster(self,"cluster",kubectl_enabled=False)Take care: a change in this property will cause the cluster to be destroyed
and a new cluster to be created.When kubectl is disabled, you should be aware of the following:When you log-in to your cluster, you don't need to specify--role-arnas
long as you are using the same user that created the cluster.As described in the Amazon EKS User Guide, you will need to manually
edit theaws-auth ConfigMapwhen you add capacity in order to map the IAM instance role to RBAC to allow nodes to join the cluster.Anyeks.ClusterAPIs that depend on programmatic kubectl support will fail
with an error:cluster.addResource,cluster.addChart,cluster.awsAuth,props.mastersRole.Helm ChartsTheHelmChartconstruct orcluster.addChartmethod can be used
to add Kubernetes resources to this cluster using Helm.The following example will install theNGINX Ingress Controllerto you cluster using Helm.# cluster: eks.Cluster# option 1: use a constructeks.HelmChart(self,"NginxIngress",cluster=cluster,chart="nginx-ingress",repository="https://helm.nginx.com/stable",namespace="kube-system")# or, option2: use `addChart`cluster.add_chart("NginxIngress",chart="nginx-ingress",repository="https://helm.nginx.com/stable",namespace="kube-system")Helm charts will be installed and updated usinghelm upgrade --install.
This means that if the chart is added to CDK with the same release name, it will try to update
the chart in the cluster. The chart will exists as CloudFormation resource.Helm charts are implemented as CloudFormation resources in CDK.
This means that if the chart is deleted from your code (or the stack is
deleted), the nextcdk deploywill issue ahelm uninstallcommand and the
Helm chart will be deleted.When there is noreleasedefined, the chart will be installed with a unique name allocated
based on the construct path.RoadmapAutoScaling (combine EC2 and Kubernetes scaling)