Skip to content

Instantly share code, notes, and snippets.

@urlichLivonian
Last active May 18, 2022 12:45
Show Gist options
  • Save urlichLivonian/86efcf8f862170b910243756ba97ffd9 to your computer and use it in GitHub Desktop.
Save urlichLivonian/86efcf8f862170b910243756ba97ffd9 to your computer and use it in GitHub Desktop.
Pull base images from Azure Container Registry on GitLab CI

Pulling images from Azure Container Registry on GitLab CI

How to use an image from Azure Container Registry as the base for GitLab Runner’s Docker executor.

Using Service Principal

Let's imagine we have image in ACR as follows jigurda.azurecr.io/namaespace/awesome-toolbox:1.0.1. This image is private and requires you to sign in to a private container registry. Let’s also assume that these are the sign-in credentials for your service principal:

Key Example Value
registry jigurda.azurecr.io
client_id 6394a177-82c1-4ce7-abe2-f6e92f3c5e76
client_secret sTr0NgSecReT~etAmjI+JPF/aRPeHdRwicjhf

You can set the DOCKER_AUTH_CONFIG variable within your project’s Settings > CI/CD page:

"auths": {
  "jigurda.azurecr.io": {
    "auth": "bla-bla-bla"
  }
}

You can add configuration for as many registries as you want, adding more registries to the "auths" hash as described above. The value of auth is base64-encoded version of your client_id and client_secret that you use to authenticate into the registry:

echo -n "6394a177-82c1-4ce7-abe2-f6e92f3c5e76:sTr0NgSecReT~etAmjI+JPF/aRPeHdRwicjhf" | base64

You can generate a JSON for DOCKER_AUTH_CONFIG variable using the following command:

export CONTAINER_REGISTRY=<registry>
export AZURE_CLIENT_ID=<client_id>
export AZURE_CLIENT_SECRET=<client_secret>
PASSWORD_ENCODED=$(echo "${AZURE_CLIENT_ID}:${AZURE_CLIENT_SECRET}" | base64)
jq -n --arg registry "${CONTAINER_REGISTRY}" --arg userpass "${PASSWORD_ENCODED}" '{auths: {($registry): {auth: $userpass}}}'

Now, add the DOCKER_AUTH_CONFIG variable to your project’s Settings > CI/CD page:

Add DOCKER_AUTH_CONFIG variable from Gitlab job

If you need to dynamically update the DOCKER_AUTH_CONFIG variable with a new password. Let's setup a new job for this

build:acr_auth:
  stage: build
  image: alpine:3.13
  script:
    - export CONTAINER_REGISTRY=${PROJECT_CONTAINER_REGISTRY}
    - export AZURE_CLIENT_ID=${PROJECT_AZURE_CLIENT_ID}
    - export AZURE_CLIENT_SECRET=${PROJECT_AZURE_CLIENT_SECRET}
    # Your personal or project token with api access
    - export TOKEN=${PROJECT_API_TOKEN}
    - export PROJECT_ID=${CI_PROJECT_ID}
    - apk add --no-cache curl jq bash
    - chmod +x ./acr_auth.sh
    - bash ./acr_auth.sh

acr_auth.sh

#!/bin/bash

set -e

GILBAL_CI_VARIABLE='DOCKER_AUTH_CONFIG'
PASSWORD_ENCODED=$(echo "${AZURE_CLIENT_ID}:${AZURE_CLIENT_SECRET}" | base64)
PAYLOAD=$(jq -n --arg registry "${CONTAINER_REGISTRY}" --arg userpass "${PASSWORD_ENCODED}" '{auths: {($registry): {auth: $userpass}}}')
RESPONCE=$(curl --request GET --header "PRIVATE-TOKEN:$TOKEN" "$CI_API_V4_URL/projects/$PROJECT_ID/variables/$GILBAL_CI_VARIABLE" -s -o /dev/null -w "%{http_code}")


if [[ "${RESPONCE}" == '404' ]]; then
    echo "Project level variable $GILBAL_CI_VARIABLE does not exist. Let's create it!"
    curl --request POST --header "PRIVATE-TOKEN:$TOKEN" "$CI_API_V4_URL/projects/$PROJECT_ID/variables" --form "key=$GILBAL_CI_VARIABLE" --form "value=$PAYLOAD"
else
    echo "Update project level variable $GILBAL_CI_VARIABLE"
    curl --request PUT --header "PRIVATE-TOKEN:$TOKEN" "$CI_API_V4_URL/projects/$PROJECT_ID/variables/$GILBAL_CI_VARIABLE" --form "value=$PAYLOAD"
fi

Access an image from Azure Container Registry with access_token from Gitlab job

I doubt this will be useful to anyone, but I'll leave it here just in case.

build:acr_auth:
  stage: build
  image: docker:stable
  script:
    - export CONTAINER_REGISTRY=${PROJECT_CONTAINER_REGISTRY}
    - export AZURE_CLIENT_ID=${PROJECT_AZURE_CLIENT_ID}
    - export AZURE_CLIENT_SECRET=${PROJECT_AZURE_CLIENT_SECRET}
    - export AZURE_TENANT_ID=${PROJECT_AZURE_TENANT_ID}
    # Your personal or project token with api access
    - export TOKEN=${PROJECT_TOKEN}
    - export PROJECT_ID=${CI_PROJECT_ID}
    - apk add --no-cache curl jq bash
    - chmod +x ./acr_auth_token.sh
    - bash ./acr_auth_token.sh

acr_auth_token.sh

#!/bin/sh

set -e

ACCESS_TOKEN=$(docker run --rm \
-e AZURE_CLIENT_ID=${AZURE_CLIENT_ID} \
-e AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET} \
-e AZURE_TENANT_ID=${AZURE_TENANT_ID} \
mcr.microsoft.com/azure-cli az login --service-principal -u ${AZURE_CLIENT_ID} -p ${AZURE_CLIENT_SECRET} -t ${AZURE_TENANT_ID} 1> /dev/null \
&& az acr login -n ${CONTAINER_REGISTRY} --expose-token 2> /dev/null | jq -r '.accessToken' | base64)

PASSWORD_ENCODED=$(echo "00000000-0000-0000-0000-000000000000:${ACCESS_TOKEN}" | base64)
PAYLOAD=$(jq -n --arg registry "${CONTAINER_REGISTRY}" --arg userpass "${PASSWORD_ENCODED}" '{auths: {($registry): {auth: $userpass}}}')

curl --request PUT --header "PRIVATE-TOKEN:$TOKEN" "${CI_API_V4_URL}/projects/${PROJECT_ID}/variables/DOCKER_AUTH_CONFIG" --form "value=${PAYLOAD}"

Related Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment