Azure DevOps YAML release pipeline : Trigger when a container is pushed to Azure Container Registry
Tags: azure, devops, containerregistry
Published: 2020-07-30 07:31:17


I explain how to trigger a pipeline when another pipeline completed in [this article](https://dev.to/kenakamu/azure-devops-yaml-release-pipeline-trigger-when-build-pipeline-completed-54d5). 

This time, I demonstrate how to trigger a pipeline when docker image is pushed into Azure Container Registry.

Kudos to my teammate who did research on this :)

[Azure DevOps pipeline: container resources](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/resources?view=azure-devops&tabs=schema#resources-containers)

# Scenario

When the projects uses docker container for deployment, such as AKS, ACI, Container for WebApp, you may want to run pipeline to work with recently pushed images.

Of course you can trigger release pipeline after a build pipeline which build and push container images to ACR, however, you want to trigger any pipeline when new image is pushed to ACR, separate from build pipeline, then you can use container trigger.

# Prerequisites

I assume you already have following Azure resources

- Azure DevOps
- Azure Container Registry
- Any program to package into container
- ACI to run the container. You can use anything.

# Sample application

I just create MVC app by using dotnet core from template.

```shell
dotnet new mvc -n sampleapp
```
The Dockerfile I added is like this.

```docker
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["sampleapp.csproj", "sampleapp/"]
RUN dotnet restore "sampleapp/sampleapp.csproj"
COPY . sampleapp
WORKDIR "/src/sampleapp"
RUN dotnet build "sampleapp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "sampleapp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "sampleapp.dll"]
```
Once created the application, I simply push the code into ADO repository.

# Build Pipeline

The build pipeline simply build and push container to ACR. You need to create service connection to ACR. See [documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml#sep-docreg) for more detail.

I have "kenakamuacr" service connection which connect to my ACR.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tzwpa95r61m02b3n6ck5.png)

Below is my build pipeline yaml.

```yaml
trigger:
  branches:
    include:
    - master
  paths:
    exclude:
    - README.md

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: Docker@2
  inputs:
    containerRegistry: 'kenakamuacr'
    repository: 'sampleapp'
    command: 'buildAndPush'
    Dockerfile: './Dockerfile'
```
Once this run successfully, then I can see new image is pushed into my ACR.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pisxx2hbr2fe0jydi3fd.png)

# Release Pipeline

The trigger is very similar to pipeline resource trigger. It's defined under resources | containers. I give **sampleapp** as it's name which can be referenced later. For example, if I want to know the tag of the container image, then I can get it as **$(resources.container.sampleapp.tag)**. See [Container Resource variables](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/resources?view=azure-devops&tabs=schema#container-resource-variables) for complete list.

I then use these information to delete and re-create ACI to run the application. You can check more detail of az command for aci [here](https://docs.microsoft.com/en-us/cli/azure/container?view=azure-cli-latest)

Please replace variables to match to your environment.

```yaml
# Explicitly set none for repositry trigger
trigger:
  - none

resources:
  containers:
  - container: sampleapp
    type: ACR  
    azureSubscription: ConnectionToAzure
    resourceGroup: ADOSample
    registry: kenakamuacr
    repository: sampleapp
    trigger: true

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: AzureCLI@2
  displayName: Delete Existing container if exists
  inputs:
    azureSubscription: ConnectionToAzure
    scriptType: 'pscore'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az container delete -g ADOSample -n sampleapp --yes
    powerShellErrorActionPreference: 'silentlyContinue'
- task: AzureCLI@2
  displayName: Create Container Instance
  inputs:
    azureSubscription: ConnectionToAzure
    scriptType: 'pscore'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az container create -g ADOSample -n sampleapp --image kenakamuacr.azurecr.io/sampleapp:$(resources.container.sampleapp.tag) `
      --registry-username <username> --registry-password <password> --location <location> `
      --ports 80 443 --dns-name-label sampleapp
    powerShellErrorActionPreference: 'silentlyContinue'
```

# Test

Let's do the final test. Commit any change to master branch. It triggers build pipeline, and then release pipeline will be triggered when new image is pushed to ACR.

You can see who triggers the release pipeline, which is container image push event.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/05gnap16fjm8o3chpsav.png)

ACI is up and running as expected.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nkb82vpr4l6u9svx5r55.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ur059obbs0r20xf7hcch.png)

# Summary

Container trigger is handy when there are several pipeline push image to registry or under complex pipelines environment. Please play with it!