Post

Building a nested virtual machine in Azure: Part 3

Series Table of contents:

We continue our journey of building a nested virtual machine in Azure. In the following article, I will discuss the following aspect:

  • Create the GitHub Workflows

What are GitHub Workflows?

A workflow is a configurable automated process that will run one or more jobs. Workflows are defined by a YAML file checked in to your repository and will run when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule.

Workflows are defined in the .github/workflows directory in a repository, and a repository can have multiple workflows, each of which can perform a different set of tasks.

If you want to learn more check out the official GitHub documentation

We will create the following workflows:

  • A workflow that triggers if a pull request is created.
  • A workflow that triggers the Terraform Azure Storage Account.

Clone the GitHub repository

Your local machine must have GIT installed.

To generate files within our recently created GitHub repository, it is necessary to first clone the repository from GitHub.

To clone the repository to your local machine, select the “Code” button within your repository, switch to the local tab and copy the HTTPS URL.

GitHub Clone repository

Inside of Visual Studio Code press CTRL + SHIFT + P (or F1, or CMD + SHIFT + P) to open the command palette and select “GIT: Clone”.

GitHub Clone repository 2

Paste the GitHub URL and press the ENTER key, select a local folder and click on “Select as Repository Destination”. Select “Open” to reload Visual Studio Code with the cloned repository.

If you're logged into GitHub within Visual Studio Code, you can also utilize the "Clone from GitHub" option. You can also authenticate to GitHub from within Visual Studio Code.

Set up the GitHub workflows

create the .github/workflows folder structure

GitHub create folder structure

Deploy Terraform Storage Account workflow (deploytfstorageaccount.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
name: CreateTFStorageAccount

on:
  workflow_dispatch:

permissions:
  id-token: write
  issues: write
  pull-requests: write
  contents: read

jobs:
  deploytfstorageaccount:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Azure Login
        uses: Azure/login@v1.4.6
        with:
          client-id: $
          tenant-id: $
          subscription-id: $
          enable-AzPSSession: true

      - name: Add TF Storage Account
        uses: Azure/powershell@v1
        with:
          inlineScript: |
            $Param = @{
              Name     = $Env:RESOURCE_GROUP_NAME
              Location = $Env:STORAGE_ACCOUNT_LOCATION
            }
            New-AzResourceGroup @Param

            $Param = @{
              ResourceGroupName = $Env:RESOURCE_GROUP_NAME
              Name              = $Env:STORAGE_ACCOUNT_NAME
              Location          = $Env:STORAGE_ACCOUNT_LOCATION
              SkuName           = $Env:STORAGE_ACCOUNT_SKU
            }
            $StorageAccount = New-AzStorageAccount @Param

            $Param = @{
              Name    = $Env:STORAGE_CONTAINER_NAME
              Context = $StorageAccount.Context
            }
            New-AzStorageContainer @Param
          azPSVersion: latest
        env:
          RESOURCE_GROUP_NAME: $
          STORAGE_ACCOUNT_NAME: $
          STORAGE_CONTAINER_NAME: $
          STORAGE_ACCOUNT_LOCATION: West Europe
          STORAGE_ACCOUNT_SKU: Standard_LRS

Pull Request workflow (pullrequest.yml)

The workflow might be adjusted based on your Pull Request. The Terraform steps will be featured in the upcoming blog post.
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
name: Pull Request

on:
  pull_request:
    branches:
      - main

env:
  TF_LOG: INFO

permissions:
  id-token: write
  issues: write
  pull-requests: write
  contents: read
jobs:
  pr-infra-check:
    runs-on: ubuntu-latest
    steps:
      # Checkout the repository to the GitHub Actions runner
      - name: Checkout
        uses: actions/checkout@v2

      # Install the latest version of Terraform CLI
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1

      # Log into Azure with OIDC integration
      - name: "Az CLI login"
        uses: azure/login@v1
        with:
          client-id: $
          tenant-id: $
          subscription-id: $

      # Run az commands to confirm sub access
      - name: "Run az commands"
        run: |
          az account show

      # Run Terraform init
      #- name: Terraform Init
      #  id: init
      #  env:
      #    STORAGE_ACCOUNT: $
      #    CONTAINER_NAME: $
      #    RESOURCE_GROUP_NAME: $
      #    ARM_CLIENT_ID: $
      #    ARM_SUBSCRIPTION_ID: $
      #    ARM_TENANT_ID: $
      #  run: terraform init -backend-config="storage_account_name=$STORAGE_ACCOUNT" -backend-config="container_name=$CONTAINER_NAME" -backend-config="resource_group_name=$RESOURCE_GROUP_NAME"
      #  working-directory: <your working directory inside of the GitHub repository>

      # Run a Terraform validate
      #- name: Terraform validate
      #  id: validate
      #  if: success() || failure()
      #  env:
      #    ARM_CLIENT_ID: $
      #    ARM_SUBSCRIPTION_ID: $
      #    ARM_TENANT_ID: $
      #  run: terraform validate -no-color
      #  working-directory: <your working directory inside of the GitHub repository>

      # Run a Terraform plan
      #- name: Terraform plan
      #  id: plan
      #  env:
      #    ARM_CLIENT_ID: $
      #    ARM_SUBSCRIPTION_ID: $
      #    ARM_TENANT_ID: $
      #  run: terraform plan -no-color
      #  working-directory: <your working directory inside of the GitHub repository>

      # Add a comment to pull requests with plan results
      #- name: Add Plan Comment
      #  id: comment
      #  uses: actions/github-script@v3
      #  env:
      #    PLAN: "terraform\n$"
      #  with:
      #    github-token: $
      #    script: |
      #      const output = `#### Terraform Format and Style 🖌\`$\`
      #      #### Terraform Initialization ⚙️\`$\`
      #      #### Terraform Validation 🤖$
      #      #### Terraform Plan 📖\`$\`

      #      <details><summary>Show Plan</summary>

      #      \`\`\`${process.env.PLAN}\`\`\`

      #      </details>

      #      *Pusher: @$, Action: \`$\`, Working Directory: \`$\`, Workflow: \`$\`*`;

      #      github.issues.createComment({
      #        issue_number: context.issue.number,
      #        owner: context.repo.owner,
      #        repo: context.repo.repo,
      #        body: output
      #      })

Generate the files and insert the provided code into them.

End result:

Create GitHub Workflow files

Commit them to the repository.

Commit GitHub Workflow files

Create the Terraform Storage Account

Navigate to your GitHub repository inside of a browser and select “Actions”.

GitHub Actions

Select “CreateTFStorageAccount”, select “Run workflow” and select “Run workflow”

CreateTFStorageAccount

CreateTFStorageAccount 1

CreateTFStorageAccount 2

CreateTFStorageAccount 3

Part 3 wraps up here. In the upcoming blog post, we’ll delve into an exploration of Terraform and delve into the mechanics of the Pull Request model.

This post is licensed under CC BY 4.0 by the author.