Automate Sitecore Based Images with ACR Tasks

In my last article I walked through the basics of ACR Tasks. As a quick recap,

ACR Tasks is a set of features which provide cloud-based image building for images based on Linux, Windows, and ARM without having to install the docker engine (and Docker Desktop) locally. Images are built and pushed to the registry for you. ACR Tasks covers the following scenarios

I was led to investigate options for better managing my image builds after having to perform an uninstall of docker and loosing a number of images that had never been pushed to any registry. (That is part of the sales-pitch of docker images, is the ability to grab an application from the cloud and start working from anywhere.)

The Plan

The first step of images that I like to have is what I have called the Organization Images or base images. Organization Images start with the Sitecore provided images and then layer in the appropriate asset images for the different features. These images are what will be used as the base for any future sites. I will be using my dotnet CLI Templates to help provide the starting structure for our conversion to ACR Tasks. The converted file set to ACR Tasks can be found in the TheCodeAttic.ACRTask.SitecoreImages Repository.

The first step in the process it so convert the .env file into a YAML based file to still allow us to take advantage of centrally managed variables for our image build. To accomplish this the following steps will need to be taken:

  1. Rename from .env to env.yml
  2. Open the new file and perform a simple Find and Replace All changing = to :
  3. Currently ACR Tasks only support alphanumeric characters in alias (key) names, thus need to run a Find and Replace All changing ___ to non-blank or other alphanumeric based seperator you like. This results in something that looks like this
.env file used with docker-compose vs env.yml for use with ACR Taks

In the ACR Task the build sequence is controlled not by a docker-compose file but through a tasks YAML file. Thus we will need to convert each image build into a step within the task YAML file. To see how this plays out we will convert the build instructions for the base SQL image and the SXA SQL image. Thus the Docker-compose is as follows:

version: "3.8"
services:
  mssql-spe:
    image: ${REGISTRY}${COMPOSE_PROJECT_NAME}/mssql-spe:${VERSION:-latest}
    build:
      context: ${SERVICES_PATH}/mssql-spe
      args:
        BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}${SQL_BASE_IMAGE}:${SITECORE_VERSION}
        SPE_IMAGE: ${SITECORE_MODULE_REGISTRY}${SPE_ASSET_IMAGE}
  mssql-sxa:
    image: ${REGISTRY}${COMPOSE_PROJECT_NAME}/mssql-sxa:${VERSION:-latest}
    build:
      context: ${SERVICES_PATH}/mssql-sxa
      args:
        BASE_IMAGE: ${REGISTRY}${COMPOSE_PROJECT_NAME}/mssql-spe:${VERSION:-latest}
        SXA_IMAGE: ${SITECORE_MODULE_REGISTRY}${SXA_ASSET_IMAGE}

The boilerplate for the task YAML, includes setting a version and making reference to the variables or as known within ACR Tasks the aliases which can be referenced.

version: v1.1.0
alias:
  src:
    - env.yml
steps:

Steps is technically an array, so we will identify the first step via the key word *id assigning our reference name to the step/image build. The id value can then be used in other steps to create dependency hierarchy, controlling when the next thing can build.

version: v1.1.0
alias:
  src:
    - env.yml
steps:
  - id: mssql-spe
  - id: mssql-sxa

This task file would successfully run, just not create any images for you, we need to provide the build instructions. To do this the key work build is added. The value here is the full docker build command you would normally enter, so sadly becomes very verbose if there are a number of build arguments required. All values pre-fixed with $ (dollar-sign) reference either a default alias (‘$Registry’ represents the current ACR) or an alias defined in our source file, such as ‘$ComposeProjectName’ which will be substituted for ‘sc-base’.

version: v1.1.0
alias:
  src:
    - env.yml
steps:
  - id: mssql-spe
    build: -t $Registry/$ComposeProjectName/mssql-spe:$TagVersion -t $Registry/$ComposeProjectName/mssql-spe:latest -f $ServicesPath/mssql-spe/Dockerfile . --build-arg BASE_IMAGE=$SitecoreDockerRegistry$SQLBaseImage:$SitecoreVersion --build-arg SPE_IMAGE=$Registry/$SPEAssetImage
  - id: mssql-sxa
    build: -t $Registry/$ComposeProjectName/mssql-sxa:$TagVersion -t $Registry/$ComposeProjectName/mssql-sxa:latest -f $ServicesPath/mssql-sxa/Dockerfile . --build-arg BASE_IMAGE=$Registry/$ComposeProjectName/mssql-spe:$TagVersion --build-arg SXA_IMAGE=$SitecoreModuleRegistry$SXAAssetImage

I want to call specific attention to the -f $ServicesPath/mssql-spe/Dockerfile . segment of the build value. This is used to identify the Dockerfile which will be built, and can be managed in a nested folder setup as we are use to with the standard template, but you must also include the context location of the directory and file, this is best done by basing the pathing off the root, where the task file lives and setting to a dot.

Where as a docker-compose file will run top to bottom, ACR Tasks provides us the opportunity to build things in parallel or in ‘top-to-bottom’ fashion as well as allows us to setup dependencies between images. This type of control logic is accomplished by the key when. This is set to an array of strings, with the strings being the id of steps that are a pre-requisite for completion. If you set when to be just dash ( – ), then those steps get built in parallel, while not setting at all step order becomes top-to-bottom.

Given the mssql-sxa relies on the base mssql-spe to be completed we can setup the following dependencies:

version: v1.1.0
alias:
  src:
    - env.yml
steps:
  - id: mssql-spe
    build: -t $Registry/$ComposeProjectName/mssql-spe:$TagVersion ... # shortened for readability
    when: ["-"] # run in parallel to other images
  - id: mssql-sxa
    build: -t $Registry/$ComposeProjectName/mssql-sxa:$TagVersion ... # shortened for readability
    when: ["mssql-spe"] # only start the build once mssql-spe has completed

By default a build step via ACR Task does not push the created image to the registry. This happens to allow an image to be built and used for testing scenarios or as an intermediate step before the final image is pushed to the registry. Therefore we must add the key push to indicate what images we want push into the registry. Push can be set to a JSON array of image names or by expanded using the YAML dash syntax.

version: v1.1.0
alias:
  src:
    - env.yml
steps:
  - id: mssql-spe
    build: -t $Registry/$ComposeProjectName/mssql-spe:$TagVersion ... # shortened for readability
    when: ["-"]
  - push: # push list via YAML expanded syntax, my preferred mehtod for readability
    - $Registry/$ComposeProjectName/mssql-spe:$TagVersion
    - $Registry/$ComposeProjectName/mssql-spe:latest
  - id: mssql-sxa
    build: -t $Registry/$ComposeProjectName/mssql-sxa:$TagVersion ... # shortened for readability
    when: ["mssql-spe"]
  - push: ["$Registry/$ComposeProjectName/mssql-sxa:$TagVersion", "$Registry/$ComposeProjectName/mssql-sxa:latest"]

Task Setup

With our files all edited and ready, we need to upload them to a Git based repository, this could be in GitHub or Azure DevOps. To help speed you along you can clone/fork mine from https://github.com/gillissm/TheCodeAttic.ACRTask.SitecoreImages. As of the writing of this ACR Tasks can only be created via the Azure CLI which can be installed following https://docs.microsoft.com/en-us/cli/azure/install-azure-cli.

As you will find in TheCodeAttic.ACRTask.SitecoreImages Repository, you will see that I have included specific task files for each set of base images, ie CM, SQL, etc…This has allowed me to create very targeted (as well as shorter) tasks that I can trigger as needed based on potential changes. To futher separate and allow for a level of automation each task set has been loosely associated to a specific branch within int he repository.

In continuing with our SQL base image example the create task command is

# Create code commit trigger task
az acr task create `
# must provide a unique name for the task
  -n SitecoreBaseImages-SQL ` 
# must indicate the registry name
  --registry thecodeatticimages ` 
# name of the task YAML that will be run, is expected to be at the root of the repository
  --file sc-base-sql.yml `
# URL to the repository including the branch name that commit trigger will watch
  --context 'https://github.com/gillissm/TheCodeAttic.ACRTask.SitecoreImages.git#sql' `
# default image building is Linux, so must indicate the platform as windows
  --platform windows/amd64 `
# automating the task tied to commits against the branch
  --commit-trigger-enabled true `
# automating the task to rebuild if any referenced images are updated
  --base-image-trigger-enabled true `
# pass a PAT to allow for the commit-trigger web hook to successfully be setup
  --git-access-token <personal_access_token>

Run the Task

You can trigger the task via simply making a commit to the branch, even a blank commit will trigger it or using the CLI run command.

# Manually trigger an ACR Task
az acr task run --registry thecodeatticimages --name SitecoreBaseImages-SQL

Some Quick Troubleshooting Notes

One major issue I ran into while setting up the ACR Tasks is there is currently a limit to how updated the ACR system is to for Windows based image builds. As it turns out the ACR host is limited to OS version 10.0.19041, which translates to no images based on 20H2 or newer currently. I found the most recent I could use was *2004 tagged images. This is a ticketed ACR issue, with no indication of a fix, https://github.com/Azure/acr/issues/532.

  • You may experience failed tasks due to a timeout when communitcating to the Sitecore image repository, at this time I’m not clear how to resolve said issue directly. There is some ACR documentation which discusses the importing of public images, such as the Sitecore created ones, to avoid this type of issue. I have not tried a POC this, but you can read more about it at https://docs.microsoft.com/en-us/azure/container-registry/tasks-consume-public-content to see if it will be of benifit for you needs.

References

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.