We assume you’ve already forked the IRIS project to your own private repository. It’s called <username>/my-objectscript-rest-docker-template in this article. <root_repo_dir> is its root directory.
Before getting started, install the AWS command-line interface and, for Kubernetes cluster creation, eksctl, a simple CLI utility. For AWS you can try to use aws2, but you’ll need to set aws2 usage in kube config file as described here.
Like AWS resources in general, EKS is not free. But you can create a free-tier account to play with AWS features. Keep in mind, though, that not everything you want to play with is included in the free tier. So, to manage your current budget and understand the financial issues, read this and this.
We’ll assume you already have an AWS account and root access to it, and that you don’t use this root access but have created a user with admin permissions. You’ll need to put the access key and secret key of this user into the AWS credentials file under the [dev] profile (or whatever you choose to name the profile):
We’re going to create resources in the AWS “eu-west-1” region, but you should choose the region closest to your location and replace “eu-west-1” by your region everywhere below in the text.
By the way, all needed files (.circleci/, eks/, k8s/) are also stored here to simplify copying and pasting.
All required EKS resources will be created from scratch. You’ll find the Amazon EKS Workshop to be a good resource to get an initial impression.
Now let’s check our access to AWS (we’ve used a dummy account here):
We could run “eksctl create cluster <cluster_name> --region eu-west-1” now, relying on the fact that all the default settings are good for us, or we can manage our own settings by creating a configuration file and using it.
The latter is preferable because it allows you to store such a file in a version control system (VCS). Examples of configurations can be found here. After reading about the different settings here, let’s try to create our own configuration:
Note that "nodeGroups.desiredCapacity = 1" would make no sense in a production environment, but it’s fine for our demo.
Also note that AMI images could differ between regions. Look for "amazon-eks-node-1.14" and choose one of the latest:
Now let’s create the cluster—the control plane and worker nodes:
By the way, when you no longer need a cluster, you can use the following to delete it:
Creating a cluster takes about 15 minutes. During this time you can look at the eksctl output:
You can also view the CloudFormation console, which will have two stacks. You can drill down into each one and look at the Resources tab to see exactly what will be created, and at the Events tab to check the current state of the resources creation.
The cluster was successfully created, although you can see in the eksctl output that we had difficulties connecting to it: "unable to use kubectl with the EKS cluster".
Let's fix this by installing the aws-iam-authenticator (IAM) and using it to create a kube context:
It should work now, but we created a cluster with a user who has administrator rights. For the regular deployment process from CircleCI, it’s better to create a special AWS user, named, in this case, CircleCI, with only programmatic access and the following policies attached:
The first policy is built into AWS, so you only need to select it. The second one should be created on your own. Here is a creation process description. The policy “AmazonEKSDescribePolicy” should look like:
After user creation, save the user’s access key and secret access key — we’ll need them soon.
We also want to give this user rights within the Kubernetes cluster itself, as described in this article. In short, after creating the EKS cluster, only the IAM user, creator, has access to it. To add our CircleCI user, we need to replace default empty "mapUsers" section in the cluster AWS authentication settings (configmap aws-auth, 'data' section) by the following lines using kubectl edit (use your own Account Id instead of ‘01234567890’):
We’ll use the Kubernetes manifests from the earlier article (see the “Google Cloud Prerequisites” section) with one change: in the deployment image field we use placeholders. We’ll store those manifests in the <root_repo_dir>/k8s directory. Note that the deployment file was renamed to deployment.tpl:
The deployment process on the CircleCI side is similar to the process used for GKE:
- Pull the repository
- Build the Docker image
- Authenticate with Amazon Cloud
- Upload the image to Amazon Elastic Container Registry (ECR)
- Run the container based on this image in AWS EKS
Like last time, we’ll take advantage of already created and tested CircleCI configuration templates: orbs.
- aws-ecr orb for building an image and pushing it to ECR
- aws-eks orb for AWS authentication
- kubernetes orb for Kubernetes manifests deployment
Our deployment configuration looks like this:
The Workflows section contains a list of jobs, each of which can be either called from an orb, such as aws-ecr/build-and-push-image, or defined directly in the configuration using “deploy-application”.
The following code means that the deploy-application job will be called only after the aws-ecr/build-and-push-image job finishes:
The Jobs section contains a description of the deploy-application job, with a list of steps defined, including:
- checkout, to pull from a Git repository
- run, to run a script that dynamically sets the Docker-image repository and tag
- aws-eks/update-kubeconfig-with-authenticator, which uses aws-iam-authenticator to set up a connection to Kubernetes
- kubernetes/create-or-update-resource, which is used several times as a way to run “kubectl apply” from CircleCI
We use variables and they, of course, should be defined in CircleCI on the “Environment variables” tab:
The following table shows the meaning of the variables used:
|AWS_ACCESS_KEY_ID||Access key of CircleCI IAM user|
|AWS_SECRET_ACCESS_KEY||Secret key of CircleCI IAM user|
|AWS_REGION||eu-west-1, in this case|
URL of the AWS ECR Docker Registry, such as 01234567890.dkr.ecr.eu-west-1.amazonaws.com
where ‘01234567890’ is the account ID
Here’s how we trigger the deployment process:
This will show the two jobs in this workflow:
Both jobs are clickable, and this allows you to see details of the steps taken.
Deployment takes several minutes. Once it completes, we can check the status of the Kubernetes resources and of the IRIS application itself:
Allow several minutes to propagate the DNS-record. Until then you’ll receive a “Could not resolve host” error when running curl:
At first glance, deployment to AWS EKS looks more complex than to GKE, but it’s not really much different. If your organization uses AWS, you now know how to add Kubernetes to your stack.
Note that the EKS API was recently extended to support managed groups. These allow you to deploy the control plane and the data plane as a whole, and they look promising. Moreover, Fargate, the AWS serverless compute engine for containers, is now available.
Finally, a quick note about AWS ECR: don’t forget to set up a lifecycle policy for your images.