Menu

Virtual Geek

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

Part 4.1 GitHub Actions deploy azure resources with PowerShell

After successfully configuring and setting up Azure and Terraform in GitHub Actions, I embarked on a Proof of Concept (POC) to automate PowerShell scripts (Azure az module) using GitHub Actions. I meticulously automated all the job steps using PowerShell, with a primary focus on utilizing credentials to establish a secure connection to the Microsoft Azure cloud and perform the necessary configuration and setup.

For authentication to Azure, I have securely added credentials in GitHub Actions secrets and variables, ensuring seamless and secure access to Azure resources. 

To authenticate to Azure using the PowerShell Az module, I'm utilizing Azure Service Principal information. I've stored the sensitive credentials, including AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET, as secrets in GitHub Actions. By inputting these values into the secrets, I can securely leverage the same credentials to authenticate and perform Azure management tasks using PowerShell scripts.

Complete series on DevOps - GitHub Actions
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

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 this Azure management with PowerShell and Github Actions.zip here or it is also available on github.com.

When code is pushed to GitHub, the Actions workflow is triggered, initiating the automation process. The workflow executes the specified PowerShell commands or scripts, automating the environment as configured. This seamless integration enables efficient and consistent management of Azure resources, streamlining tasks and workflows.

# Push the code to github
git add . ; git commit -m "PowerShell Credentials" ; git push origin --force

PowerShell git push commit add configuration github actions secrets and variable setup credentials subscription id tenant id client id secret secure login devops ci cd source control versioning.png

Below is my complete GitHub Actions workflow YAML file. In the PowerShell task's inline script, I've created variables from secrets using the ${{ secrets.<id> }} syntax. These variables correspond to my Azure Service Principal ID, Secret and subscription/Tenant IDs.

I utilize these variables to create credentials PowerShell object, which authenticate my connection to Azure, connect it and enables the execution of subsequent commands. Additionally, I have the option to run or execute a PowerShell (.ps1) file, providing flexibility in my automation workflow.

# Name of the action that will trigger
name: PowerShell

# Trigger on push event to the repository
on:
  push:

# Define jobs to run
jobs:
  powershell:
    name: Run PowerShell Workflow
    runs-on: ubuntu-latest  # Specify the OS for the runner

    # Use bash as the default shell for the steps
    defaults:
      run:
        shell: bash

    # List of steps to execute
    steps:
      # Step 1: Checkout the repository to the runner
      - name: Checkout Repository
        uses: actions/checkout@v3

      # Step 3: Run PowerShell script with Azure commands
      - name: Run Azure PowerShell Script
        uses: azure/powershell@v1
        with:
          inlineScript: |
            # Authenticate using service principal credentials
            $clientId = "${{ secrets.AZURE_CLIENT_ID }}"
            $tenantId = "${{ secrets.AZURE_TENANT_ID }}"
            $clientSecret = "${{ secrets.AZURE_CLIENT_SECRET }}"
            $subscriptionId = "${{ secrets.AZURE_SUBSCRIPTION_ID }}"

            # Log in using Service Principal credentials
            Connect-AzAccount -ServicePrincipal -TenantId $tenantId -Credential (New-Object System.Management.Automation.PSCredential($clientId, (ConvertTo-SecureString $clientSecret -AsPlainText -Force))) -SubscriptionId $subscriptionId
            # Example: List resource groups in Azure
            Get-AzResourceGroup -Name Dev
          # Specify the PowerShell Core version to use
          azPSVersion: "latest"

      # Step 4: (Optional) Run a PowerShell script file instead of inline script
      # - name: Run PowerShell Script from File
      #   uses: azure/powershell@v1
      #   with:
      #     scriptPath: ./scripts/deploy.ps1  # Path to the PowerShell script
      #     azPSVersion: "latest"

This auto triggered and successfully completed workflow after pushing code to GitHub.

PowerShell GitHub Actions configuration setup azure managment cloud devops ci cd configuration administration automation setup terraform secrets key vault variable sensetive security.png

Here is the screenshot of the GitHub Actions workflow successful output.

PowerShell Workflow Azure github actions configuration connect-azaccount get-azresourcegroup devops continous delivery integration ci cd automation sre site reliability engineer setup management.png

Below is the complete text output from GitHub Action of executed workflow PowerShell Job.

 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
Run azure/powershell@v1
  with:
    inlineScript: # Authenticate using service principal credentials
  $clientId = "***"
  $tenantId = "***"
  $clientSecret = "***"
  $subscriptionId = "***"
  
  # Log in using Service Principal credentials
  Connect-AzAccount -ServicePrincipal -TenantId $tenantId -Credential (New-Object System.Management.Automation.PSCredential($clientId, (ConvertTo-SecureString $clientSecret -AsPlainText -Force))) -SubscriptionId $subscriptionId
  
  # Example: List resource groups in Azure
  Get-AzResourceGroup -Name Dev
  
    azPSVersion: latest
    errorActionPreference: Stop
    failOnStandardError: false
    githubToken: ***
Validating inputs
Module Az latest installed from hostedAgentFolder
Initializing Az Module
/usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -Command Test-Path (Join-Path /usr/share az_*)
/usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -Command $env:PSModulePath
/home/runner/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/powershell/7/Modules
/usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -Command try {
            $ErrorActionPreference = "Stop"
            $WarningPreference = "SilentlyContinue"
            $output = @{}
            $data = Get-Module -Name Az -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1
            $output['AzVersion'] = $data.Version.ToString()
            $output['Success'] = "true"
        }
        catch {
            $output['Error'] = $_.exception.Message
        }
        return ConvertTo-Json $output
True
{
  "AzVersion": "12.1.0",
  "Success": "true"
}
/usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -Command $env:PSModulePath
/usr/share:/home/runner/.local/share/powershell/Modules:/usr/local/share/powershell/Modules:/opt/microsoft/powershell/7/Modules
Initializing Az Module Complete
Running Az PowerShell Script
/usr/bin/pwsh -NoLogo -NoProfile -NonInteractive -Command /home/runner/work/_temp/0cc34a53-1b9a-48d0-a951-4d1686df31c5.ps1
WARNING: The provided service principal secret or certifcate password will be included in the 'keystore.cache' file found in the user profile ( /home/runner/.Azure ). Please ensure that this directory has appropriate protections.
Subscription name        Tenant
-----------------        ------
Sponsership-by-Microsoft ***
ResourceGroupName : dev
Location          : eastus
ProvisioningState : Succeeded
Tags              : {}
TagsTable         : 
ResourceId        : /subscriptions/***/resourc
                    eGroups/dev
ManagedBy         : 
WARNING: You're using Az version 12.1.0. The latest version of Az is 12.3.0. Upgrade your Az modules using the following commands:
  Update-PSResource Az -WhatIf    -- Simulate updating your Az modules.
  Update-PSResource Az            -- Update your Az modules.
Script execution Complete

Useful Articles
Terraform clone virtual machine template in VMware vSphere vCenter from CSV file
Terraform error retrieving storage account failure responding to request StatusCode 404 StorageAccountNotFound The storage account was not found
Terraform testing local variables and output csv file without resource Part 1
Terraform testing variable map object values without resource configuration part 2
Terraform foreach module output to show only required results
Terraform deploy create A Private DNS Record in Microsoft Azure from list of objects
Terraform clone virtual machine template in VMware vSphere vCenter Dynamic Content Part 2
Terraform variable precedence and priority
Terraform filter map and list object with if condition in for_each loop examples
Terraform Azure function app with private endpoint and storage account
Terraform module Azure function app with private endpoint and storage account
Terraform passing different credentials to different subscriptions with provider alias
Terraform Azure provider alias passing credentials and configuration in module resources
Terraform Azure provider passing multiple alias environment and credentials in child module
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
Terraform using for loop in attribute value without for_each

Go Back

Comment

Blog Search

Page Views

12162468

Follow me on Blogarama