Trigger Azure DevOps Build pipeline from Docker image update
Tags: azure, azuredevops, docker
Published: 2020-04-18 00:52:37

---
title: Trigger Azure DevOps Build pipeline from Docker image update
published: true
canonical_url: https://larryclaman.github.io/post/2019-11-10-trigger-docker-build-azdo/
tags: Azure,AzureDevOps,Docker
---
_Originally published at [Larry Claman's Blog](https://larryclaman.github.io/post/2019-11-10-trigger-docker-build-azdo/)_


## How to trigger a build?
I was recently asked how to trigger a classic (gui) Azure DevOps build pipeline when a Docker base image updates.  You might want to do this, for example, if your build pipeline includes unit, functional, or security tests.


My immediate answer was "you can't."  However, after a little investigation and a little hacking, I was able to prototype a solution using the [automated trigger & build feature](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-tutorial-base-image-update) of Azure Container Registry (ACR).  The hint for how to do this was buried in the [Q&A](https://github.com/MicrosoftDocs/azure-docs/issues/34480) on documentation page, where it's suggested to use a dummy image to trigger the AzDo pipeline.  Here's a walkthrough of how I did this:

## Sample Repo & Pipeline
As a sample repo, I used the canonical [Azure voting app](https://dev.azure.com/larrydevopstest/_git/AzureVotingApp), but I simplified it a bit to suit my needs. My Dockerfile is pretty simple; my goal is for the build pipeline to run whenever the base python:3.6-slim image is updated on Dockerhub.

### Step 1:  Create a dummy base image and task in ACR
As I mentioned above, I'm going to build a dummy base image using ACR, and then use a webhook when this image updates to trigger my Azure DevOps pipeline.

First, I'll need to follow the instructions [here](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-tutorial-base-image-update) to create a dummy base image and a task to update it when its reference base updates on Dockerhub.

Dummy Dockerfile for base image:
```
FROM python:3.6-slim
```

To start, build the base image in ACR:
```
ACR_NAME=larrymsvoting
REPO="https://larrydevopstest@dev.azure.com/larrydevopstest/AzureVotingApp/_git/AzureVotingApp"
DOCKER_FILE="azure-vote/Dockerfile-pythonbase"

az acr build --registry $ACR_NAME -t baseimages/python-3.6-slim-base \
    --file $DOCKER_FILE $REPO
    
```
### Step 2: Create a task

```
az acr task create \
    --registry $ACR_NAME \
    --name taskpythonbase \
    -t baseimages/python-3.6-slim-base:{{.Run.ID}} \
    --arg REGISTRY_NAME=$ACR_NAME.azurecr.io \
    --context $REPO \
    --file Dockerfile-pythonbase \
    --commit-trigger-enabled false \
    -o table
```
Assuming it runs successfully, you'll see output like:
```
NAME            PLATFORM    STATUS    SOURCE REPOSITORY                                                                         TRIGGERS
--------------  ----------  --------  ----------------------------------------------------------------------------------------  ----------
taskpythonbase  linux       Enabled   https://larrydevopstest@dev.azure.com/larrydevopstest/AzureVotingApp/_git/AzureVotingApp  BASE_IMAGE
```

### Step 3: Logic App
Now comes the fun part: getting the base image update to trigger a build in Azure DevOps.  We'll start by creating a logic app.
In the portal, create a logic app and give it a relevant name, eg 'pythonbasetrigger'.  In the Logic Apps Designer pane, use "When an HTTP Request is Received" as the trigger.

Add a new step, then type 'Azure DevOps' in the search field, then choose 'Queue a new build' as the action.  After authenticating, choose the account name, project name, and build id (eg, pipleline).  Once it's saved, it should like like:
![logic app](https://dev-to-uploads.s3.amazonaws.com/i/vfhuzzx2tc6uh6f7q4be.png)

You can test the logic app by pressing 'Run', which should kick off an Azure DevOps pipeline build.

Finally, in your logic apps's first step 'When an HTTP request is received', find the post URL and copy it, as it will be needed for the next step.


## Step 4: ACR webhook
Next, we'll create an ACR webhook which fires whenever the base image updates.
```
URI=<webhook post url from prior step>

az acr webhook create -n pythonbasehook -r $ACR_NAME \
    --scope baseimages/python-3.6-slim-base \
    --actions push --uri $URI
```

## Step 5: Enjoy!
We've done it!  We now have a set up a set of integrations that does the following:
![flow](https://dev-to-uploads.s3.amazonaws.com/i/hrazfxxyvx183myqsxat.png)

## Step 6: Test
Since the Dockerhub base image is only going to be updated periodically, you can test your integration by manually running a build in ACR:
```
az acr build --registry $ACR_NAME -t baseimages/python-3.6-slim-base \
    --file $DOCKER_FILE $REPO
```
If all is working, this should trigger a build in Azure DevOps.

## Final Thoughts
An alternative to using a webhook would be to use an Event Grid to trigger the Logic App.  This is slightly more work to set up, but it might better if you have a number of different pipelines that want to receive notifications when a base image updates.  With a webhook, you'd need to set up a trigger for each and every one of them.  Eventgrid, having a pubsub architecture, would fan-out one:many more effectively than webhooks.