Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Part 3 Automating and Planning Azure Resources with Terraform and GitHub Actions

GitHub Actions is a CI/CD tool that automates tasks and workflows within your repository. It lets you to create custom workflows, trigger actions, and keep sensitive information securely. Common use cases include automating testing, deployment, and code quality checks. You can also use GitHub Actions to automate Azure Terraform deployments, enabling consistent and repeatable infrastructure provisioning. By integrating Azure Terraform with GitHub Actions, you can streamline cloud infrastructure management and simplify DevOps workflows.

Configuring GitHub Actions: A Step-by-Step Guide

In this blog article, I will explore into the world of GitHub Actions, a powerful tool for automating workflows and streamlining development procedures. Before starting, make sure to check out my earlier articles, where I set up and configured a GitHub Repository and branches. This foundation is crucial and important for understanding the concepts I'll explore further.

Check this Series of Articles:
Part 1: Create GitHub repository and branches using Terraform
Part 2 Terraform modules using a github.com repository as a source
Part 3 Automating and Planning Azure Resources with Terraform and GitHub Actions
Part 4 GitHub Actions deploy azure resources with Terraform backend
Part 4.1 GitHub Actions deploy azure resources with PowerShell
Part 4.2 GitHub Actions manage Microsoft Azure Cloud with az CLI

What to Expect:

In this article, I will cover the fundamentals of GitHub Actions, covering:

  • Utilizing actions and secrets
  • Creating a workflow file
  • Automating Azure Terraform resources deployments
  • Defining jobs and steps

Prerequisites:

  • Rudimentary understanding of GitHub workflows and YAML syntax
  • A GitHub Repository with configured branches (main and dev)

By the finish of this guide, you'll be prepared with the information to automate your workflows, make simpler development procedures, and take your DevOps game to the next level. Let's get started!

Once GitHub Repository is setup, navigate to Settings > Secrets and Variables > Actions, and click New repository secret to add the following four secrets (Service Principal, Subscription and Tenant ID): 

  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_SUBSCRIPTION_ID
  • AZURE_TENANT_ID

Enter their respective values for authentication.

Terraform Github Actions Azure cloud resources management automation actions secrets and variables git codespace .gihub token workflows yml terraform yaml.png

For more on other authentication to Azure check below official guide:
https://github.com/azure/login#configure-a-service-principal-with-a-federated-credential-to-use-oidc-based-authentication
https://github.com/Azure/login?tab=readme-ov-file#login-with-a-service-principal-secret

After adding Azure credentials information, your can view of Repository Secrets, how it will look like below screenshot. To find the details of you infrastructure subscription, tenant and credentials for Azure cloud using PowerShell script check this blog: Create storage account and Service Principal using PowerShell for Terraform Azure Backend.

Terraform hashicorp plan azure resource managment with github actions AZURE_CLIENT_ID CLIENT_SECRET SUBSCRIPTION_ID TENANT_ID Secrets and Variables Environment variables branches github repository collaborators deploy keys github.com.png

 

Download complete project on github.com or it is also available to download complete project Terraform_GitHub_Actions_Azure.zip here.

By storing below workflow file terraform.yml inside .github/workflows folder, As soon you push files to GitHub Repository, GitHub Actions will automatically trigger the defined tasks on push events to the main branch, simplifying your infrastructure deployment process. Just for note I will only run Terraform Plan.

#File and Folder Location .github\workflows\terraform.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Name of the action that will trigger
name: Terraform

# On push event occur
on: push

# Environment variable to get more detailed log output
# Environment variable to controls Terraform's input prompts: true enables prompting, false disables prompting and relies on defaults or automation.
env:
  TF_LOG: INFO
  TF_INPUT: false

# Jobs section  
jobs:
  terraform:
    name: Terraform
    runs-on: ubuntu-latest # OS where job will trigger

    #Use the bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest or windows-latest
    #Setting default bash shell
    defaults:
      run:
        shell: bash

    steps:
    # Checkout the repository to the GitHub Actions runner
    - name: Checkout
      uses: actions/checkout@v3

    # Install the preferred version of terraform CLI
    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v2
      with:
          terraform_version: 1.9.2 # specify your Terraform version here

    # - name: Login to Azure
    #   uses: azure/login@v2
    #   with:
    #     client-id: ${{ secrets.AZURE_CLIENT_ID }}
    #     client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
    #     tenant-id: ${{ secrets.AZURE_TENANT_ID }}
    #     subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

    # Initialize a new or existing terraform working directory 
    - name: Terraform Init
      id: init
      run: terraform init

    # Run terraform fmt for push 
    - name: Terraform Format
      id: fmt
      run: terraform fmt -check
      if: (success() || failure())
    # Run a terraform validate
    # Run even if formatting fails
    - name: Terraform Validate
      id: validate
      if: (success() || failure())
      run: terraform validate

    # Run terraform plan for push 
    - name: Terraform Plan
      id: plan
      run: terraform plan
      env:
        ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
        ARM_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
        ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}

In the above code yellow highlighted area, if terraform code is not formatted, It will check condition and will error out workflow in Actions. It is similar to pre-commit, it will ask to format the code and upload to Git.

Below is the terraform configuration main.tf file, which I will store on GitHub repository with the .github folder. This Terraform configuration file creates a new subnet resource on existing Azure Virtual Network.

provider "azurerm" {
  features {}
}
##################
variable "subnet" {
  type = object({
    name                 = string
    resource_group_name  = string
    virtual_network_name = string
    address_prefixes     = list(string)
  })
  default = {
    name                 = "subnet1"
    resource_group_name  = "dev"
    virtual_network_name = "dev-vnet"
    address_prefixes     = ["10.0.1.0/24"]
  }
}
##################
resource "azurerm_subnet" "subnet" {
  name          = var.subnet.name
  resource_group_name  = var.subnet.resource_group_name
  virtual_network_name = var.subnet.virtual_network_name
  address_prefixes     = var.subnet.address_prefixes
}
##################
output "subnet_id" {
  value = resource.azurerm_subnet.subnet.id
}

Download complete project on github.com or it is also available to download complete project Terraform_GitHub_Actions_Azure.zip here.

Here are the all the git command to setup and push files to GitHub repository.

Terraform GitHub Actions azure cloud resource management configurations git init initial branch main git add . commit -m first Commit git remote add https git fetch branch upstream push origin main.png

$env:GITHUB_TOKEN = 'ghp_pqsawobVFd3gp2iJ'
git init --initial-branch=main
git add .
git commit -m "First Commit"
git remote add origin https://github.com/janviudapi/vcloud-lab.com.git
git fetch
git branch --set-upstream-to="origin/main" main
git push origin --force

Whenever you make changes to any of file in the directory. You can push the changes to GitHub with below one liner command.

git add . ; git commit -m "Testing Credentials" ; git push origin --force

As soon as files are pushed on GitHub repository and main branch navigate to Actions tab, you can see it trigged the workflow automatically.

Terraform Github Actions pull request pr security insights settings github azure cloud push workflows auto trigger configuration devops configuration ci cd hashicorp using free testing.png

Inside the workflow on push, check and verify all the task executed by this configuration. In my case there is no error and it succeeded successfully.

Terraform Github Actions Azure cloud code pull requests actions security insights github repository branch settings terraform init format  post checkout complete job Devops ci cd.png

Clicking on any of the task you can dig down for more details or troubleshooting.

Terraform plan azure resource managment subnet configuration registry.terraform azurerm devops automation coding configuration.png

Useful Articles
Terraform using for loop in attribute value without for_each
Terraform variable multiple validation advanced blocks example
Terraform variable type list with for_each for loop examples
Terraform convert single string to list or set
Terraform workspaces with example
Terraform map of object for loop with if condition example
Terraform for_each for loop list of object without count example
Hashicorp Terraform map and object inside module and variable example
Terraform one module deploy null or multiple resources based on input
Terraform A reference to a resource type must be followed by at least one attribute access, specifying the resource name
Terraform fore_each for loop filter with if condition example
Terraform remote-exec provisioner with ssh connection in null_resource
Terraform count vs for_each for examples with map of objects
Terraform one module deploy null or multiple resources based on input (nested for loop) Example of Terraform functions flatten() and coalesce()
Terraform Azure Create Private Endpoint to existing Storage Account with Custom Private DNS zone record link
Creating a Private Endpoint for Azure Storage Account with required sub services using Terraform Example Terraform functions of lookup() and lower()
Using element function with count meta argument example Terraform Azure subnets Example Terraform functions of element()count() and sum()
Terraform create Azure Virtual Network subnets from map of object and show name in the header Header name change in the output
Creating a Private Endpoint for Azure Storage Account with Terraform example 2 Example of for_each with toset() function
Creating a Private Endpoint for Azure Storage Account with Terraform example 3

Go Back

Comment

Blog Search

Page Views

12086078

Follow me on Blogarama