LoginSignup
2
1
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

【Github Actions】Gitに上げている静的WebサイトをCommit時にGitHub ActionsでAzure Storageに自動デプロイする

Posted at

機会あってUnityで制作中のWebGLアプリをAzureのBlobStorageに入れて管理することになりました。しかし、開発中にいちいち格納するの面倒くさいな…という思いから自動デプロイするワークフローを構築することを決断。以下の記事にチャレンジしました。

こういうのをやりたい
image.png

とはいえ、初心者の私に読んだだけ直ぐ理解するのは厳しい内容だったので、私なりの理解・解釈を交えて解説しながら手順を説明していきます。

はじめに

前提

この記事は非エンジニアの私が経験した苦しみを他者に味わってほしくない、もっとわかりやすく仕組みを知れたらいいなという思いで作成したものです。認識や進め方が非効率的で誤りがあるかもしれません。その際には容赦なくご指摘頂けると幸いです。

動作環境

Windows11 22H2 OSビルド22621.2861
Azure CLI 2.55.0
VScode 1.85.1

前提条件を整える

Azureアカウント・サブスクリプションとGithubアカウント、格納するコンテンツの作成は省略します。

格納先のStorageとAzure CDNを作る

元の記事の指示に従い、格納先とAzureCDNを作っておきます。
Storageはわかるのですが、AzureCDNを使う目的が余りわかっていません…
AzureCDN自体はWebサイトやビデオといったコンテンツをユーザー近くのサーバにキャッシュするサービスなので、GitHub連携の際に使われるんじゃないんでしょうか(想像)。

上記記事、「ストレージ アカウントの Azure CDN を有効にする」 まで進めましょう。

次にVScodeのコマンドラインでAzure CLIを使うため以下を参考にAzure CLIをインストール。

インストールしたらVScodeにMicrosoftアカウントを紐づけておきましょう。
VScodeの左下にある人間のアイコンをクリックして 「クラウドの変更を有効にします」 を押すとMicrosoftアカウントへのログインができます。

スクショ.png

OpenID Connectを使った認証資格情報を作成する

Microsoft Entra アプリを作成しGitHubへ短期間のトークンを使って認証する仕組みをくみ上げます。GitHubにはOpenID Connectという仕組みがあるようで、クラウドプロバイダとセキュアに認証できるようですね。

コマンドラインツールで以下のコードを打ち、アプリケーションを作成します。Microsoft EntraはもともとAzure Active Directory (AD) という名前だった名残かadという文字が見えますね。myAppの部分はお好みの名前に変えてもOKです。

Azure CLI
az ad app create --display-name myApp

JSON形式で作成したアプリの情報が並びますが、appidを控えておきましょう。

次にサービスプリンシパルを作成します。
説明が難しいのですが、要はMicrosoft Entra内で作成したアプリのID・パスワード認証を委任する役割?のようです。次のコードを打ちましょう。

Azure CLI
az ad sp create --id $appId

このコードを打つとまたしても大量のJSON形式の情報が並びますが、その中にappid以外にもう一つ同じ桁数のidと、appOwnerOrganizationIdが生成されるので控えておきましょう。

余談:appOwnerOrganizationIdは前のバージョンだとappOwnerTenantIdとされていたようですね。元の記事ではそう表記されているのでご注意を。

続いてサブスクリプションとオブジェクト別にユーザーのロールを割り当てます。
$resourceGroupNameにストレージアカウントを置いたリソースグループの名前を、
$subscriptionIdに作成したサブスクリプションのID(AzurePortalから確認)を、
$assigneeObjectIdに一つ前に控えたidを入れて以下コードを実行しましょう。

Azure CLI
az role assignment create --role contributor --scope /subscriptions/$subscriptionId/resourceGroups/$resourceGroupName --subscription $subscriptionId --assignee-object-id  $assigneeObjectId --assignee-principal-type ServicePrincipal

この後元の記事では以下のコードをAzure CLIで打ち込みますが、私の場合は「実行結果」にあるようにエラーが発生してしまいました。

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上から検索。
[管理から] [証明書とシークレット] を選択し、[フェデレーション資格情報] タブを選択してから、[資格情報の追加]をクリックしましょう。

image.png

[フェデレーション資格情報シナリオ]を[Azure リソースをデプロイする GitHub Action]に選択、組織とリポジトリは今回デプロイ元にするGitHubのリモートリポジトリの情報を入力してください。エンティティ型は今回はBranchへのcommitをトリガーとするので、「Branch」としましょう。そうすると下の入力欄にどのBranchでトリガーするか聞かれるので、今回はmainにして開発用ブランチから本番移行する時にデプロイする仕様にします。最後にこの資格情報自体の[名前]を書いてクレデンシャルの発行完了です。

image.png

作成したアプリケーションのOverview = 概要を確認しましょう。
GitHubと連携する時に必要な各種IDが記載されています。
使用しているサブスクリプションのIDとともに、コピーして控えておきましょう。

  • アプリケーション(クライアント)ID
  • ディレクトリ(テナント)ID
  • サブスクリプションID

GitHub SecretにAzure側の連携先情報を格納する

以下の記事を参考にGitHubの公式サイトからデプロイ対象のリポジトリに入り、Actionsを設定します。

Settings→Secrets and variables→Actionsの順で開きましょう

スクリーンショット 2023-12-30 13.09.37.png

開いたら緑色の「New repository secret」を押しNameとSecretを入力しておきます。
上記画像の通りNameに大文字で定数名を、SecretにさっきAzurePortalで確認した値を入れておきましょう。

Azureログイン→デプロイ→ログアウトする処理を書く

元の記事"ワークフローを追加する" を参考にして、対象のリポジトリのページから "Actions" を選択。

image.png

青字で光る ”set up a workflow yourself” を選びます。

スクリーンショット 2023-12-30 19.51.22.png

コードを書け!と言われるので、元の記事にあったコードを参考にした以下を貼付け。
一部大文字での<>部分は今回作ったリソースにあわせ値を格納してください。

YAML
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"からも確認可能です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1