Young Leaves

OpenID Connect を使ってGitHub Actions からAzure にログインする

今回はGitHub 社が提供しているGitHub Actions でAzure リソースの操作などを行う準備として、OpenID Connect を使ってGitHub Actions からAzure アカウントにログインする方法について説明します。

実行環境

記事内のAzure CLI コマンドはAzure CloudShell で実行とします。

Azure CLl

2.50.0

前提条件

  • GitHub のアカウントおよびAzure のアカウントを持っていること。
  • GitHub Actions 用のリポジトリを作成していること。

GitHub Actions からAzure を操作するには

GitHub Actions からAzure のリソースを作成したりAzure CLI 操作を行うためには、GitHub Actions でAzure のログインを行う必要があります。GitHub Actions のタスクでAzure のログインを行う方法は2つあります。

  • OpenID Connect でAzure にログインする。
  • サービスプリンシパルのシークレットでAzure にログインする。

今回はサービスプリンシパルのフェデレーション資格情報を利用した方法でログインを行っていきます。

リソースグループの作成

初めにサービスプリンシパルを割り当てるリソースグループを作成します。

# リソースグループを作成する
az group create -n azlogin-rg -l japaneast

サービスプリンシパルの作成

リソースグループ作成後、GitHub Actions からAzure へログインするために必要なサービスプリンシパルを作成します。スコープについては先程作成したリソースグループID を変数に格納して利用します。

# リソースグループのIDとアプリケーション名を変数に格納する
resourceGroupId=$(az group show -n azlogin-rg --query "id" -o tsv)
servicePrincipalName="GitHubActionsLoginTest"

# サービスプリンシパルを作成する
az ad sp create-for-rbac --name $servicePrincipalName \
    --role contributor \
    --scopes $resourceGroupId \
    --sdk-auth

サービスプリンシパル作成後、JSON形式でサービスプリンシパルの情報が出力されます。こちらはGitHub Actions の資格情報として利用するため控えておきます。

{
  "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "clientSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
  "resourceManagerEndpointUrl": "https://management.azure.com/",
  "activeDirectoryGraphResourceId": "https://graph.windows.net/",
  "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
  "galleryEndpointUrl": "https://gallery.azure.com/",
  "managementEndpointUrl": "https://management.core.windows.net/"
}

今回は動作確認のためロールをContributor としておりますが、Contributor はリソースの作成、削除など強い権限を持っているため、業務などで利用する際は環境に合わせたロールを付与してください。

フェデレーション資格情報の作成

サービスプリンシパル作成後、OpenID Connect 用のフェデレーション資格情報を作成します。今回は以下のGitHub の情報を利用するため、利用する際はrepo とenvironment の値を各自の環境に合わせた値に修正してください。

名前

azure-login

GitHub 組織名

kdkwakaba

リポジトリ名

azurelogintest

環境名

Production

# サービスプリンシパルのアプリケーションIDを変数に格納する
applicationId=$(az ad sp list --display-name "GitHubActionsLoginTest" --query "[].appId" -o tsv)

# 資格情報のJSONファイルを作成
cat <<EOF > credential.json
{
    "name": "azure-login",
    "issuer": "https://token.actions.githubusercontent.com",
    "subject": "repo:kdkwakaba/azlogintest:environment:Production",
    "description": "This credential is azure login test.",
    "audiences": [
        "api://AzureADTokenExchange"
    ]
}
EOF

# フェデレーション資格情報を作成する
az ad app federated-credential create --id $applicationId --parameters credential.json

実行に成功するとJSON 形式で結果が出力されます。

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#applications('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')/federatedIdentityCredentials/$entity",
  "audiences": [
    "api://AzureADTokenExchange"
  ],
  "description": "This credential is azure login test.",
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "issuer": "https://token.actions.githubusercontent.com",
  "name": "azure-login",
  "subject": "repo:kdkwakaba/azlogintest:environment:Production"
}

資格情報をGitHub のシークレット に登録

GitHub Actions からAzure にログインするためには資格情報が必要となりますが、資格情報を平分でメタデータファイルに記載するのはセキュリティ上推奨されません。そのため、今回は資格情報をGitHub のSecret に登録し、Secret をメタデータファイルで使用する方法とします。

GitHub Actions を利用するリポジトリの設定画面から、「Settings > Secrets and variables > Actions」を選択し、「New repository secret」から以下のシークレットを作成します。

AZURE_CLIENT_ID

アプリケーション (クライアント) ID (JSON で控えたclientId の値)

AZURE_TENANT_ID

ディレクトリ (テナント) ID (JSON で控えたtenantId の値)

AZURE_SUBSCRIPTION_ID

サブスクリプション ID ()JSON で控えたsubscriptionId の値

GitHub Actions からAzure にログイン

GitHub Actions 用の資格情報が作成できたら、GitHub Actions のAction ファイルからAzure にログインします。今回はAzure にログイン後、リソースグループを表示させるジョブを実行させます。ディレクトリを作成していない場合は「.github/workflows」のディレクトリを作成し、拡張子「.yml」のメタデータファイルを作成します。

name: OpenID Connect Login Test

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    # フェデレーション資格情報で環境を指定した場合、環境名と一致させる必要がある
    environment:
      name: Production
    steps:
      - name: "Az CLI 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: "Run Azure CLI commands"
        run: |
          az group list -o table

ファイルをmain ブランチにpush したらGitHub Actions が実行されるため、Login のタスクで「Login successful.」が表示されること、Azure CLI コマンド実行タスクでリソースグループが表示されることを確認します。

リソースのクリーンアップ

動作確認後、作成したリソースを削除します。サービスプリンシパルのID はフェデレーション資格で取得したアプリケーションID を利用します。

# リソースグループを削除する
az group delete -n azlogin-rg

# サービスプリンシパルを削除する
az ad sp delete --id $applicationId

まとめ

  • GitHub Actions からAzure にログインする場合、OpenID Connect のログインとサービスプリンシパルのログインがある。
  • 資格情報はサービスプリンシパル作成、フェデレーション資格情報作成の順で作成する。
  • 資格情報作成後、GitHub のシークレットとして設定する。
  • フェデレーション資格情報で環境を指定した場合、GitHub Actions のメタデータファイルで環境名を指定する必要がある。

参考資料