GitHubActionsからAzureに接続する場合、Azureでサービスプリンシパルを作成し、GitHubのSecretに登録して認証します。ひと昔前はクライアントシークレット(パスワードに相当するもの)を含む4つの情報が必要で、AZURE_CREDENTIALS
の名前でGitHubのSecretに登録していました。
{
"clientId": "<GUID>",
"clientSecret": "<GUID>",
"subscriptionId": "<GUID>",
"tenantId": "<GUID>",
}
OpenID Connect(OIDC)を使うと、クライアントシークレットなしに認証することができます。以下の3つだけそれぞれ登録すればOK。
AZURE_CLIENT_ID
AZURE_SUBSCRIPTION_ID
AZURE_TENANT_ID
公式ドキュメントにわかりやすく記載されていますが、よく使うので備忘録としてまとめます。
記事の中でご紹介するコードはGitHubに公開しています。
サービスプリンシパルの作成
まずはじめに、Azure AD で新しいアプリを作成し、そのアプリにサービスプリンシパルを作成します。
appName="githubactions"
# Azure sign in
az login
# Get the current Azure subscription ID
subscriptionId=$(az account show --query 'id' --output tsv)
# Create a new Azure Active Directory application
appId=$(az ad app create --display-name $appName --query appId --output tsv)
# Create a new service principal for the application
assigneeObjectId=$(az ad sp create --id $appId --query id --output tsv)
これは、Azure AD > アプリの登録から新規登録する操作に該当します。appName
はお好みで。
ロールの割り当て
ここではサブスクリプションをスコープとして「共同作成者」のロールを割り当てています。
# Assign the 'Contributor' role to the service principal for the subscription
az role assignment create --role contributor \
--subscription $subscriptionId \
--assignee-object-id $assigneeObjectId \
--assignee-principal-type ServicePrincipal \
--scope /subscriptions/$subscriptionId
フェデレーション資格情報の追加
フェデレーション資格情報を追加して、GitHubのリポジトリを信頼するように構成します。
# Assign the 'Contributor' role to the service principal for the subscription
az ad app federated-credential create --id $appId --parameters credential.json
パラメータはjsonファイルで渡しています。
subject
がパッと見わかりにくいですが、例えば mian ブランチを対象とする場合は repo:<user_name>/<repo_name>:ref:refs/heads/main
と書きます。
- name:任意の名前
- issuer:トークンの発行者(GithubActions)
- subject:フェデレーション ID 資格情報に関連付けられている対象リソース
- 組織名、リポジトリ名、ブランチ名やタグの情報から構成される
- OIDCトークンの検証に使用される
- description:説明(省略可)
- audiences:対象ユーザー(api://AzureADTokenExchange 固定)
{
"name": "m-oka-system-azure-gha-oidc-main",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:m-oka-system/azure-gha-oidc:ref:refs/heads/main",
"audiences": [
"api://AzureADTokenExchange"
]
}
これは、Azure AD > アプリの登録 > 登録したアプリ > 証明書とシークレット > フェデレーション資格情報タブの「資格情報の追加」の操作に該当します。繰り返しになりますが、「クライアントシークレット」の発行は必要ありません。
GitHubにシークレットを作成
GitHub CLIで Repository secrets を登録します。
gh auth login
gh secret set -f .secrets
AZURE_TENANT_ID=<GUID>
AZURE_SUBSCRIPTION_ID=<GUID>
AZURE_CLIENT_ID=<GUID>
これは、リポジトリのSettings > Secrets and variables > Actions > New repository secret の操作に該当します。
GitHubActionsのワークフローを作成
Azure にサインインして az account show
でサブスクリプション名を取得するだけのワークフローを作ってみました。
name: Azure Login with OpenID Connect
on:
push:
branches:
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
env:
azcli_verion: 2.46.0
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- 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 }}
- name: Azure CLI script
uses: azure/CLI@v1
with:
azcliversion: ${{ env.azcli_verion }}
inlineScript: |
az account show --query name
- name: logout
run: |
az logout
ポイントは2カ所です。
-
アクセス許可設定の追加
OIDCのトークンを要求するためにid-token: write
のパーミッションが必要です。
permissions:
id-token: write
contents: read
-
Repository secretsの参照
azure/login@v1
アクションのwith
で先に登録したシークレットを渡して認証しています。
- 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 }}
ワークフローの実行
リポジトリにpushするとワークフローが実行されます。
サブスクリプションの名前 Pay-As-You-Go
が表示されていることがわかります。
今回は簡単なAzure CLIの実行だけでしたが、Dockerfile
をビルドしてACRにpushしたり、App Serviceにアプリをデプロイする時などに役立つと思います。