デジタル開発G 黒木です。
目次
この記事では、以下の内容についてご紹介します:
はじめに
アジャイル推進ユニットでは、Azure上に構築したMLOps1環境で機械学習モデルを運用しています。この運用作業を自動化するためにGitHub Actions2を活用していますが、Azureのネットワーク制限によって保護された一部のリソースに対しては、GitHub Actionsから直接アクセスできないという課題がありました。 本記事では、特にAzure Container Registry (ACR)3へのイメージプッシュを自動化するケースで発生した課題と解決策について取り上げ、具体的なワークフローの構築手順を紹介します。
課題:GitHub ActionsからACRにアクセスできない
ACRのネットワーク制御
ACRは不要なアクセスを防ぐために、必要なアクセスのみを許可している状態です。 ACRリソースのファイアウォール設定において、アクセス元となるIPアドレス群をアクセス許可設定に追加しています。

GitHub Actionsの実行環境
GitHub ActionsはGitHubが提供するサーバー上の仮想マシンで実行されます。そのため、上記のようなネットワーク制御が行われたACRにはアクセスができません。 アクセスを可能にするには、GitHub Actionsがアクセスに使用するIPアドレスをファイアウォールの許可設定に追加する必要があります。
解決策:GitHub Actionsで一時的なアクセス許可を自動化
ワークフロー構成
以下の図のように、ACRへのアクセスを必要とする処理の前後に、ファイアウォール設定を変更する処理を追加することで解決しました。 * ACRへのアクセス前:アクセス元となるIPアドレスの許可設定を追加 * ACRへの処理完了後:追加した許可設定を削除

ワークフローの作成手順
前提条件
1. サービスプリンシパルの作成
GitHub ActionsワークフローがAzureにログインし、対象のサブスクリプションにアクセスするための認証情報が必要となります。
2. フェデレーション資格情報の追加
Azure-GitHub間の接続許可設定を作成するため、フェデレーション資格情報の作成またはクライアントシークレットの作成が必要となります。 本手順では、フェデレーション資格情報の作成手順を記載します。
- Azure portal > Microsoft Entra ID > [アプリの登録] を開く
- 作成したサービスプリンシパルを選択し、[証明書とシークレット]タブの[フェデレーション資格情報]を開く
- [資格情報の追加]を選択し、以下設定をして追加
3. ロールの割り当て
対象環境-GitHub間の接続許可設定を作成するため、作成したサービスプリンシパルに対象サブスクリプションでロールの割り当てが必要になります。本手順では、「共同作成者」ロールを割り当てます。
- Azure portal > サブスクリプションを開く
- 対象のサブスクリプションを選択し、[アクセス制御(IAM)]タブの[ロールの割り当て]を開く
- [追加]>[ロール割り当ての追加]を選択し、以下を設定して追加

4. シークレットの作成
GitHubリポジトリにシークレットを作成することで、IDやパスワード等の情報を変数として保存し、GitHub Actionsワークフローで使用することができます。シークレットは暗号化して保存されるため、一度作成すると見ることができなくなります。実行ログにもマスキングされた形で表示されるため、安全性を高めることができます。
本手順では以下情報をシークレットに登録し、ワークフローで使用します。
| シークレット名 | 説明 |
|---|---|
AZURE_CLIENT_ID |
サービスプリンシパルのクライアントID |
AZURE_TENANT_ID |
サービスプリンシパルのテナントID |
AZURE_SUBSCRIPTION_ID |
サブスクリプションID |
REGISTRY_RESOURCE_GROUP_NAME |
ACRが属するリソースグループ名 |
REGISTRY_NAME |
ACRのリソース名 |
REGISTRY_LOGIN_SERVER |
ACRのログインサーバー名 |
REGISTRY_USERNAME |
ACRの管理ユーザー名 |
REGISTRY_PASSWORD |
ACRの管理ユーザーのパスワード |
5. GitHub Actionsワークフローの作成
ワークフローはGitHubリポジトリの
/.github/workflows パスのYAMLファイルによって定義されます。
作成するワークフローの流れは以下になります。
- リポジトリのチェックアウト
- Azureへのログイン
- 一時的なアクセス許可の設定
- ACRへのログイン
- Dockerイメージのビルドとプッシュ
- アクセス許可のリセット
1. リポジトリのチェックアウト
- name: Check out repository uses: actions/checkout@v4
GitHub公式のチェックアウトアクション(actions/checkout@v4)を使用し、リポジトリの内容をワークフローの実行環境に複製します。
2. Azureへのログイン
- name: Log in to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
Azure公式のログインアクション(azure/login@v2)を使用し、Azureにログインします。
3. ファイアウォール許可設定の追加
- name: Allow ACR Firewall
if: always()
run: |
set -eu
agentIP=$(curl -s https://api.ipify.org/)
echo $agentIP
az acr network-rule add \
--resource-group "${{ secrets.REGISTRY_RESOURCE_GROUP_NAME }}" \
--name "${{ secrets.REGISTRY_NAME }}" \
--ip-address $agentIP
sleep 10
GitHub Actionsが実行される環境のIPアドレスをACRのファイアウォールに一時的に追加しています。
- 詳細説明:
4. ACRへのログイン
- name: Log in to ACR
uses: azure/docker-login@v2
with:
login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
Azure公式のログインアクション(azure/docker-login@v2)を使用し、ACRにログインします。
5. Dockerイメージのビルドとプッシュ
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
file: Dockerfile
tags: image:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
Dockerのビルドツールをセットアップし、イメージのビルド・プッシュを行います。
- 詳細説明:
push: true:ビルドが成功した後にDockerイメージをACRにプッシュするtags: image:${{ github.sha }}:ビルドしたDockerイメージに一意のタグを付けるcache-from: type=gha:GitHub Actionsのキャッシュを使用してビルド時間を短縮cache-to: type=gha,mode=max:可能な限り多くのキャッシュを保存
6. アクセス許可のリセット
- name: Deny ACR Firewall
if: always()
run: |
agentIP=$(curl -s https://api.ipify.org/)
az acr network-rule remove \
--resource-group "${{ secrets.REGISTRY_RESOURCE_GROUP_NAME }}" \
--name "${{ secrets.REGISTRY_NAME }}" \
--ip-address $agentIP
ビルドが完了した後、GitHub Actionsが実行される環境のIPアドレスをACRのファイアウォールから削除します。
まとめ
本記事では、ネットワーク制御が行われているAzureリソースに対して、GitHub Actionsを活用して自動的にイメージをプッシュする方法を紹介しました。 この仕組みにより、人為的な設定ミスを防ぎつつ、安全かつ効率的な運用作業が可能となりました。

