機会あってUnityで制作中のWebGLアプリをAzureのBlobStorageに入れて管理することになりました。しかし、開発中にいちいち格納するの面倒くさいな…という思いから自動デプロイするワークフローを構築することを決断。以下の記事にチャレンジしました。
とはいえ、初心者の私に読んだだけ直ぐ理解するのは厳しい内容だったので、私なりの理解・解釈を交えて解説しながら手順を説明していきます。
はじめに
前提
この記事は非エンジニアの私が経験した苦しみを他者に味わってほしくない、もっとわかりやすく仕組みを知れたらいいなという思いで作成したものです。認識や進め方が非効率的で誤りがあるかもしれません。その際には容赦なくご指摘頂けると幸いです。
動作環境
前提条件を整える
Azureアカウント・サブスクリプションとGithubアカウント、格納するコンテンツの作成は省略します。
格納先のStorageとAzure CDNを作る
元の記事の指示に従い、格納先とAzureCDNを作っておきます。
Storageはわかるのですが、AzureCDNを使う目的が余りわかっていません…
AzureCDN自体はWebサイトやビデオといったコンテンツをユーザー近くのサーバにキャッシュするサービスなので、GitHub連携の際に使われるんじゃないんでしょうか(想像)。
上記記事、「ストレージ アカウントの Azure CDN を有効にする」 まで進めましょう。
次にVScodeのコマンドラインでAzure CLIを使うため以下を参考にAzure CLIをインストール。
インストールしたらVScodeにMicrosoftアカウントを紐づけておきましょう。
VScodeの左下にある人間のアイコンをクリックして 「クラウドの変更を有効にします」 を押すとMicrosoftアカウントへのログインができます。
OpenID Connectを使った認証資格情報を作成する
Microsoft Entra アプリを作成しGitHubへ短期間のトークンを使って認証する仕組みをくみ上げます。GitHubにはOpenID Connectという仕組みがあるようで、クラウドプロバイダとセキュアに認証できるようですね。
コマンドラインツールで以下のコードを打ち、アプリケーションを作成します。Microsoft EntraはもともとAzure Active Directory (AD) という名前だった名残かadという文字が見えますね。myAppの部分はお好みの名前に変えてもOKです。
az ad app create --display-name myApp
JSON形式で作成したアプリの情報が並びますが、appid
を控えておきましょう。
次にサービスプリンシパルを作成します。
説明が難しいのですが、要はMicrosoft Entra内で作成したアプリのID・パスワード認証を委任する役割?のようです。次のコードを打ちましょう。
az ad sp create --id $appId
このコードを打つとまたしても大量のJSON形式の情報が並びますが、その中にappid
以外にもう一つ同じ桁数のid
と、appOwnerOrganizationId
が生成されるので控えておきましょう。
余談:appOwnerOrganizationId
は前のバージョンだとappOwnerTenantId
とされていたようですね。元の記事ではそう表記されているのでご注意を。
続いてサブスクリプションとオブジェクト別にユーザーのロールを割り当てます。
$resourceGroupName
にストレージアカウントを置いたリソースグループの名前を、
$subscriptionId
に作成したサブスクリプションのID(AzurePortalから確認)を、
$assigneeObjectId
に一つ前に控えたid
を入れて以下コードを実行しましょう。
az role assignment create --role contributor --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName --subscription $subscriptionId --assignee-object-id $assigneeObjectId --assignee-principal-type ServicePrincipal
この後元の記事では以下のコードをAzure CLIで打ち込みますが、私の場合は「実行結果」にあるようにエラーが発生してしまいました。
az rest --method POST --uri 'https://graph.microsoft.com/beta/applications/<APPLICATION-OBJECT-ID>/federatedIdentityCredentials' --body '{"name":"<CREDENTIAL-NAME>","issuer":"https://token.actions.githubusercontent.com","subject":"repo:organization/repository:ref:refs/heads/main","description":"Testing","audiences":["api://AzureADTokenExchange"]}'
Bad Request({"error":{"code":"BadRequest","message":"Write requests (excluding DELETE) must contain the Content-Type header declaration.","innerError":{"date":"2023-12-26T19:54:51","request-id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","client-request-id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}}})
従ってここからは下記記事の 「フェデレーション ID 資格情報をアプリに構成する GitHub Actions」 を参考にPortalからサービスプリンシパルを作成しフェデレーション資格情報を追加します。
先ほど作成したアプリケーション(この例では"myApp")をAzurePortal上から検索。
[管理から] [証明書とシークレット] を選択し、[フェデレーション資格情報] タブを選択してから、[資格情報の追加]をクリックしましょう。
[フェデレーション資格情報シナリオ]を[Azure リソースをデプロイする GitHub Action]に選択、組織とリポジトリは今回デプロイ元にするGitHubのリモートリポジトリの情報を入力してください。エンティティ型は今回はBranchへのcommitをトリガーとするので、「Branch」としましょう。そうすると下の入力欄にどのBranchでトリガーするか聞かれるので、今回はmainにして開発用ブランチから本番移行する時にデプロイする仕様にします。最後にこの資格情報自体の[名前]を書いてクレデンシャルの発行完了です。
作成したアプリケーションのOverview = 概要を確認しましょう。
GitHubと連携する時に必要な各種IDが記載されています。
使用しているサブスクリプションのIDとともに、コピーして控えておきましょう。
- アプリケーション(クライアント)ID
- ディレクトリ(テナント)ID
- サブスクリプションID
GitHub SecretにAzure側の連携先情報を格納する
以下の記事を参考にGitHubの公式サイトからデプロイ対象のリポジトリに入り、Actionsを設定します。
Settings→Secrets and variables→Actionsの順で開きましょう
開いたら緑色の「New repository secret」を押しNameとSecretを入力しておきます。
上記画像の通りNameに大文字で定数名を、SecretにさっきAzurePortalで確認した値を入れておきましょう。
Azureログイン→デプロイ→ログアウトする処理を書く
元の記事の "ワークフローを追加する" を参考にして、対象のリポジトリのページから "Actions" を選択。
青字で光る ”set up a workflow yourself” を選びます。
コードを書け!と言われるので、元の記事にあったコードを参考にした以下を貼付け。
一部大文字での<>部分は今回作ったリソースにあわせ値を格納してください。
name: CI with OpenID Connect
on:
push:
branches: [ main ]
permissions:
id-token: write
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Upload to blob storage
uses: azure/CLI@v1
with:
inlineScript: |
az storage blob upload-batch --account-name <STORAGE_ACCOUNT_NAME> --overwrite --auth-mode key -d '$web' -s .
- name: Purge CDN endpoint
uses: azure/CLI@v1
with:
inlineScript: |
az cdn endpoint purge --content-paths "/*" --profile-name "CDN_PROFILE_NAME" --name "CDN_ENDPOINT" --resource-group "RESOURCE_GROUP"
# Azure logout
- name: logout
run: |
az logout
if: always()
(--overwirteという記述を私の方で追加しています。そうでないとすでにAzureStorage側に同名のフォルダが有っても上書き保存してくれません。この記事によるとどうやらAzure CLIのバージョンが原因のようです。)
動作確認
これでVisual Studio codeからmainブランチにプッシュするなどしてみてください。
Azureストレージにデータが格納されればOKです。
ワークロードがいつ起動したかどうかは、GitHubの"Actions"からも確認可能です。