Hands up if you are used to deploy servers either by unpacking them from a box or using a graphical user interface (GUI)? Yip, that’s me and it's where I’ve built my career. However, over the last few years I’ve been getting more and more used to deploying servers and their supporting resources via code. Either using something like PowerShell or Azure CLI, or sometimes a combination of both.
I’ve also taught myself how to use tools such as Visual Studio Code, Git, GitHub or even Azure DevOps to get the task done. It’s not been an easy journey but what it has been is fun and a challenge.
At the end of 2019 GitHub announced GitHub Actions, a new way to automate deployment of code from GitHub repositories. I’ve been watching with interest as my developer focused colleagues and friends dig into the new service and show examples of it being used and have decided to take a look at it myself and see what it can do for the IT Pro community, as I’m a firm believer that these types of tools can offer IT Pros great opportunities as well.
There is some new terminology that comes with GitHub Actions, so let’s define those before we dig in.
Keeping it simple, I want my GitHub Action to build a virtual machine (VM) within Azure. Keeping it really simple I want it to build the VM and it’s associated supporting technology (disk, network interface, virtual network, storage account, etc) within the same resource group. This isn’t exactly best practice but is an easy example to start with and one that is well known/documented.
I can use four blocks of Azure CLI code to build the VM within Azure. The first block of code helps log into my Azure subscription using an Azure Service Principal and perform the necessary steps to create the VM.
#region Login
# This logs into Azure with a Service Principal Account
#
Write-Output "Logging in to Azure with a service principal..."
az login `
--service-principal `
--username $servicePrincipal `
--password $servicePrincipalSecret `
--tenant $servicePrincipalTenantId
Write-Output "Done"
Write-Output ""
#endregion
The next section selects the correct subscription, just to be sure my resources go to the right place:
#region Subscription
#This sets the subscription the resources will be created in
Write-Output "Setting default azure subscription..."
az account set `
--subscription $azureSubscriptionName
Write-Output "Done"
Write-Output ""
#endregion
The third section creates the resource group for my VM to live in:
#region Create Resource Group
# This creates the resource group used to house the VM
Write-Output "Creating resource group $resourceGroupName in region $resourceGroupNameRegion..."
az group create `
--name $resourceGroupName `
--location $resourceGroupNameRegion
Write-Output "Done creating resource group"
Write-Output ""
#endregion
And the fourth section creates the VM within that resource group:
#region Create VM
# Create a VM in the resource group
Write-Output "Creating VM..."
try {
az vm create `
--resource-group $resourceGroupName `
--name $serverName `
--image win2016datacenter `
--admin-username $adminLogin `
--admin-password $adminPassword
}
catch {
Write-Output "VM already exists"
}
Write-Output "Done creating VM"
Write-Output ""
#endregion
>
The code isn’t complex and is a well-known example you can see in a lot of Documentation and tutorials. Within my script I’ve used various parameters to allow me to store the information securely or pass it in from my workflow file. You can find my full PowerShell script here.
To kick off the VM build we construct a Workflow file. This is in the form of YAML. You can call your workflow file anything you want as long as it ends with. yml or .yaml as the extension type. It also needs to be stored within a specific directory within your GitHub repository - .github/workflows
Your workflow file is split up into several sections, let’s look at each of them individually:
Metadata
We start off with some naming the workflow:
name: GitHub for IT Pro CI/CD Pipeline
Environment variables:
Env:
OUTPUT_PATH: ${{ github.workspace }}
Triggers
We then instruct how the action will be triggered; I have set my action to start whenever something is pushed to the repository:
on: [push]
Jobs
Now we start to declare the jobs that our workflow will do, we have to start by declaring what platform our Workflow will run on (Linux, MacOS or Windows).
jobs:
# Deploy VM in Azure
DeployVM:
runs-on: windows-latest
Steps
Now we can start with the steps within the workflow. The first step I’ve instructed my workflow to do a checkout. This takes the files/code from my repository and puts it into $github.workspace for my workflow to access it.
steps:
# checkout code from repo
- name: checkout repo
uses: actions/checkout
The next step we have is one where we tell the workflow to look for the PowerShell script that helps to build the VM:
- name: look for ps1 file
run: |
ls '${{ env.OUTPUT_PATH }}\IaC\AzCLI'
And the last step in our workflow is to deploy and provision the VM:
- name: provision virtual machine in azure
env:
RESOURCE_GROUP: rg-githubitpro
RESOURCE_GROUP_REGION: southcentralus
SERVER_NAME: gihtubactions
ADMIN_LOGIN: sarah
run: >
powershell -command "& '${{ env.OUTPUT_PATH }}\IaC\AzCLI\vmcreation.ps1'"
-servicePrincipal ${{ secrets.SERVICE_PRINCIPAL_APPID }}
-servicePrincipalSecret ${{ secrets.SERVICE_PRINCIPAL_SECRET }}
-servicePrincipalTenantId ${{ secrets.SERVICE_PRINCIPAL_TENANTID }}
-azureSubscriptionName ${{ secrets.AZURE_SUBSCRIPTION_ID }}
-resourceGroupName %RESOURCE_GROUP%
-resourceGroupNameRegion %RESOURCE_GROUP_REGION%
-serverName %SERVER_NAME%
-adminLogin %ADMIN_LOGIN%
-adminPassword ${{ secrets.ADMIN_PASSWORD }}
Now there is a lot to that step so let’s break down what we are doing even further:
- name: provision virtual machine in azure
env:
RESOURCE_GROUP: rg-githubitpro
RESOURCE_GROUP_REGION: southcentralus
SERVER_NAME: gihtubactions
ADMIN_LOGIN: sarah
This first part is declaring some environment variables, here I am setting my Azure Resource Group name, the region I want the resource group to be deployed in, the name of my virtual machine (server) and the name of the admin login account that will be created for that VM.
The second stage of the step is telling my workflow to call my PowerShell script and pass in the following variables from the workflow and GitHub Secrets store. To allow GitHub Actions to deploy resources within my Azure Subscription I have created an Azure Service Principal. If you’ve never worked within them before I wrote an article covering how to create and work with them here.
run: >
powershell -command "& '${{ env.OUTPUT_PATH }}\IaC\AzCLI\vmcreation.ps1'"
-servicePrincipal ${{ secrets.SERVICE_PRINCIPAL_APPID }}
-servicePrincipalSecret ${{ secrets.SERVICE_PRINCIPAL_SECRET }}
-servicePrincipalTenantId ${{ secrets.SERVICE_PRINCIPAL_TENANTID }}
-azureSubscriptionName ${{ secrets.AZURE_SUBSCRIPTION_ID }}
-resourceGroupName %RESOURCE_GROUP%
-resourceGroupNameRegion %RESOURCE_GROUP_REGION%
-serverName %SERVER_NAME%
-adminLogin %ADMIN_LOGIN%
-adminPassword ${{ secrets.ADMIN_PASSWORD }}
For a full copy of this workflow file, you can find it here.
When the Action is running you can monitor its progress. When you navigate to your repository on the GitHub website you will see a tab called Actions, click into that will take you into the Workflow section. You can create new workflows, edit workflows and monitor the progress of the workflows running.
And once the workflow has completed you can check in your Azure subscription and hopefully see the resource created:
My example workflow is a very basic one and the resource that I am deploying is a very basic one, however for me it was a great starting point to learn GitHub Actions. I’ve seen my colleagues use it for much more complex deployments and workflows, for example Aaron Powell is using it to deploy his blog.
The repository I created to test out this deployment is a public one and the output of my workflow is available for anyone logged in or not to GitHub to view, which displays certain information that could be considered as sensitive such as my Azure Subscription ID and more importantly the Public IP address of my VM, which gives people with bad intentions an easy attack surface. So, if you are testing GitHub Actions please be aware of this and vigilant on what you deploy in Azure and how it is secured.
I've recorded a video of me walking through the code and each step, this video can be found here:
I’d love to hear how other IT Pros are using GitHub Actions to deploy infrastructure, so please do reach out and share your stories!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.