I have been working with a customer who wants to get some usage data from Azure around virtual networks and available IP addresses. Specifically how many IP addresses are available in a subnet within an Azure virtual network. This is a simple enough script and I can use the Get-AzureRMVirtualNetworkUsageList cmdlet to get the exact information. However the customer's environment has some challenges.
- It has to be non-interactive (eventually this script will run as part of their build process)
- They are using Jenkins to run the script
- Jenkins is on a Linux box and I can't add a Windows slave
- Azure CLI is installed but won't get me the information I need
This post explains how I overcame these hurdles using the new cross platform capability of PowerShell Core.
Non-Interactive Azure Login
To be able to authenticate with Azure I need to use a token - this is so I don't have to run Login-AzureRMAccount and the process can work unattended. For this I have to create a new application in Azure so I can authenticate.
Fill in some details about the application and click Create.
I need to generate a client secret for use with my login - select the application and click on Settings -> Keys.
Enter a description for the key and click Save. A secret will be generated - you must copy and save it somewhere because when you close the blade it will be unaccessible again. This secret will be used in the script run by Jenkins.
Now that the application is created we can update the script with the application ID.
Script to calculate available IP addresses.
The script I use is located at https://github.com/anwather/SubnetCount and performs the following steps.
- Logs in to Azure using the application created above
- For each virtual network it iterates through the subnets and calculates how many IP addresses are available.
Very simple - but it makes for a quick example.
Provision and Configure Jenkins
I can create a Jenkins instance using the Azure marketplace image which will do all the work of setting up a virtual machine and installing the product for me.
In Azure I search for Jenkins in the marketplace.
Select it and click Create.
Step through the wizard and complete the details required - Azure will complain if you use any reserved names. You can also select instance size. I have screenshots below of the changes I made - for anything not listed I just used the default settings.
When complete click Create - the deployment will begin and the portal will notify you when it is complete.
Configuring Jenkins and PowerShell Core
To configure Jenkins you can follow the steps at https://docs.microsoft.com/en-us/azure/jenkins/install-jenkins-solution-template. First we have to connect to the Jenkins instance running in Azure by browsing to its URL. In the virtual machine you have created it will be listed in the overview page under DNS Name.
Browse to this and when the Jenkins page appears click Log in.
Because we don't want anyone to be able to log in to your instance we disable the public IP on it - you have to use ssl to connect and forward the port to your local machine. I use the Bash shell on Windows 10 and just follow the instructions replacing the username with my username. You will have to enter Yes to accept the host thumbprint and also enter your password for the Jenkins instance. When complete you should be presented with a login as below.
Let's install PowerShell Core on the Jenkins box. I follow the instructions at https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md#ubuntu-1604 and simply copy and paste the commands in the section below into the command prompt.
The full output from this will look similar to the image below. At the bottom of the image is where I launch PowerShell (pwsh)
Now I can just install the modules for AzureRM Networking,Profile and Resources by running the command below.
Install-Module AzureRM.Profile.NetCore,AzureRM.Network.NetCore -Force
Don't close the terminal window as we can now configure the job in Jenkins.
Creating and Running the Jenkins Build
Open the web browser to http://localhost:8080. The Jenkins page should appear and you can click on Login. You can use the username "admin" - the initial password can be retrieved by running sudo cat /var/lib/jenkins/secrets/initialAdminPassword at the terminal prompt. Once you have logged in click New Item and select Freestyle Project. Click ok.
In the section marked Source Code Management select git and enter the repository information as in the image.
In the section Build click Add Build Step -> Execute Shell. Enter the command as below replacing the sections with the information from your Azure Service Principal you created earlier.
pwsh -File "IPUsage.ps1" -TenantID <<your tentant ID>> -ClientID <<your client ID>> -ClientSecret <<your client secret>>
Click on Save and then Click Build Now - you will see the build start...
Click on the number of the build and select console output. You should see the network details from your Azure subscription.
So this is just an example that when faced with the possibility of writing a script in Azure CLI or Shell, now we have the option of using PowerShell Core instead.