As Continuous Integration and Continuous Delivery (CICD) continue to grow rapidly, the trend has been to put everything and anything in CICD. Infrastructure deployments, application deployments, security, unit and mock testing, and even managing Active Directory. One major technology we see continuing to grow almost daily is containerization.
In this blog post, you will learn the top five best practices for containerization with CICD from my experience.
Make Sure the Application Works
The first best practice, if not the most important, is to make sure the application works successfully. We read daily about how easy containerization is to get up and running with XYZ technology, but that isn't always the case. If you have a sophisticated application that contains backend binaries, a frontend, SQL to store persistent data, Redis cache for cached/faster data delivery, and some type of secret manager, it's not going to be as easy as throwing a few containers into Kubernetes and watching the magic happen.
The following steps should help you in creating a successful containerization test.
- Manually deploy the application. I know, CICD is supposed to get us away from manual efforts. However, you can't automate something if you don't know how to do it manually.
- Split up each part of the application inside of it's own container. For example, taking the sophisticated application example above, you would have 1 container for Redis, 1 container for SQL, 1 container for each binary, and 1 container for secret management.
- Deploy each container individually and check the logs with
docker log. The application is bound to have dependencies, for example, the binaries may need connection to the secret manager to use the connection strings from the secret manager for SQL.
- Deploy the containers locally. Since containers are so light weight, they are easily deployed on a local machine or even on a standalone virtual machine. Deploy the containers and get them working locally prior to any CICD.
- Understand what is needed from the CICD process to deploy the containers successfully. What tasks do you need in the Continuous Delivery process to deploy the containers where they need to go? What authentication methods are needed? Does the Continuous Integration process contain unit tests and create a binary, or does the code just get automatically deployed to the containers? Make sure you have a list of every dependency the CICD process will need.
Knowing Where the Containers Will Be Deployed
With the popularity increasing rapidly for containers, a ton of software-focused organizations are creating ways to host containers. For example. Azure has Azure Container Instances (ACI) and AWS has AWS Fargate. These two solutions are hosted and maintained by the cloud providers. Essentially, the only thing you need to worry about is getting the containers into the services and making sure the application is up.
However, that's not your only option. It is still more than feasible, depending on the size of the team, to host containers inside of virtual machines. Some organizations prefer to do this because they still want the control over where the containers are and how they are maintained. This is a perfectly fine approach, but keep in mind it will require a lot of team effort and possibly more hires to the team. You'll have to worry about virtual machine maintenance, monitoring, alerting, and all of the other infrastructure overhead that comes into play.
I have a buddy that created his own orchestration system using Python and Linux Containers (LXC). This certainly gives bragging rights and a spotlight on a resume because there aren't many people still doing that. Although this is a fine approach, if you don't have the numbers to maintain it, the solution will crumble. That's why most organizations today use orchestration systems that already exist, like Kubernetes.
As of now, the top two orchestration platforms for containers is Docker Swarm and Kubernetes, Kubernetes being the top one. Orchestration allows you to scale and self heal containers, allowing the application to grow and be self-maintained as much as possible. When you think of using a CICD solution, you should ensure to dive into what orchestration platform you're looking to deploy to. With the popularity of Kubernetes increasing, a ton of software organizations are throwing their hats into the ring and building around Kubernetes.
Although the application(s) and the way they are deployed or where they are deployed to may never change, you never know. Having the ability to have reusable pipelines, especially for rapidly changing software is crucial. If you hard-code everything into the pipeline, you're setting yourself up for having a cumbersome environment. Having to maintain multiple pipelines that essentially do the same thing, but maybe the only difference is that the containers get deployed to another region or another Azure subscription, for example, will result in failure.
In almost any CICD solution, there is a way to set variables and/or parameters. Ensure you always set them for key differentiators. Things like regions, subscription IDs, etc..
Building Docker Images
Building Docker images is one of the most crucial parts because if the Docker image doesn't exist, there's no application to deploy. If you are planning on deploying containers with CICD, the recommendation is to build Docker images with CICD as well.
This is a great approach because any time code is changed for the application, you can have a CI process that builds the code and a deployment process that creates a new Docker image based on that code. That way, you never have to worry about deploying an old Docker image. The application and the code is always kept up to date.
Take a look at building a Docker image with CICD using Azure DevOps, which you can find here.