共用方式為


使用 GitHub Actions 和 Azure 建置自訂虛擬機器映像

建立工作流程來建置虛擬機器映像,以開始使用 GitHub Actions

使用 GitHub Actions,您可以使用工作流程中的成品建立自訂虛擬機器映像,以加速 CI/CD 程序。 您可以建置映像,並將其分發至 共用映像庫

然後,您可以使用這些映像來建立 虛擬機器虛擬機器擴展集

建置虛擬機器映像動作會使用 Azure 映像產生器服務

先決條件

工作流程檔案概觀

工作流程是由您存放庫內 /.github/workflows/ 路徑中的 YAML (. yml) 檔案所定義的。 此定義包含組成工作流程的各種步驟與參數。

該檔案有三個部分:

章節 任務
驗證 1. 新增使用者管理的身分識別。
2. 設定服務主体或 Open ID Connect。
3. 建立 GitHub 秘密。
構建 1. 設置環境。
2. 構建應用程序。
圖像 1. 建立虛擬機器映像。
2. 建立虛擬機器。

建立使用者受控識別

您需要使用者管理的 Azure 影像建構器 (AIB) 身份認證,才能分發映像。 您的 Azure 使用者指派的受控識別將會在映像組建期間使用,以讀取映像並將其寫入共用映像庫。

  1. 使用 Azure CLIAzure 入口網站建立使用者受控識別。 記下受控識別的名稱。

  2. 自訂此 JSON 程式碼。 將 {subscriptionID}{rgName} 預留位置替換為您的訂用帳戶識別碼和資源群組名稱。

    {
    "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 入口網站中,開啟 Azure Compute Gallery,然後移至 [存取控制 (IAM)]。

  5. 選取 新增角色指派,並將影像建立角色指派至您的使用者受控身分識別。

產生部署認證

若要搭配 OIDC 使用Azure 登入動作,您必須在 Microsoft Entra 應用程式或使用者指派的受控身分識別上設定同盟身分憑證。

選項 1:Microsoft Entra 應用程式

選項 2:使用者指派的受控識別

建立 GitHub 祕密

您必須將應用程式的 用戶端識別碼目錄(租使用者)標識碼和訂用帳戶 識別碼 提供給登入動作。 這些值可以直接在工作流程中提供,也可以儲存於 GitHub 祕密中,並在您的工作流程中參考。 將值儲存為 GitHub 祕密是較安全的選項。

  1. GitHub 中,移至您的存放庫。

  2. 選取 [安全性] > [祕密和變數] > [動作]

    新增秘密的螢幕快照

  3. 選取 [新增存放庫祕密]

    備註

    若要增強公用存放庫中的工作流程安全性,請使用 環境秘密 ,而不是存放庫秘密。 如果環境需要核准,則作業在其中一位必要的檢閱者核准之前,無法存取環境秘密。

  4. 建立 AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_SUBSCRIPTION_ID 的祕密。 從 Microsoft Entra 應用程式或使用者指派的受控識別中複製這些值,以用於 GitHub 機密:

    GitHub 祕密 Microsoft Entra 應用程式或使用者指派的受管理識別
    AZURE_CLIENT_ID(Azure 用戶端識別碼) 用戶端識別碼
    AZURE_SUBSCRIPTION_ID 訂用帳戶識別碼
    AZURE_TENANT_ID 目錄(租戶)識別碼

    備註

    基於安全理由,建議使用 GitHub Secrets,而不是將值直接傳遞至工作流程。

使用 Azure 登入動作

搭配 Azure 登入動作 使用您的 GitHub 秘密,向 Azure 進行驗證。

對於 Open ID Connect,您將使用與 Active Directory 應用程式相關聯的聯合認證。

如需在工作流程檔案中參考 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@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

設定 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@v2
      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} 的預留位置分別取代為您的訂用帳戶識別碼、資源群組名稱和受控識別名稱。 將{galleryName}的值和{imageName}的值取代為您的影像庫名稱和影像名稱。

備註

如果 [建立應用程式烘焙映像] 動作失敗並出現權限錯誤,請確認您已將映像建立角色指派給使用者受控識別。

    - 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'

虛擬機器動作引數

Input 為必填項目 Description
resource-group-name Yes 在建置程序期間用來儲存及儲存構件的資源群組。
image-builder-template-name 使用的映像產生器範本資源的名稱。
location Yes Azure 映像產生器將執行的位置。 請參閱 支援的位置
build-timeout-in-minutes 達到時間後將取消建置。 預設為 240。
vm-size 可選 預設情況下,將使用 Standard_D1_v2。 請參閱 虛擬機器大小
managed-identity Yes 您稍早建立的使用者管理的身分識別。 如果您的身分識別位於不同的資源群組中,請使用完整識別碼。 如果名稱位於相同的資源群組中,請使用該名稱。
source-os Yes 基礎映像的作業系統類型 (Linux 或 Windows)
source-image-type Yes 將用於建立自訂映像的基礎映像類型。
source-image Yes 基底映像的資源識別碼。 來源映像應該存在於位置輸入值中設定的相同 Azure 區域中。
customizer-source 您可以保留需要新增至基礎映像檔以進行自訂的所有構件的目錄。 依預設,值為 ${{ GITHUB.WORKSPACE }}/workflow-artifacts.
customizer-destination 這是自訂映像檔中將構件複製到的目錄。
customizer-windows-update 僅適用於 Windows。 布林值。 如果 true,則映像產生器會在自訂設定結束時執行 Windows 更新。
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@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - 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 }}"              

後續步驟