Rolling Deployments
Objective
Create a service deployment that automatically updates with a newly built image for each commit pushed to your git repository.
Prerequisites
-
Complete: CI / CD Getting Started Guide
-
This guide assumes that you already have application code and a corresponding Dockerfile committed and pushed to your version control system.
Background
A common practice in software development is to have an environment such as development
that is running
the latest code on the primary integration branch of your git repository (e.g., main
).
We will demonstrate how to easily accomplish this using the Panfactum CI / CD system.
Build and Push Image from Dockerfile
First, you need to build and push an image based on the Dockerfile in your repository. We provide a submodule that will create a WorkflowTemplate that does this for you: wf_dockerfile_build.
Add this submodule to your CI / CD module that you created in the Getting Started guide. As an example of how this might look, you can reference our CI / CD module for this website.
Note that the images generated by the Workflow are tagged with the commit hash that was checked out for the build.
Before proceeding, ensure you have used the WorkflowTemplate to successfully create a build of your repo's Dockerfile.
Deploy the Image
Next, you must deploy your image using IaC. We provide an example of our
website service
as well as the terragrunt.hcl
that we use to deploy it.
Notice that our module has an input called website_image_version
which is set in terragrunt.hcl
as follows:
website_image_version = run_cmd("--terragrunt-quiet", "pf-get-commit-hash", "--ref=main", "--repo=https://github.com/panfactum/stack")
The run_cmd function is a Terragrunt feature that allows you to call an external command as your Terragrunt code is evaluated. The stdout from this call is then returned by the function.
We provide a command in the devShell
called pf-get-commit-hash
that takes a git reference
and a repository URL and returns the commit hash that reference points to.
By choosing main
, our module will deploy the image corresponding to the latest commit on the main
branch.
Before proceeding, ensure you can successfully deploy and run your service. Commit and push this new IaC so that we can pull it in the Workflows we create in the following step.
Combine WorkflowTemplates
Next, we must create a WorkflowTemplate the combines both the wf_dockerfile_build
logic
and the wf_tf_deploy
logic (created in the Getting Started guide).
This new WorkflowTemplate will reuse the existing WorkflowTemplates to first build the image and then deploy it.
This composition pattern is described in our guide for triggering Workflow. The full code for our website example can be found here, but the following snippets deserve an explanation:
Snippet 1
This code combines templates from the WorkflowTemplates created by the wf_dockerfile_build
and wf_tf_deploy
submodules and then
runs them in sequence. The entrypoint
output of each submodule refer to the name of the entry / root template
of that WorkflowTemplate. 1
templates = [
{
name = "entry",
dag = {
tasks = [
{
name = "build-image"
templateRef = {
name = module.website_builder.name
template = module.website_builder.entrypoint
}
},
{
name = "deploy-image"
templateRef = {
name = module.tf_deploy.name
template = module.tf_deploy.entrypoint
}
depends = "build-image"
}
]
}
}
]
Snippet 2
This code passes the git_ref
and tf_apply_dir
parameters to each reference template. For this Workflow,
we want to build from the main
branch and then apply only the pf_website
module.
passthrough_parameters = [
{
name = "git_ref"
value = "main"
},
{
name = "tf_apply_dir"
value = "packages/reference/environments/production/us-east-2/pf_website"
}
]
Once you have created an analogous WorkflowTemplate in your IaC, deploy it. You should now see it in the Argo web dashboard. If you create a new Workflow from the WorkflowTemplate, it should successfully run a combined execution graph of both the build and deploy Workflow:
Connect to CI / CD Webhooks
Finally, you can now connect this new WorkflowTemplate to the Argo Sensor for your CI / CD pipeline. This
will allow you to trigger a new Workflow from this WorkflowTemplate whenever you push to main
(or whichever
branch you want to use to automatically trigger deployments).
Here is an example of how we do this for our website.