1
头图

This issue of Microsoft MVP Lab researcher - Gan Gan, will share with you how to use GitHub Actions to deploy Terraform Code to Azure in an automated way through code samples.

Gan Gan, Microsoft's most valuable expert, Microsoft Azure direction, currently engaged in the back-end development of .NET technology stack products. Passionate about learning Microsoft Azure related technologies and sharing their own learning experience. At the same time, it is improving its own Azure cloud infrastructure solution design capabilities and Azure cloud technology training capabilities

Analysis of ideas

Deploying Azure infrastructure resources with Terraform Code is particularly popular, and I have written an article on Azure infrastructure resources described in Automating Terraform Code Deployment with Azure DevOps. But some people may be relatively new to Azure DevOps, plus the paid jobs of Parallel jobs for Azure DevOps. So as an alternative, today I will share with you how to deploy Terraform Code using GitHub Actions.
image.png

Configure Azure Service Principal's credentials to GitHub secret repository

Terraform Code and Azure CLI will use Azure Service Principle to authenticate Azure. For the creation of Azure Service Principle, you can refer to Blog.
Blog:https://www.cnblogs.com/AllenMaster/p/13065643.html

Next you need to add the following confidential information
  1)AZURE_AD_CLIENT_ID
  2)AZURE_AD_CLIENT_SECRET
  3)AZURE_AD_TENANT_ID
  4)AZURE_SUBSCRIPTION_ID
  5)AZURE_CREDENTIALS

The contents of the AZURE_CREDENTIALS format are as follows:

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

Store the above information in GitHub Secrets of the corresponding name.
image.png

Configure yaml for workflows run

Create terraform.yaml in the root directory of the Terraform project and save it in the following directory
image.png

The contents of terraform.yaml are as follows


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

run workflows run

Since we specified the specified work branch "remote_stats" in "terraform.yaml", when a "push" or "pull_request" operation occurs in the "remote" branch, the workflows of GitHub Actions will be triggered to run. So we push the currently edited "terraform.yaml" file directly to the "remote_stats" branch, and check the workflows running results on GitHub.

If you need to know more about what each step performed, you can select the current workflow runs
image.png

View each step and its output
image.png

View Terraform Execution Deployment Plan Contents
image.png

For detailed output information, copy the following link to browser to view https://github.com/yunqian44/Terraform_Cnbate_Traffic_Manager/runs/4740814994?check_suite_focus=true

summary

In this experiment, we learn how to use GitHub Actions to automate the syntax verification of Terraform Code, generate deployment plans, execute deployment plans, and destroy deployment plans. It also adds a new option for us to choose solutions for automating the deployment of Azure infrastructure as code.

Set up Secrets in the GitHub Action workflow:
https://github.com/Azure/actions-workflow-samples/blob/master/assets/create-secrets-for-GitHub-workflows.md

Azure Service Principal:
https://www.cnblogs.com/AllenMaster/p/13065643.html

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


Scan the code and follow the official account to get more technical knowledge points


微软技术栈
423 声望996 粉丝

微软技术生态官方平台。予力众生,成就不凡!微软致力于用技术改变世界,助力企业实现数字化转型。