使用 Bicep 參數處理環境之間的差異

已完成

您已經了解 Bicep 參數。 其會協助您指定可在 Bicep 檔案部署之間變更的值。

參數通常會用來支援環境之間的差異。 例如,在您的非實際執行環境中,通常會想要部署 Azure 資源的低成本 SKU。 在實際執行環境中,則想要部署效能更佳的 SKU。 而且您以針對每個環境中的資源使用不同名稱。

部署 Bicep 檔案時,會提供每個參數的值。 有幾個選項可讓您從工作流程指定每個參數的值,以及為每個環境指定個別的值。 在此單元中,您將了解在部署工作流程中指定 Bicep 參數值的方法。

參數檔案

參數檔案是 JSON 格式的檔案,會列出您想要針對每個環境使用的參數值。 當您提交部署時,要將參數檔案提交至 Azure Resource Manager。

以下是範例參數檔案:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "reviewApiUrl": {
      "value": "https://sandbox.contoso.com/reviews"
    }
  }
}

可將參數檔案與 Bicep 檔案一同提交至 Git 存放庫。 接著,您可以在執行部署的工作流程範本中參考該參數檔案。

最好針對參數檔案採取一致的環境命名策略。 例如可將參數檔案命名為 parameters.ENVIRONMENT_NAME.json,例如 parameters.Production.json。 接著,您可以使用工作流程範本輸入,根據輸入值自動選取正確的參數檔案。

on:
  workflow_call:
    inputs:
      environmentType:
        required: true
        type: string
      # ...

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    # ...
    - uses: azure/arm-deploy@v1
      with:
        failOnStdErr: false
        resourceGroupName: ${{ inputs.resourceGroupName }}
        template: ./deploy/main.bicep
        parameters: ./deploy/azuredeploy.parameters.${{ inputs.environmentType }}.json

使用參數檔案時,工作流程 YAML 檔案不需要包含個別傳遞至部署步驟所需的參數清單。 當您具有大量參數時,這特別實用。

參數檔案會將參數值一起保存於單一 JSON 檔案中。 參數檔案也是您 Git 存放庫的一部分,因此,可按照與您所有其他程式碼相同的方式來建立版本。

重要

參數檔案不應該用於安全值。 沒有任何方法可以保護參數檔案中的祕密值,而且絕對不得將祕密提交至 Git 存放庫。

工作流程變數

GitHub Actions 可讓您儲存「工作流程變數」,若值在不同環境中有所差異,則其相當實用。 它們也適用於您希望只定義一次,然後就能在整個工作流程中重複使用的值。

在 YAML 檔案中定義的變數

您可以在 YAML 檔案中定義變數並設定其值。 當您需要多次重複使用相同的值時,這種方式非常實用。 您可以為整個工作流程、某個作業或單一步驟定義變數:

env:
  MyVariable1: value1

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      MyVariable2: value2
    steps:
    - run: echo Hello world!
      env:
        MyVariable3: value3

在 Web 介面中定義的祕密

如同 Bicep 參數檔案,YAML 檔案不適用於祕密。 您可以改為使用 GitHub Web 介面來定義祕密。 您隨時都能變更變數值,而工作流程將在下次執行時讀取更新的值。 GitHub Actions 會嘗試隱藏工作流程記錄中祕密的值。 這表示您可以儲存 Bicep 檔案,再以參數搭配 @secure() 裝飾項目的形式加以接受。

警告

GitHub Actions 預設會模糊化工作流程記錄中的祕密變數值,而您也必須遵循良好的做法。 您的工作流程步驟可存取祕密的值。 如果您的工作流程包含未安全地處理祕密的步驟,則工作流程記錄中有可能會顯示祕密值。 您應該一律仔細檢閱對工作流程定義檔案的任何變更,以確認不會錯誤地處理祕密。

當您建立祕密時,GitHub 可讓您選擇要將其範圍設定為您的整個 Git 存放庫或特定環境。 環境範圍的秘密會接受您在環境中設定的保護規則,因此,如果您設定了必要的檢閱者規則,則在指定的 GitHub 使用者核准您的管線部署到該環境之前,工作流程將無法存取祕密的值。

環境範圍的祕密可能非常實用,但它們無法輕易地處理 Azure Resource Manager 的預檢驗證或假設狀況作業。 這些作業需要與 Azure 通訊,這表示它們需要工作負載身分識別。 您通常希望在預檢驗證或假設狀況作業完成「之後」提供部署核准,如此就會對您要部署的變更具有高信賴度。 因此,如果您使用環境範圍的祕密,人工檢閱流程就會在工作流程中過早發生。

基於這個理由,在此課程模組的練習中,您不會使用環境範圍的祕密。 您會改用包含環境名稱的可預測名稱來建立存放庫範圍的祕密。 這樣便能讓您的工作流程識別針對每個環境所使用的正確祕密。 在您自己的工作流程中,您可以選擇使用存放庫範圍的祕密、環境範圍的祕密,甚至是兩者混用。

注意

您也可以將祕密的範圍設為 GitHub 組織。 雖然這不是此課程模組的範圍,但我們會在摘要中連結至詳細資訊。

在工作流程中使用變數

在工作流程中存取變數值的方式,取決於變數的類型。

類型 語法
在相同檔案中定義的變數 ${{ env.VARIABLE_NAME }}
已呼叫工作流程的輸入 ${{ inputs.INPUT_NAME }}
密碼 ${{ secrets.SECRET_NAME }}

例如,在執行 Bicep 部署時,可以使用祕密來指定要使用的 Azure 工作負載身分識別、用於指定資源群組名稱的已呼叫工作流程輸入,以及用於指定參數值的變數:

jobs:
  deploy:
    runs-on: ubuntu-latest
    env:
      MyParameter: value-of-parameter
    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 }}
    - uses: azure/arm-deploy@v1
      with:
        failOnStdErr: false
        resourceGroupName: ${{ inputs.resourceGroupName }}
        template: ./deploy/main.bicep
        parameters: myParameter=${{ env.MyParameter }}

什麼是最好的方法?

您已了解數種可針對您的部署處理 Bicep 檔案所需參數的方式。 知道何時該使用哪種方法,很有助益。

避免不必要的參數

參數可協助您讓 Bicep 檔案可重複使用,但很容易定義太多參數。 部署 Bicep 檔案時,需要提供每個參數的值。 在針對多個環境的複雜部署中,很難管理一大組個別參數值。

建議盡量將參數設為選用,並使用適用於大部分環境的預設值。 接下來要避免工作流程需要傳入參數值。

也請記得,資源需要連接到其他資源時,通常會在 Bicep 中使用參數。 例如,若有網站需要連接到儲存體帳戶,則必須提供儲存體帳戶名稱和存取金鑰。 金鑰是安全值。 不過,在部署這個資源組合時,請考慮下列其他方法:

  • 使用網站的受控識別來存取儲存體帳戶。 當您建立受控識別時,Azure 會自動產生和管理其認證。 此方法可簡化連線設定。 這也表示您完全不需要處理祕密,因此這是最安全的選項。
  • 以相同的 Bicep 範本一起部署儲存體帳戶和網站。 使用 Bicep 模組,將網站和儲存體資源保留在一起。 然後,您可以在 Bicep 程式碼中自動查閱儲存體帳戶名稱和金鑰的值,而不需傳入參數。
  • 將儲存體帳戶的詳細資料新增至金鑰保存庫以作為祕密。 然後網站程式碼會直接從保存庫載入存取金鑰。 這種方法完全不需要在工作流程中管理金鑰。

針對一小組參數使用工作流程變數

如果您只有少數適用於 Bicep 檔案的參數,請考慮在 YAML 檔案中定義變數。

針對一大組參數集使用參數檔案

如果您有一大組適用於 Bicep 檔案的參數,請考慮使用參數檔案,將每個環境的非安全值保留在一起。 然後,每當您需要變更值時,就可以更新參數檔案並認可變更。

這種方法能讓工作流程步驟更簡單,因為不需要明確設定每個參數的值。

安全儲存祕密

使用適當的流程來儲存和處理祕密。 使用 GitHub 祕密來將祕密儲存於 GitHub 存放庫中,或使用 Key Vault 來將祕密儲存於 Azure 中。

針對安全參數,務必將每個參數明確傳遞到您的部署步驟。

GitHub 可自動掃描存放庫以尋找意外認可的祕密,讓您獲得通知。 然後,您可以移除及輪替秘密。 如需此功能的詳細資訊,請前往摘要中的連結。

合併方法

合併多種方法來處理參數,是很常見的做法。 例如,您可以將大多數的參數值儲存在參數檔案中,然後使用祕密來設定安全值。 下列範例說明了此一組合:

on:
  workflow_dispatch:
    inputs:
      environmentType:
        required: true
        type: string
      resourceGroupName:
        required: true
        type: string
    secrets:
      AZURE_CLIENT_ID:
        required: true
      AZURE_TENANT_ID:
        required: true
      AZURE_SUBSCRIPTION_ID:
        required: true
      MySecureParameter:
        required: true

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    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 }}
    - uses: azure/arm-deploy@v1
      with:
        failOnStdErr: false
        resourceGroupName: ${{ inputs.resourceGroupName }}
        template: ./deploy/main.bicep
        parameters: >
          ./deploy/azuredeploy.parameters.${{ inputs.environmentType }}.json
          mySecureParameter=${{ secrets.MySecureParameter }}

提示

在此範例結尾,使用 > 字元,以 YAML 多行字串的形式提供 parameters 值。 這可讓 YAML 檔案更容易讀取。 這相當於在單一行中包含整個值。