GitHub Actions および Azure を使用してカスタムの仮想マシン イメージを構築する

仮想マシン イメージを構築するためのワークフローを作成することによって、GitHub Actions を開始します。

GitHub Actions を使用すると、ワークフローの成果物を使用してカスタム仮想マシン イメージを作成することにより、CI/CD プロセスを高速化できます。 イメージを作成し、Shared Image Galleryに配布できます。

これらのイメージを使用して、仮想マシン仮想マシン スケール セットを作成できます。

仮想マシン イメージの構築アクションでは、Azure Image Builder サービスを使用します。

前提条件

ワークフロー ファイルの概要

ワークフローは、お使いのリポジトリの /.github/workflows/ パスの YAML (.yml) ファイルに定義されます。 この定義には、ワークフローを構成するさまざまな手順とパラメーターが含まれます。

このファイルには 3 つのセクションがあります。

Section タスク
認証 1. ユーザー管理 ID を追加します。
2. サービス プリンシパルまたは Open ID Connect を設定します。
3. GitHub シークレットを作成します。
ビルド 1.環境を設定します。
2. アプリをビルドします。
イメージ 1. VM イメージを作成します。
2. 仮想マシンを作成します。

ユーザー 管理 ID を作成する

イメージを配布するには、Azure Image Builder (AIB) のユーザー管理 ID が必要です。 Azure ユーザーによって割り当てられたマネージド ID は、イメージのビルド中に、Shared Image Gallery に対するイメージの読み取りと書き込みを行うために使用されます。

  1. Azure CLIまたはAzure portalを使用して、ユーザー管理 ID を作成します。 管理 ID の名前をメモしておきます。

  2. この JSON コードをカスタマイズします。 {subscriptionID}{rgName} のプレースホルダーをサブスクリプション ID とリソース グループ名に置き換えます。

    {
    "properties": {
        "roleName": "Image Creation Role",
        "IsCustom": true,
        "description": "Azure Image Builder access to create resources for the image build",
        "assignableScopes": [
          "/subscriptions/{subscriptionID}/resourceGroups/{rgName}"
        ],
        "permissions": [
            {
                "actions": [
                    "Microsoft.Compute/galleries/read",
                    "Microsoft.Compute/galleries/images/read",
                    "Microsoft.Compute/galleries/images/versions/read",
                    "Microsoft.Compute/galleries/images/versions/write",
                    "Microsoft.Compute/images/write",
                    "Microsoft.Compute/images/read",
                    "Microsoft.Compute/images/delete"
                ],
                "notActions": [],
                "dataActions": [],
                "notDataActions": []
            }
        ]
        } 
    } 
    
  3. この JSON コードを使用して、JSON で新しいカスタム ロールを作成します。

  4. Azure portal で Azure Compute Gallery を開き、アクセス制御 (IAM) に移動します。

  5. [ロールの割り当ての追加] を選択し、イメージの作成ロールをユーザー マネージド ID に割り当てます。

デプロイ資格情報を生成する

Azure CLIaz ad sp create-for-rbac コマンドを使用して、サービス プリンシパルを作成します。 このコマンドは、Azure portal で Azure Cloud Shell を使用するか、[試してみる] ボタンを選択して実行します。

az ad sp create-for-rbac --name "myML" --role contributor \
                            --scopes /subscriptions/<subscription-id>/resourceGroups/<group-name> \
                            --json-auth

--json-auth パラメーターは、Azure CLI バージョン 2.51.0 以降で使用できます。 これ以前のバージョンでは --sdk-auth を使用し、非推奨の警告が表示されます。

上記の例で、プレースホルダーをご利用のサブスクリプション ID、リソース グループ名、アプリ名に置き換えます。 これにより、以下のようなご自分の App Service アプリにアクセスするためのロールの割り当て資格情報を含む JSON オブジェクトが出力されます。 この JSON オブジェクトを後のためにコピーします。

  {
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    (...)
  }

GitHub シークレットを作成する

  1. GitHub で、お使いのリポジトリに移動します。

  2. ナビゲーション メニューで [設定] に移動します。

  3. [Security] (セキュリティ) > [Secrets and variables] (シークレットと変数) > [Actions] (アクション) を選びます。

    Screenshot of adding a secret

  4. [New repository secret](新しいリポジトリ シークレット) を選択します。

  5. Azure CLI コマンドからの JSON 出力全体をシークレットの値フィールドに貼り付けます。 シークレットに AZURE_CREDENTIALS と名前を付けます。

  6. [Add secret](シークレットの追加) を選択します。

Azure ログイン アクションを使用する

Azure で認証するには、GitHub シークレットと Azure Login アクションを使用します。

このワークフローでは、secrets.AZURE_CREDENTIALS に格納されているサービス プリンシパルの詳細を使用して、Azure login アクションを使って認証を行います。 次に、Azure CLI アクションを実行します。 ワークフロー ファイルで GitHub シークレットを参照する方法の詳細については、GitHub Docs の「ワークフローでの暗号化されたシークレットの使用」をご覧ください。

on: [push]

name: Create Custom VM Image

jobs:
  build-image:
    runs-on: ubuntu-latest
    steps:
      - name: Log in with Azure
        uses: azure/login@v1
        with:
          creds: '${{ secrets.AZURE_CREDENTIALS }}'

Java を構成する

Java セットアップ SDK アクションを使用して java 環境を設定します。 この例では、環境を設定し、Maven でビルドして、成果物を出力します。

GitHub 成果物 は、ジョブ間でワークフロー内のファイルを共有する方法です。 JAR ファイルを保持する成果物を作成し、それを仮想マシン イメージに追加します。

on: [push]

name: Create Custom VM Image

jobs:
  build-image:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: [ '17' ]

    steps:
    - name: Checkout
      uses: actions/checkout@v3    

    - name: Login via Az module
      uses: azure/login@v1
      with:
        creds: ${{secrets.AZURE_CREDENTIALS}}

    - name: Set up JDK ${{matrix.java}}
      uses: actions/setup-java@v2
      with:
        java-version: ${{matrix.java}}
        distribution: 'adopt'
        cache: maven
    - name: Build with Maven Wrapper
      run: ./mvnw -B package
        
    - name: Build Java
      run: mvn --batch-mode --update-snapshots verify

    - run: mkdir staging && cp target/*.jar staging
    - uses: actions/upload-artifact@v2
      with:
        name: Package
        path: staging

イメージのビルド

Azure 仮想マシン イメージの構築アクションを使用して、カスタム仮想マシン イメージを作成します。

{subscriptionID}{rgName}{Identity} のプレースホルダーをサブスクリプション ID、リソース グループ名および管理 ID 名に置き換えます。 {galleryName}{imageName} の値を イメージ ギャラリー名とイメージ名に置き換えます。

Note

Create App Baked Image アクションがアクセス許可エラーで失敗する場合は、イメージの作成ロールがユーザー マネージド ID に割り当てられていることを確認してください。

    - name: Create App Baked Image
      id: imageBuilder
      uses: azure/build-vm-image@v0
      with:
        location: 'eastus2'
        resource-group-name: '{rgName}'
        managed-identity: '{Identity}' # Managed identity
        source-os-type: 'windows'
        source-image-type: 'platformImage'
        source-image: MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest #unique identifier of source image
        dist-type: 'SharedImageGallery'
        dist-resource-id: '/subscriptions/{subscriptionID}/resourceGroups/{rgName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{imageName}/versions/0.1.${{ GITHUB.RUN_ID }}' #Replace with the resource id of your shared image  gallery's image definition
        dist-location: 'eastus2'

仮想マシン アクションの引数

入力 必須 Description
resource-group-name はい ビルド処理中にストレージと成果物を保存するために使用されるリソース グループ。
image-builder-template-name いいえ 使用するイメージ ビルダー テンプレート リソースの名前。
location はい Image Builder が実行される場所です。 サポートされる場所を参照してください。
build-timeout-in-minutes いいえ ビルドがキャンセルされるまでの時間です。 既定値は 240 です。
vm-size 省略可能 既定では Standard_D1_v2 が使用されます。 仮想マシンのサイズを参照してください。
managed-identity はい 前に作成したユーザー管理 ID。 ID が別のリソース グループにある場合は、完全な識別子を使用します。 同じリソース グループ内にある場合は、名前を使用します。
source-os はい 基本イメージの OS の種類 (Linux または Windows)
source-image-type はい カスタム イメージの作成に使用される基本イメージの型。
source-image はい 基本イメージのリソース識別子です。 ソース イメージは、場所の入力値に設定されているのと同じ Azure リージョンに存在する必要があります。
customizer-source いいえ カスタマイズのために基本イメージに追加する必要があるすべての成果物を保持できるディレクトリ。 既定値は ${{ GITHUB.WORKSPACE }}/workflow-artifacts. です。
customizer-destination いいえ これは、成果物のコピー先のカスタマイズされたイメージ内のディレクトリです。
customizer-windows-update いいえ Windows のみ。 ブール値。 trueの場合 、イメージ ビルダーは、カスタマイズの最後に Windows Update を実行します。
dist-location いいえ SharedImageGallery の場合、これは dist-type です。
dist-image-tags いいえ これらは、作成されたカスタム イメージ (例: version:beta) に追加されるユーザー定義のタグです。

仮想マシンを作成する

最後の手順として、イメージから仮想マシンを作成します。

  1. {rgName} のプレースホルダーを目的のリソース グループとサイト名に置き換えます。

  2. 仮想マシンのパスワード (VM_PWD) を使用して、GitHub シークレットを追加します。 パスワードは、もう一度確認することができないため、書き留めておいてください。 ユーザー名は myuser です。

    - name: CREATE VM
      uses: azure/CLI@v1
      with:
        azcliversion: 2.0.72
        inlineScript: |
        az vm create --resource-group ghactions-vMimage  --name "app-vm-${{ GITHUB.RUN_NUMBER }}"  --admin-username myuser --admin-password "${{ secrets.VM_PWD }}" --location  eastus2 \
            --image "${{ steps.imageBuilder.outputs.custom-image-uri }}"              

YAML の完了

  on: [push]

  name: Create Custom VM Image

  jobs:
    build-image:
      runs-on: ubuntu-latest    
      steps:
      - name: Checkout
        uses: actions/checkout@v2    

      - name: Login via Az module
        uses: azure/login@v1
        with:
          creds: ${{secrets.AZURE_CREDENTIALS}}

      - name: Setup Java 1.8.x
        uses: actions/setup-java@v1
        with:
          java-version: '1.8.x'
          
      - name: Build Java
        run: mvn --batch-mode --update-snapshots verify

      - run: mkdir staging && cp target/*.jar staging
      - uses: actions/upload-artifact@v2
        with:
          name: Package
          path: staging

      - name: Create App Baked Image
        id: imageBuilder
        uses: azure/build-vm-image@v0
        with:
          location: 'eastus2'
          resource-group-name: '{rgName}'
          managed-identity: '{Identity}' # Managed identity
          source-os-type: 'windows'
          source-image-type: 'platformImage'
          source-image: MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest #unique identifier of source image
          dist-type: 'SharedImageGallery'
          dist-resource-id: '/subscriptions/{subscriptionID}/resourceGroups/{rgName}/providers/Microsoft.Compute/galleries/{galleryName}/images/{imageName}/versions/0.1.${{ GITHUB.RUN_ID }}' #Replace with the resource id of your shared image  gallery's image definition
          dist-location: 'eastus2'

      - name: CREATE VM
        uses: azure/CLI@v1
        with:
          azcliversion: 2.0.72
          inlineScript: |
          az vm create --resource-group ghactions-vMimage  --name "app-vm-${{ GITHUB.RUN_NUMBER }}"  --admin-username myuser --admin-password "${{ secrets.VM_PWD }}" --location  eastus2 \
              --image "${{ steps.imageBuilder.outputs.custom-image-uri }}"              

次のステップ