Integrating AWS ECR, EKS with Azure DevOps

The idea of this article is to share a need I encountered while conducting a POC, where it was necessary to perform the CI/CD flow using two clouds, AWS and Azure. Since I couldn't find a centralized place containing this information and had to read several articles on the topics, I decided to compile everything into one article.

Requirements

For this article, you will need: An account on Azure DevOps and AWS Cloud.

Architecture

CI/CD Flow

CI (Continuous Integration): This is the process of automating the integration of code from different contributors into a single software project. The goal is that whenever a developer commits (sends) new changes to the source code, that code is automatically tested and integrated with the rest of the project.

Characteristics of CI include:

  • Automated Testing: Every time there is a new code submission, a CI system runs automated tests to ensure that the change does not break anything in the project.

  • Quick Feedback: Developers receive immediate feedback on the integration of their code, allowing for quick corrections in case of errors.

CD (Continuous Delivery): This practice extends CI by automating the delivery of code to test or production environments after the integration process.

In Continuous Delivery, important characteristics are:

  • Automated Deployment: After code integration, the system automates deployment to test and/or production environments.

  • Reduced Release Time: With automated processes, the time to deliver new features and fixes to end users is significantly reduced. ECR

AWS ECR

AWS ECR (Amazon Elastic Container Registry) is a container registry service in the Amazon Web Services cloud. Its main goal is to store, manage, and deploy Docker container images. It provides a secure and scalable place to store and manage your container images, facilitating integration with container development, delivery, and deployment tools on AWS.

EKS

AWS EKS (Amazon Elastic Kubernetes Service) is a managed Kubernetes service in the Amazon Web Services cloud. Its primary goal is to provide an environment for running containerized applications using Kubernetes, a container orchestration system, without the need to install, operate, and maintain your own Kubernetes management infrastructure. EKS makes it easy to run containerized applications at scale in the AWS cloud.

Azure DevOps Pipeline

Azure DevOps is a set of software development tools from Microsoft, designed to support continuous integration, continuous delivery, project planning, source code collaboration, and application monitoring. Its goal is to facilitate collaboration between teams, automate development and delivery pipelines, and efficiently manage software projects, helping organizations build, test, and release software faster and more reliably.

I drew the diagram below to bring something more visual and make it easier to understand, so let's discuss the proposed solution. In the diagram, we can see some components. I will detail only EKS, ECR, and Azure DevOps.

  • ECR is used to store the Docker image generated by Azure DevOps.

  • AWS EKS is used here to run the application. A node group with the node and pods for running the application was created, and it has a load balancer with external access.

  • Azure DevOps runs all the pipeline commands, builds the app, generates the Docker image, sends the image to ECR, and deploys the image to EKS via AWS Shell Script.

Detailing the POC

The first step is to create an AWS account; take advantage of the free tier plan with 12 months free, click here. It's also necessary to create an Azure DevOps account, which can also be created for free with some limitations, click here.

Now let's create the services we will use, starting with AWS:

  • For ECR, the process is very simple and can be done using the AWS guide, clicking here. In the image, we can see the summary of the created ECR.

  • For EKS, the process can also be done using the AWS interface following these steps.

It's also necessary to create the node group, which basically creates an EC2 to instantiate the pods according to the desired configuration. To create the node group, we can use this detailed AWS material.

Points of Attention:

  • It's recommended to create EKS and ECR in the same region;

  • It's recommended to create a private ECR for greater security;

  • It's recommended not to use the AWS root user to create the services;

  • Make sure to create the correct roles EKSClusterRole and EKSNodeRole as mentioned in the links to avoid permission issues. In this POC, ECR, EKS, and Node group are within the same VPC to avoid connectivity issues;

  • Once ECR and EKS are created, let's configure Azure DevOps. I will skip the project and repository creation steps, but you can find them here.

Once ECR and EKS are created, let's configure Azure DevOps. I will skip the project and repository creation steps, but you can find them here.

The first configuration to be done is setting up the variables as shown in the image below. You should create a variable group called dev and add the AWS variables: Account key, Access key, secret, region, and repository name, all the data from AWS.

Now you can create a pipeline and configure it as follows.

For the POC, we can use a simple React project that contains the azure-pipeline file with all the configuration to build, generate the Docker image, send it to AWS ECR, and deploy it to EKS. The file can be found here and imported during the pipeline configuration as shown in the image below.

Points of Attention:

  • Don't forget to change the variables in the Azure YAML;

  • In the YAML, it is also possible to change the Load Balance port, the default is 80;

After the configuration is done, just run the pipeline and wait for the entire process as shown in the image below.

Troubleshooting

Errors encountered during the POC.

  • Failed to pull image …. no such host: In this case, we had a network issue where we had to configure the AWS network. In this link, you can perform connectivity tests between network points, instances, to identify any point of interruption.

  • Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB: In this case, it was unable to create the LoadBalancer. We used the configuration below to force the creation of the LoadBalancer. annotations: service.beta.kubernetes.io/aws-load-balancer-internal: "true" Here are some other error cases in EKS.

annotations:
          service.beta.kubernetes.io/aws-load-balancer-internal: "true"

Cost Simulation

To understand the solution's feasibility in terms of cost, I generated a small table containing the involved costs and the final monthly amount. Obviously, this is an estimate but can be useful for having a baseline for a real project.

To reach this value, I used the AWS services calculator in this link.

https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html

https://dev.to/aws-builders/provisioning-infrastructure-on-aws-using-azure-devops-3g75

https://learn.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml

https://repost.aws/knowledge-center/eks-pod-status-troubleshooting

https://blog.searce.com/aws-pipeline-to-create-ecr-image-ci-and-deploy-cd-nodejs-application-on-eks-a9550add782c

https://learnk8s.io/deploying-nodejs-kubernetes-eks

https://www.freecodecamp.org/news/build-and-push-docker-images-to-aws-ecr/

https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/annotations/#lb-scheme

Did you find this article valuable?

Support Leandro Martins by becoming a sponsor. Any amount is appreciated!