はじめに
Visual Studio のアップデートにより Azure App Service デプロイ時のセキュリティが強化されて基本認証がデフォルトで無効になりました。
ただ 1 点問題があり、環境の問題かそのままの状態では認証がうまくいかなったです。そのため以前は基本認証に戻す方法をとっていました。
認証を通すことができるようになったため、この記事では OIDC 認証を使用して Github Actions から Azure にデプロイする方法を紹介します。
前提
- Azure のアカウントを保有している
- Azure App Service にアプリのリソースを作成済み
- Github アカウントを保有している
- Shell 上から Azure の操作ができる(
az login
を正常に実行できる)環境がある
手順表
操作の手順は基本的に公式チュートリアルに沿って実施します。
- デプロイ対象のリソースの AppID を取得
- サービスプリンシパルを作成
- 新しいロールの割り当て
- フェデレーション ID 用の Json をローカルに準備
- フェデレーション ID の資格情報を作成
- Github にシークレット登録
- yml ファイルの修正
順番に説明します。
また ID などが複雑であるため、出力された Json をテキストエディタに張り付けて作業完了まで見直せるようにするのがおすすめです。
1. デプロイ対象のリソース AppID を取得
2 のサービスプリンシパル作成で使用するためデプロイしたいアプリの AppID を取得します。下記コマンドを実行してください。
az ad app list
大量の json ファイルが出力されてかなりビビりますが落ち着いて 1 度メモ帳に張り付けましょう。
そして確認すべき項目は 2 つだけです。
-
displayName
: Azure App Service に作成したリソース名 -
appId
: 取得したい AppID
出力された JSON からdisplayName
でデプロイ対象のアプリを検索してappId
を確認してください。
2. サービスプリンシパルの作成
下記コマンドを実行してサービスプリンシパルを作成します。$appId
は先ほど確認したappID
に置き換えてください。
az ad sp create --id $appId
上記のコマンドを実行すると生成されたサービスプリンシパルの結果が出力されます。
結果のうちId
とappOwnerOrganizationId
は以降の操作で使用するためメモしておいてください。
Id
は 1.で確認したappId
とは別の値です。
3. 新しいロールの割り当て
下記コマンドを実行してロールを割り当てます。置き換えが必要なのは 3 種類です。
-
$assigneeObjectId
は 2.で確認したId
に置き換えてください。 -
$subscriptionId
はサービスが存在するサブスクリプションの ID に置き換えてください。 -
$resourceGroupName
はアプリが存在するリソースグループ名で置き換えてください。
az role assignment create --role contributor --subscription $subscriptionId --assignee-object-id $assigneeObjectId --assignee-principal-type ServicePrincipal --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName
4. フェデレーション ID 用の Json を準備
資格情報の登録の際に Json ファイルをローカルに作成し、その中に値を記載したのちにそれを読み込む必要があります。
Shell を実行しているパスにcredential.json
ファイルを追加して中身を書き換えます。
-
<CREDENTIAL-NAME>
に任意の名称を記載してください。 -
octo-org/octo-repo
をリポジトリが存在するGithubユーザー名/デプロイ対象のリポジトリ名
に書き換えてください。
{
"name": "<CREDENTIAL-NAME>",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:octo-org/octo-repo:ref:refs/heads/master",
"description": "Testing",
"audiences": ["api://AzureADTokenExchange"]
}
Github 上で下記のようになっているリポジトリの場合は
このような Json になります。
{
"name": "DeployTest-OIDC",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:KM5075/BizCardKeeper:ref:refs/heads/master",
"description": "Testing",
"audiences": ["api://AzureADTokenExchange"]
}
上記の設定は master ブランチからの認証を承認するためのフェデレーションを生成しています。Azure にログインが必要なのは基本的にデプロイのタイミングであるため master ブランチで問題ないと思います。
ただし OIDC 認証が正しく設定できているかの確認をするために別のブランチで認証する場合にはsubject
のref:
以下を都度修正してください。
5. フェデレーション ID の資格情報を作成
資格用の Json が準備出来たら下記コマンドを実行します。
az ad app list
最初の手順 1.で実行したのと同じコマンドです。その時の出力がさかのぼれる場合は不要です。
そして確認すべき項目は 2 つだけです。
-
displayName
: Azure App Service に作成したリソース名 -
Id
: 取得したい ID(appId ではないので注意。識別のためこちらはobjectId
と呼ぶ)
ここまで出来たら下記コマンドを実行します。<APPLICATION-OBJECT-ID>
はobjectId
で置き換えてください。
az ad app federated-credential create --id <APPLICATION-OBJECT-ID> --parameters credential.json
6. Github にシークレット登録
設定はすべて完了したためあとは必要な情報を Github シークレットに登録していきます。
シークレット | 内容 |
---|---|
AZURE_CLIENT_ID | 1.で出力されたappId
|
AZURE_TENANT_ID | 2.で出力されたappOwnerOrganizationId
|
AZURE_SUBSCRIPTION_ID | 使用するサブスクリプション ID |
7. yml ファイルの修正
yml ファイルに以下の 2 点を確認します。
- 権限の付与(permissions)の追加
- ログイン処理で使用しているパラメーターの確認(Visual Studio から出力したら不要?)
jobs:
build:
#省略
deploy:
runs-on: windows-latest
needs: build
# 権限の付与の追加
permissions:
contents: read
id-token: write
steps:
# ログイン処理の追加
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Download artifact from build job
uses: actions/download-artifact@v4
with:
name: webapp
path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
- name: Deploy to Azure WebApp
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
実行
上記をすべて行った状態でフローを実行すると Azure へのログインおよびデプロイが可能になります。
おわりに
改めて記事を書いてみるとかなり複雑だという印象を受けました。複数の画面を見に行くとわかりづらくなる上に、画面のレイアウトがそこそこの頻度で変わるためコマンドラインをメインで説明しましたが、それでも複雑になりました。。。
特に複数のところにある ID を使用する必要があるというのが理解を難しくしている印象です。
この記事が皆様のコーディングライフの助けになれば幸いです。
参考