How to use an image from Azure Container Registry as the base for GitLab Runner’s Docker executor.
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" | base64You 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:
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.shacr_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"
fiI 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.shacr_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}"