IP制限をかけているAzure Container RegistryにGitHub ActionsからPushする方法
やりたいこと
Azureに構築したContainer RegistryにIP制限をかけており、パブリックIPでの接続は社内の規定のネットワークのみ許可しています。
Container Registryに保存するImageはApp ServiceにPushして動かしますが、Azureリソース間はVnet統合でプライベートエンドポイント経由で接続が可能となっています。
GitHub ActionsはSaaSであり、ランナーを実行するとGitHubのクラウド上で動作するためIPが動的です。
そのため、設定したActionsの環境のIPを登録するということは不可能。
しかしContainer Regsitryを全てのIPからアクセスできるようにはしたくない。

解決方法
思いついたのは二つ
1. Actionsのワークフロー内でIPを一時的に解放させる
こちらはワークフローにスクリプトを追加するだけで実現が可能です。
- ワークフロー開始時にIPを取得
↓ - 対象のAzure Container Registryの許可IPに追加
↓ - デプロイ処理
↓ - 完了後に追加したIPを削除
という流れです。
今回はこっちを紹介します。
2. セルフホストランナーを使用
自社環境にVM等のサーバーを立てて、そこにActionsのランナー環境を構築します。
そうすることで他のリソース同様にプライベートエンドポイント経由での接続が可能となりセキュアなデプロイパイプラインの構築が可能です。
本番運用等を考えると、こちらが適切なのかもしれません。
ワークフロー内で一時解放する
設定方法
対象のAzureテナントにログイン後、Azure CLIを使って、対象のContainer Registryリソースのネットワーク設定を更新させます。
IPは動的に変わるため、実行のたびにcurlコマンドで現在のIPを取得してきます。
name: コンテナベースのアプリのデプロイ
on:
workflow_dispatch:
push:
branches:
- develop
jobs:
build-and-deploy:
name: Build and Push to ACR → Deploy to App Service
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
# AzureにOICDでログイン(ログインしないとazコマンドが使えない)
- name: Azure Login
uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# このワークフロー環境のIPを取得して、Azure CLIで対象リソースのネットワーク設定を変更
- name: Allow ACR Firewall
run: |
set -eu
workflowIP=$(curl -s https://api.ipify.org/)
echo $workflowIP
az acr network-rule add \
--resource-group "${{ secrets.RESOURCE_GROUP_NAME }}" \
--name "${{ secrets.ACR_RESOURSE_NAME }}" \
--ip-address $workflowIP
sleep 60
デプロイが完了したら、追加したIPをネットワーク設定から削除します。
再びAzure CLIで対象のContainer Registryリソースのネットワーク設定を修正します。
name: コンテナベースのアプリのデプロイ
on:
workflow_dispatch:
push:
branches:
- develop
jobs:
build-and-deploy:
name: Build and Push to ACR → Deploy to App Service
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
steps:
...
- name: Deny ACR Firewall
if: always()
run: |
workflowIP=$(curl -s https://api.ipify.org/)
az acr network-rule remove \
--resource-group "${{ secrets.RESOURCE_GROUP_NAME }}" \
--name "${{ secrets.ACR_RESOURSE_NAME }}" \
--ip-address $workflowIP
補足
Azure CLIで対象のリソースにIPを追加した後、反映用に60秒間待たせていますがそれでも反映ができておらずデプロイ時にIP制限エラーになることがたまにあります。
ですので、デプロイ実行直前に再度ネットワーク設定が反映されているか確認することを推奨します。
Azure CLIで対象リソースの許可しているIP一覧を取得して今のIPが存在するかをチェックします。
もし反映されてたら次のステップに進みますが、存在していなければ10秒待機して再度確認するようにしています。
name: コンテナベースのアプリのデプロイ
on:
workflow_dispatch:
push:
branches:
- develop
jobs:
build-and-deploy:
name: Build and Push to ACR → Deploy to App Service
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write
steps:
...
- name: Verify ACR Firewall Rule Applied
run: |
set -eu
workflowIP=$(curl -s https://api.ipify.org/)
echo "Wokiflow IP: $workflowIP"
# ACRのネットワークルールを取得して、IPが含まれているか確認
for i in {1..10}; do
echo "Attempt $i: Checking if IP $workflowIP is in ACR firewall rules..."
rules=$(az acr network-rule list \
--resource-group "${{ secrets.RESOURCE_GROUP_NAME }}" \
--name "${{ secrets.ACR_RESOURSE_NAME }}" \
--query "ipRules[?ipAddressOrRange=='$workflowIP'].ipAddressOrRange" \
-o tsv)
if [ -n "$rules" ]; then
echo "✅ IP $workflowIP is allowed in ACR firewall"
exit 0
fi
if [ $i -lt 10 ]; then
echo "⏳ IP not found yet, waiting 10 seconds..."
sleep 10
fi
done
echo "❌ Failed to verify IP in ACR firewall after 10 attempts"
exit 1
最後に
もし今回取ったような「一時的にActionsのIPを解放する」とか、「セルフホストランナーのGitHub Actionsを使う」以外にいい方法がありましたらご教示いただきたいです!
Discussion