🔥

GitHub Actionsを使用したAzureリソースのIaCデプロイ

2024/11/08に公開

はじめに

Infrastructure as Code (IaC)を用いたAzureリソースのデプロイは、Azure DevOpsだけでなく、GitHub Actions上でも実行可能です。本記事では、GitHub Actionsを用いたIaC(Bicepファイル)デプロイ手法と、その際に用いる資格情報のパターンについて紹介します。また、Azure DevOpsとの比較として、GitHub Actionsで用いる資格情報の動作確認プロセスにも触れます。

本記事の ソースコードは、Gitに登録しています。

https://github.com/yutaka-art/bicep_deployment

デプロイ時に利用する資格情報

Azure上にIaCデプロイを行う際、Azureリソースへの認証には主に以下の2パターンが存在します。

  1. サービスプリンシパルを用いた認証
  2. OpenID Connect (OIDC) を用いた Workload Identity による認証

GitHub Actionsで従来から用いられてきたのは、サービスプリンシパルを使用してAzureにログインする方法です。しかし、よりセキュアでトークンの使い捨てが可能なOIDCを利用することで、GitHubリポジトリから直接Azureリソースへのトラストベースなアクセスが可能になります。
OIDCを使用することで、Azure AD(Entra ID)上で特別な秘密情報を保存する必要がなく、GitHubからのアクセスをより安全かつ柔軟に管理できます。

Azure Service Principalの登録とGitHub⇔Azureのコネクション

Entra ID>アプリの登録をしサービスプリンシパルとして構成します。
続いて、証明書とシークレットより、フェデレーション資格情報を構成します。

GitHub シークレットへ登録する情報

GitHub ActionsでAzureへログインする場合、特定のシークレットが必要になります。以下はサービスプリンシパル利用時に必要となる情報と、GitHub シークレットとの対応関係です。なお、OIDCを利用する場合でも、azure/login Actionで関連パラメータを渡すために同様の値が求められます。

GitHub シークレット Microsoft Entra アプリケーションの値
AZURE_CLIENT_ID アプリケーション (クライアント) ID
AZURE_TENANT_ID ディレクトリ (テナント) ID
AZURE_SUBSCRIPTION_ID サブスクリプション ID

これらは GitHubリポジトリ > Settings > Secrets and variables > Actions から登録可能です。

サンプルワークフロー(OIDC利用時)

以下は、OIDCベースでAzureに認証し、Bicepを用いてリソースをデプロイするGitHub Actionsのサンプルです。
workflow_dispatchで手動前提としていますが、よしなに変えてください。

name: Deploy Bicep using ARM Deploy

on:
  workflow_dispatch:
    inputs:
      azureRgName:
        description: 'Azure Resource Group Name'
        required: true
        default: 'rg-bicep-osa-test-001'
      environmentType:
        description: 'Environment type (nonprod or prod)'
        required: true
        default: 'nonprod'
      deployAmeretatManualsStorageAccount:
        description: 'Deploy Ameretat Manuals Storage Account (true or false)'
        required: true
        default: 'true'

# OIDC認証を使用してAzureにログインしている場合(id-token: write が必要)
# リポジトリからBicepファイルを取得している場合(contents: read が必要)
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      # Azure CLIでのログイン
      - name: 'Login to Azure'
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      # 必要に応じてリポジトリをチェックアウト
      - name: 'Checkout repository'
        uses: actions/checkout@v3

      # 定義したパラメータを確認
      - name: 'Set parameters as environment variables'
        run: |
          echo "ENVIRONMENT_TYPE=${{ github.event.inputs.environmentType }}"
          echo "DEPLOY_AMERETAT_STORAGE=${{ github.event.inputs.deployAmeretatManualsStorageAccount }}"

      # ARM Deployを使用したBicepファイルのデプロイ
      - name: 'Deploy Bicep file'
        uses: azure/arm-deploy@v1
        with:
          subscriptionId: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
          resourceGroupName: ${{ github.event.inputs.azureRgName }}
          template: deploy/main.bicep
          parameters: >
            environmentType=${{ github.event.inputs.environmentType }}
            deployAmeretatManualsStorageAccount=${{ github.event.inputs.deployAmeretatManualsStorageAccount }}
          deploymentMode: Incremental
          failOnStdErr: false

ポイント

  • permissions セクションで id-token: writecontents: read を設定することで、OIDC認証とリポジトリ内容へのアクセスが可能になります。
  • azure/login@v1 Actionを用いてOIDCを使用したAzureログインを実施します。
  • azure/arm-deploy@v1 Actionにより、BicepファイルをARMテンプレートとしてデプロイします。

Azure DevOpsとの違い(サービスコネクション vs GitHub Secrets)

Azure DevOpsでのデプロイ時には、サービスコネクションを用いてAzureリソースへの接続性を事前検証できます。例えば、Azure DevOpsの「Service connections」からAzureへの接続を事前に確認しておけば、ワークフロー実行前に資格情報の有効性を把握できます。

一方、GitHub Actionsでは、SecretsやOIDC設定を行っても、実際にワークフローをトリガーしてみるまで、資格情報が正しくAzureと通信できるかを確実には把握しづらい点があります。つまり、「設定後すぐにボタン一つで接続性をテスト」するような仕組みは現在のところ存在せず、ワークフロー実行(=実運用に近い形)で初めて有効性を確認できます。

これは、GitHub ActionsとAzure DevOpsの運用思想の違いとも言えます。GitHub Actionsの場合、セキュリティや運用設計の中で、事前検証のプロセスを別途用意することを検討する必要があるでしょう。

疎通だけであれば下記のようにCLIを発行するActionsを作成し、確認するのもいいかもしれません。

name: Run Azure Login with OpenID Connect

on:
  workflow_dispatch:
#  push:
#    branches: [ main ]

permissions:
      id-token: write
      contents: read
 
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    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 account show
          az group list
          pwd

参考リンク

GitHubで編集を提案

Discussion