CI/CD のツールとして Azure Pipeline を使うのですが、Microsoft-Hosted Agent の場合、Parallel Job の制限がきつく、 どうしても順番待ちが発生しがちでした
Self Hosted Agent の場合、Visual Studio のサブスクリプションがあると、Parallel Job の枠が増える為、 手っ取り早く Self Hosted Agent を増やして、有効活用したいということで、Container Apps を使った Self Hosted Agents を構築しました
今回は、その時の備忘録です。
その1 で行う事
- Azure Container Registry (ACR) を作成する
- Self Hosted Agent のイメージを ACR へ登録する
前提条件
環境
- Azure CLI : v.2.39.0
- Docker : v.20.10
Azure Container Registry (ACR) を作成する
今回は、サクッと Bicep で構築します
リソースグループを作成する
まず今回作るものを格納するリソースグループを作成します
- bicep
targetScope = 'subscription' resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { name: 'rg-devops-agent' location: deployment().location }
- コマンド
az deployment sub create \ --location japaneast \ --template-file {bicep ファイル名}
ACR を作成する
次に、ACR を作成します。
- bicep
param location string = resourceGroup().location // Create Azure Container Registry param acrName string module acr 'modules/containerRegistry.bicep' = { name: acrName params: { acrName: acrName adminUserEnabled: true location: location sku: 'Basic' } }
- コマンド
az deployment group create \ --resource-group rg-devops-agent \ --template-file {bicep ファイル名} \ --parameters acrName={ACR 名}
Self Hosted Agent のイメージを ACR へ登録する
Dockerfile をビルドする
公式でベースになる Dockerfile が提供されているので、次のものを保存します
FROM ubuntu:20.04 RUN DEBIAN_FRONTEND=noninteractive apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get upgrade -y RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \ apt-transport-https \ apt-utils \ ca-certificates \ curl \ git \ iputils-ping \ jq \ lsb-release \ software-properties-common RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash # Can be 'linux-x64', 'linux-arm64', 'linux-arm', 'rhel.6-x64'. ENV TARGETARCH=linux-x64 WORKDIR /azp COPY ./start.sh . RUN chmod +x start.sh ENTRYPOINT [ "./start.sh" ]
次に、コンテナの ENTRYPOINT で実行するスクリプトを Dockerfile と同じ場所に start.sh
として保存します。
#!/bin/bash set -e if [ -z "$AZP_URL" ]; then echo 1>&2 "error: missing AZP_URL environment variable" exit 1 fi if [ -z "$AZP_TOKEN_FILE" ]; then if [ -z "$AZP_TOKEN" ]; then echo 1>&2 "error: missing AZP_TOKEN environment variable" exit 1 fi AZP_TOKEN_FILE=/azp/.token echo -n $AZP_TOKEN > "$AZP_TOKEN_FILE" fi unset AZP_TOKEN if [ -n "$AZP_WORK" ]; then mkdir -p "$AZP_WORK" fi export AGENT_ALLOW_RUNASROOT="1" cleanup() { if [ -e config.sh ]; then print_header "Cleanup. Removing Azure Pipelines agent..." # If the agent has some running jobs, the configuration removal process will fail. # So, give it some time to finish the job. while true; do ./config.sh remove --unattended --auth PAT --token $(cat "$AZP_TOKEN_FILE") && break echo "Retrying in 30 seconds..." sleep 30 done fi } print_header() { lightcyan='\033[1;36m' nocolor='\033[0m' echo -e "${lightcyan}$1${nocolor}" } # Let the agent ignore the token env variables export VSO_AGENT_IGNORE=AZP_TOKEN,AZP_TOKEN_FILE print_header "1. Determining matching Azure Pipelines agent..." AZP_AGENT_PACKAGES=$(curl -LsS \ -u user:$(cat "$AZP_TOKEN_FILE") \ -H 'Accept:application/json;' \ "$AZP_URL/_apis/distributedtask/packages/agent?platform=$TARGETARCH&top=1") AZP_AGENT_PACKAGE_LATEST_URL=$(echo "$AZP_AGENT_PACKAGES" | jq -r '.value[0].downloadUrl') if [ -z "$AZP_AGENT_PACKAGE_LATEST_URL" -o "$AZP_AGENT_PACKAGE_LATEST_URL" == "null" ]; then echo 1>&2 "error: could not determine a matching Azure Pipelines agent" echo 1>&2 "check that account '$AZP_URL' is correct and the token is valid for that account" exit 1 fi print_header "2. Downloading and extracting Azure Pipelines agent..." curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & wait $! source ./env.sh print_header "3. Configuring Azure Pipelines agent..." ./config.sh --unattended \ --agent "${AZP_AGENT_NAME:-$(hostname)}" \ --url "$AZP_URL" \ --auth PAT \ --token $(cat "$AZP_TOKEN_FILE") \ --pool "${AZP_POOL:-Default}" \ --work "${AZP_WORK:-_work}" \ --replace \ --acceptTeeEula & wait $! print_header "4. Running Azure Pipelines agent..." trap 'cleanup; exit 0' EXIT trap 'cleanup; exit 130' INT trap 'cleanup; exit 143' TERM chmod +x ./run-docker.sh # To be aware of TERM and INT signals call run.sh # Running it with the --once flag at the end will shut down the agent after the build is executed ./run-docker.sh "$@" & wait $!
- コマンド
後で使うので、分かりやすいタグも付けておきます
docker build . -t devops-agent
エラーが出なければ、イメージの作成完了です
ACR へイメージを登録する
まず ACR へログインします
az acr login --name {ACR 名}
次にプッシュしたいイメージにタグと明示的なイメージ名を設定します
イメージ名は、ACR のサーバ名/イメージ名:タグ名
とします
docker tag devops-agent {ACR 名}.azurecr.io/devops-agent:latest
最後に ACR に push します
docker push {ACR 名}.azurecr.io/devops-agent:latest
まとめ
ここまでで、Azure Container Registry に Self Hosted Agent のイメージを登録できました。
次回は、このイメージを基に Container Apps へ Self Hosted Agent を展開していこうと思います。