掌握自動化部署,拿下DevOps半壁江山還遠嗎?

微軟技術棧發表於2022-01-31

本期的微軟 MVP 實驗室研究員-貟乾,將通過程式碼示例為大家分享如何使用 GitHub Actions 以自動化的方式部署 Terraform Code 到 Azure。

貟乾,微軟最有價值專家,Microsoft Azure方向,目前從事.NET技術棧產品後端開發工作。熱衷學習微軟Azure相關技術,分享自己的學習經驗。同時,正在提高自己Azure雲基礎設施解決方案的設計能力和Azure雲技術方面的培訓能力

思路淺析

使用 Terraform Code 部署 Azure 基礎設施資源是特別受歡迎的,我曾經有寫文章分享過利用 Azure DevOps 自動部署 Terraform Code 所描述的 Azure 基礎設施資源。但是有些人對於Azure DevOps 可能比較陌生,再加上 Azure DevOps 的 Parallel jobs 付費作業。所以作為替代方案,今天給大家分享如何使用 GitHub Actions 部署 Terraform Code。
image.png

配置 Azure Service Principal 的憑據到 GitHub 機密庫

Terraform Code 以及Azure CLI 會使用 Azure Service Principle 對 Azure 進行身份認證,關於 Azure Service Principle 的建立大家可以參考Blog。
Blog:https://www.cnblogs.com/Allen...

接下來需要新增以下機密資訊
  1)AZURE_AD_CLIENT_ID
  2)AZURE_AD_CLIENT_SECRET
  3)AZURE_AD_TENANT_ID
  4)AZURE_SUBSCRIPTION_ID
  5)AZURE_CREDENTIALS

其中 AZURE_CREDENTIALS 格式內容如下所示:

"clientId": "XXXX",
"clientSecret": "XXXX",
"subscriptionId": "XXXX",
"tenantId": "XXXX"

將上述資訊儲存到對應名稱的 GitHub Secrets。
image.png

配置 workflows run 的 yaml

在 Terraform 專案根目錄建立 terraform.yaml 並儲存在以下目錄
image.png

terraform.yaml 內容如下


name: " using GitHub Action for Terraform Auto CI/CD"
on:
  pull_request:
    branches:
      - remote_stats
  push:
    branches:
      - remote_stats
env:
  tf_version: "latest"
  tf_working_dir: "./src/model/"
  terraform_rg: "Web_Test_TF_RG"
  storage_account: "cnbatestorestatefile004"
  storage_account_container: "terraform-state"
  key: "cnbate.terraform.stats"
jobs:
  terraform_auto_deploy:
    name: "Azure CLI Action (secrect created)"
    env:
      ARM_CLIENT_ID: ${{ secrets.AZURE_AD_CLIENT_ID }}
      ARM_CLIENT_SECRET: ${{ secrets.AZURE_AD_CLIENT_SECRET }}
      ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      ARM_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }}
    runs-on: ubuntu-latest
    environment: production
 
    # Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
    defaults:
      run:
        shell: bash
    steps:
      - name: "Checkout"
        uses: actions/checkout@master
      - name: Azure Login
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
          enable-AzPSSession: false
          environment: azurecloud
          allow-no-subscriptions: false
      - name: Azure CLI script
        uses: azure/CLI@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
          enable-AzPSSession: false
          environment: azurecloud
          allow-no-subscriptions: false
          azcliversion: 2.30.0
          inlineScript: |
 
            # create azure resource group
            az group create --location eastasia --name ${{ env.terraform_rg }}
 
            # create azure storage account
            az storage account create --name ${{ env.storage_account }} --resource-group ${{ env.terraform_rg }} --location eastasia --sku Standard_LRS
 
            # create storage account container for tf state
            az storage container create --name ${{ env.storage_account_container }} --account-name ${{ env.storage_account }}
 
            # query storage key and set variable
            export ARM_ACCESS_KEY=$(az storage account keys list --resource-group ${{env.terraform_rg}} --account-name ${{ env.storage_account }} --query "[?keyName == 'key1'][value]" --output tsv)
 
            echo $ARM_ACCESS_KEY
 
      - name: "Terraform init azurerm backend"
        uses: ahmedig/terraform-azurerm-backend@v1
        with:
          azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
          resource_group_name: ${{ env.terraform_rg }}
          container_name: ${{ env.storage_account_container }}
          storage_account_name: ${{ env.storage_account }}
          file_name: ${{ env.key }}
          subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
          tf_working_directory: ${{ env.tf_working_dir }}
 
      - name: "Terraform Validate"
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: ${{ env.tf_version }}
          tf_actions_subcommand: 'validate'
          tf_actions_working_dir: ${{ env.tf_working_dir }}
        env:
          GITHUB_TOKEN: ${{ secrets.AZURE_CREDENTIALS }}
 
      - name: "Terraform Plan"
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: ${{ env.tf_version }}
          tf_actions_subcommand: 'plan'
          tf_actions_working_dir: ${{ env.tf_working_dir }}
        env:
          GITHUB_TOKEN: ${{ secrets.AZURE_CREDENTIALS }}
 
      - name: "Terraform Deploy"
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: ${{ env.tf_version }}
          tf_actions_subcommand: 'apply'
          tf_actions_working_dir: ${{ env.tf_working_dir }}
        env:
          GITHUB_TOKEN: ${{ secrets.AZURE_CREDENTIALS }}
 
      - name: "Terraform Destroy"
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: ${{ env.tf_version }}
          tf_actions_subcommand: 'destroy'
          tf_actions_working_dir: ${{ env.tf_working_dir }}
        env:
          GITHUB_TOKEN: ${{ secrets.AZURE_CREDENTIALS }}

執行 workflows run

由於我們在 "terraform.yaml" 中指定指定工作分支 “remote_stats”,當 “remote” 分支發生 “push” 或者 “pull_request” 操作就會觸發 GitHub Actions 的 workflows 的執行。所以我們直接推送當前已編輯好的 "terraform.yaml" 檔案到 “remote_stats” 分支,並在 GitHub 上檢視 workflows 執行結果。

如果需要進一步瞭解每個步驟都執行了那些操作,可以選擇當前 workflow runs
image.png

檢視每個步驟並其輸出內容
image.png

檢視 Terraform 執行部署計劃內容
image.png

如需參考詳細輸出資訊,複製以下連結到瀏覽器檢視https://github.com/yunqian44/...

總結

本期實驗,我們學習如何使用 GitHub Actions 自動化的方式實現 Terraform Code 的語法校驗、生成部署計劃,執行部署計劃,銷燬部署計劃。也為我們在選擇自動化部署 Azure 基礎設施即程式碼的解決方案上又增加了新的方案。

GitHub Action 工作流程中設定 Secrets:
https://github.com/Azure/acti...

Azure服務主體:
https://www.cnblogs.com/Allen...

GitHub:
https://github.com/yunqian44/...


掃碼關注公眾號,獲到更多技術知識點

相關文章