AWS DevOps & Developer Productivity Blog
Deploy container applications in a multicloud environment using Amazon CodeCatalyst
In the previous post of this blog series, we saw how organizations can deploy workloads to virtual machines (VMs) in a hybrid and multicloud environment. This post shows how organizations can address the requirement of deploying containers, and containerized applications to hybrid and multicloud platforms using Amazon CodeCatalyst. CodeCatalyst is an integrated DevOps service which enables development teams to collaborate on code, and build, test, and deploy applications with continuous integration and continuous delivery (CI/CD) tools.
One prominent scenario where multicloud container deployment is useful is when organizations want to leverage AWS’ broadest and deepest set of Artificial Intelligence (AI) and Machine Learning (ML) capabilities by developing and training AI/ML models in AWS using Amazon SageMaker, and deploying the model package to a Kubernetes platform on other cloud platforms, such as Azure Kubernetes Service (AKS) for inference. As shown in this workshop for operationalizing the machine learning pipeline, we can train an AI/ML model, push it to Amazon Elastic Container Registry (ECR) as an image, and later deploy the model as a container application.
Scenario description
The solution described in the post covers the following steps:
- Setup Amazon CodeCatalyst environment.
- Create a Dockerfile along with a manifest for the application, and a repository in Amazon ECR.
- Create an Azure service principal which has permissions to deploy resources to Azure Kubernetes Service (AKS), and store the credentials securely in Amazon CodeCatalyst secret.
- Create a CodeCatalyst workflow to build, test, and deploy the containerized application to AKS cluster using Github Actions.
The architecture diagram for the scenario is shown in Figure 1.
Figure 1 – Solution Architecture
Solution Walkthrough
This section shows how to set up the environment, and deploy a HTML application to an AKS cluster.
Setup Amazon ECR and GitHub code repository
Create a new Amazon ECR and a code repository. In this case we’re using GitHub as the repository but you can create a source repository in CodeCatalyst or you can choose to link an existing source repository hosted by another service if that service is supported by an installed extension. Then follow the application and Docker image creation steps outlined in Step 1 in the environment creation process in exposing Multiple Applications on Amazon EKS. Create a file named manifest.yaml as shown, and map the “image” parameter to the URL of the Amazon ECR repository created above.
apiVersion: apps/v1
kind: Deployment
metadata:
name: multicloud-container-deployment-app
labels:
app: multicloud-container-deployment-app
spec:
selector:
matchLabels:
app: multicloud-container-deployment-app
replicas: 2
template:
metadata:
labels:
app: multicloud-container-deployment-app
spec:
nodeSelector:
"beta.kubernetes.io/os": linux
containers:
- name: ecs-web-page-container
image: <aws_account_id>.dkr.ecr.us-west-2.amazonaws.com/<my_repository>
imagePullPolicy: Always
ports:
- containerPort: 80
resources:
limits:
memory: "100Mi"
cpu: "200m"
imagePullSecrets:
- name: ecrsecret
---
apiVersion: v1
kind: Service
metadata:
name: multicloud-container-deployment-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: multicloud-container-deployment-app
Push the files to Github code repository. The multicloud-container-app github repository should look similar to Figure 2 below
Figure 2 – Files in Github repository
Configure Azure Kubernetes Service (AKS) cluster to pull private images from ECR repository
Pull the docker images from a private ECR repository to your AKS cluster by running the following command. This setup is required during the azure/k8s-deploy Github Actions in the CI/CD workflow. Authenticate Docker to an Amazon ECR registry with get-login-password by using aws ecr get-login-password. Run the following command in a shell where AWS CLI is configured, and is used to connect to the AKS cluster. This creates a secret called ecrsecret, which is used to pull an image from the private ECR repository.
kubectl create secret docker-registry ecrsecret\
--docker-server=<aws_account_id>.dkr.ecr.us-west-2.amazonaws.com/<my_repository>\
--docker-username=AWS\
--docker-password= $(aws ecr get-login-password --region us-west-2)
Provide ECR URI in the variable “–docker-server =”.
CodeCatalyst setup
Follow these steps to set up CodeCatalyst environment:
- Create a CodeCatalyst space and associated AWS account.
- Create a CodeCatalyst project.
- A CodeCatalyst environment connected to the AWS account, where the ECR repository is configured.
Configure access to the AKS cluster
In this solution, we use three GitHub Actions – azure/login, azure/aks-set-context and azure/k8s-deploy – to login, set the AKS cluster, and deploy the manifest file to the AKS cluster respectively. For the Github Actions to access the Azure environment, they require credentials associated with an Azure Service Principal.
Service Principals in Azure are identified by the CLIENT_ID, CLIENT_SECRET, SUBSCRIPTION_ID, and TENANT_ID properties. Create the Service principal by running the following command in the azure cloud shell:
az ad sp create-for-rbac \
--name "ghActionHTMLapplication" \
--scope /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP> \
--role Contributor \
--sdk-auth
The command generates a JSON output (shown in Figure 3), which is stored in CodeCatalyst secret called AZURE_CREDENTIALS. This credential is used by azure/login Github Actions.
Figure 3 – JSON output
Configure secrets inside CodeCatalyst Project
Create three secrets CLUSTER_NAME (Name of AKS cluster), RESOURCE_GROUP(Name of Azure resource group) and AZURE_CREDENTIALS(described in the previous step) as described in the working with secret document. The secrets are shown in Figure 4.
Figure 4 – CodeCatalyst Secrets
CodeCatalyst CI/CD Workflow
To create a new CodeCatalyst workflow, select CI/CD from the navigation on the left and select Workflows (1). Then, select Create workflow (2), leave the default options, and select Create (3) as shown in Figure 5.
Figure 5 – Create CodeCatalyst CI/CD workflow
Add “Push to Amazon ECR” Action
Add the Push to Amazon ECR action, and configure the environment where you created the ECR repository as shown in Figure 6. Refer to adding an action to learn how to add CodeCatalyst action.
Figure 6 – Create ‘Push to ECR’ Action
Select the Configuration tab and specify the configurations as shown in Figure7.
Figure 7 – Configure ‘Push to ECR’ Action
Configure the Deploy action
1. Add a GitHub action for deploying to AKS as shown in Figure 8.
Figure 8 – Github action to deploy to AKS
2. Configure the GitHub action from the configurations tab by adding the following snippet to the GitHub Actions YAML property:
- name: Install Azure CLI
run: pip install azure-cli
- name: Azure login
id: login
uses: azure/login@v1.4.3
with:
creds: ${Secrets.AZURE_CREDENTIALS}
- name: Set AKS context
id: set-context
uses: azure/aks-set-context@v3
with:
resource-group: ${Secrets.RESOURCE_GROUP}
cluster-name: ${Secrets.CLUSTER_NAME}
- name: Setup kubectl
id: install-kubectl
uses: azure/setup-kubectl@v3
- name: Deploy to AKS
id: deploy-aks
uses: Azure/k8s-deploy@v4
with:
namespace: default
manifests: manifest.yaml
pull-images: true
Figure 9 – Github action configuration
3. The workflow is now ready and can be validated by choosing ‘Validate’ and then saved to the repository by choosing ‘Commit’.
We have implemented an automated CI/CD workflow that builds the container image of the application (refer Figure 10), pushes the image to ECR, and deploys the application to AKS cluster. This CI/CD workflow is triggered as application code is pushed to the repository.
Figure 10 – Automated CI/CD workflow
Test the deployment
When the HTML application runs, Kubernetes exposes the application using a public facing load balancer. To find the external IP of the load balancer, connect to the AKS cluster and run the following command:
kubectl get service multicloud-container-deployment-service
The output of the above command should look like the image in Figure 11.
Figure 11 – Output of kubectl get service
Paste the External IP into a browser to see the running HTML application as shown in Figure 12.
Figure 12 – Application running in AKS
Cleanup
If you have been following along with the workflow described in the post, you should delete the resources you deployed so you do not continue to incur charges. First, delete the Amazon ECR repository using the AWS console. Second, delete the project from CodeCatalyst by navigating to Project settings and choosing Delete project. There’s no cost associated with the CodeCatalyst project and you can continue using it. Finally, if you deployed the application on a new AKS cluster, delete the cluster from the Azure console. In case you deployed the application to an existing AKS cluster, run the following commands to delete the application resources.
kubectl delete deployment multicloud-container-deployment-app
kubectl delete services multicloud-container-deployment-service
Conclusion
In summary, this post showed how Amazon CodeCatalyst can help organizations deploy containerized workloads in a hybrid and multicloud environment. It demonstrated in detail how to set up and configure Amazon CodeCatalyst to deploy a containerized application to Azure Kubernetes Service, leveraging a CodeCatalyst workflow, and GitHub Actions. Learn more and get started with your Amazon CodeCatalyst journey!
If you have any questions or feedback, leave them in the comments section.