Skip to main content

Something completely different – PoshARM

I needed a project for my Xmas holiday and I needed something remotely work related. Thus the dubious PoshARM PowerShell module was born and brought to life during my Xmas holiday. Simply put it is a module that lets you build – for now – simple Azure Resource Manager (ARM) templates with PowerShell . 

The module can also import templates from a file or from the clipboard/string. Your partial template or ready made template can be exported as a PowerShell script. This blog post will walk you through how to use it and the features that is currently implemented. 



Update 08.02.2017:

The module is now published to the PowerShellGallery (https://www.powershellgallery.com/packages/posharm). It is still in beta version, however test coverage have increased and some bugs have been squashed during the testing. Also help is present, however somewhat lacking here and there.

Update 18.01.2017:

The module is now on GitHub. Here is the link to the repro (PoshARM on GitHub)



What is a ARM template?

It is a text file, or more correctly a JSON text file. Here is a sample template which is empty:

image

The ARM template is an input to the Azure Resource Manager which is responsible for deploying you resource definition (your ARM template) onto an Azure Subscription. There are multiple ways you can make or build your template:


  • Any pure text editor (Notepad, Notepad++)
  • Visual Studio
  • Visual Studio Code
  • PoshARM (this module)

To summarize an ARM template consists of these main building blocks:

  • Parameters
  • Variables
  • Resources
  • Outputs

In addition you should also have a metadata.json file associated with your template. You can find the complete Microsoft documentation of an ARM template on this link: Authoring ARM-templates


Why PoshARM?

Good question. In my experience this will probably not be the primary way of creating an ARM template for the professionals. For them is will probably be quicker to manually copy/paste and edit the template in an text editor or in Visual Studio. Trouble is when your template expands, it can get quite big. In addition I have yet to say hello to any IT-pro (with very few exceptions) that embrace and understand big JSON files, much less IT-pros that build their own ARM templates. If only a single person find it useful or any part of this module is useful, I will be happy.



Module status

This is a public alpha preview. There are bugs in the module and it is not feature complete in any way. Currently I have Pester coverage for most of the cmdlets, however the current ARM-template test file is just to create a simple VM in Azure and it contains 6 resources, some parameters and variables. As always, help is missing everywhere and this is the reason I have not published it to Powershell Gallery yet.

There are currently no cmdlet for working with the template outputs property. It is handled and imported if you use the Import-ARMtemplate cmdlet, however it will be missing if you export it.




ARM Variables

To interact with variables we have these cmdlets:

  • Get-ARMvariable
  • New-ARMvariable
  • Add-ARMvariable
  • Get-ARMvariableScript
  • Set-ARMvariable

Creating a new variable is straight forward and we can pipe the output to Add-ARMvariable to add it to the template:




Set-ARMvariable and Get-ARMvariable cmdlets implements a dynamic parameter for the Name of the variable. This makes it impossible to set or get the value of a variable if it does not exists:

image


ARM Parameters

A parameter have many more properties than a variable, however you need to specify a Name and the Type of the parameter. These are the cmdlets we have:


  • Get-ARMparameter
  • Get-ARMparameterScript
  • New-ARMparameter
  • Add-ARMparameter
  • Set-ARMparameter

Creating a parameter for adminUserName can be as simple as this:




As with the variable cmdlets, we have a dynamic parameter for the name both for Get-ARMparameter and Set-ARMparameter.



ARM Resources

This is where it gets rather complicated. The resources property of the ARM template, expects an array of resources which in turn can have nested resources, which again can have nested resources. As you would expect, we have a few cmdlets to work with resources as well:


  • Get-ARMresourceList
  • Update-ARMresourceList
  • Get-ARMresourceScript
  • New-ARMresource
  • Add-ARMresource

Get-ARMresourceList provides dynamic resource type parameter for New-ARMresource. The Update-ARMresourceList cmdlet is used to update the cached version of the resource providers that is available in Azure. Currently the cached resource list is saved in the module path (.\Data\AllResources.json), however it should probably be moved to AppData.

Creating a new resource is straight forward. Currently it does not support lookup of variables and parameters, however that feature could be added later. Here is an example that creates an new Storage Account on Azure:


The New-ARMresource cmdlet implements a Dynamic parameter named Type. The value for this parameter is generated by the Get-ARMresourceList command. 



ARM template metadata


Each template should have some metadata that help to identify the template. There is a Set-ARMmetadata cmdlet that will create the metadata.json file for you. Here is an example metadata.json file:




Importing existing ARM templates

On GitHub you can find loads of quick starter templates that you can modify and update. It would be pretty useless if this module did not let you import these templates and work with them. The Import-ARMtemplate will import an template from the clipboard/string or from a file on your computer. Here is how you can use it:



ARM template


For working with ARM templates, we have the following cmdlets:


  • Get-ARMtemplate
  • Get-ARMtemplateScript
  • New-ARMtemplate

The New-ARMtemplate cmdlet will create a new empty ARM template in the current Powershell session. Currently it will overwrite the current template if you have started creating one. This will change and will require you to specify the Force parameter if a template exists.

Get-ARMtemplate executed without any parameters will return the template which is stored in a module variable called $Script:Template. It also have 2 switch parameters:


  • Get-ARMtemplate –AsJSON
  • Get-ARMtempalte –AsHashTableString

The hashtable string version is easier on the eye compared to the JSON version, however that depends on your JSON experience level and your hashtable fondness level.



Helper functions

There are two helper functions available in the module. Both of them are used heavily in the Script cmdlets which we will talk about next.


ConvertTo-Hash

If you have worked with Powershell it should be pretty simple to understand what this cmdlet does. It converts an Inputobject to an hashtable, that is it actually outputs a ordered hashtable. It will chew through the Inputobject and create an ordered hashtable even for nested objects and arrays. Lets take it for a spin:


image



Out-HashString

Give this cmdlet an hashtable or an ordered hashtable an it will output the text version of it that you can paste into a Powershell host and execute. Let’s use the $fileObject hashtabel and see if we can get back the text representation of the object:

image

Yes, there it is with proper indention and everything.




Get-ARM*Script

You may have noticed that I have added a cmdlet for each property that have the Get-ARM*Script name syntax. The purpose of those cmdlets are to generate the Powershell script for each property in the template. Here is how you use it:

In the example we have created 2 variables, a parameter and a resource. These have been added to our template as we have moved along. Now we introduce the Get-ARMtemplateScript cmdlet which will give you the template as a script. Here are the commands we have executed:



Now we are going to run Get-ARMtemplateScript and see what we get back:

image

There we have it. We just created a ARM template with Powershell and converted the template back to a Powershell script. This also works with imported templates which enables you to copy snippets of code to create templates. The observant reader may spot the bug in the screenshot above. The SKU key is “System.Collections.Hashtable” which is not correct. Did I mention that it is not ready yet? Well it is not, but it is almost working.



Planned features

Depending on the reception of the module, I have planned some enhancements for the module:


  • Add help
  • Improve Pester coverage
  • Add cmdlets for creating outputs
  • Add support for template functions and keywords ([variables()], [parameters()], [concat()], [resourceId()] etc)
  • Template linking

Please contact me if you have other suggestions or ideas. I cannot think of everything.



Final thoughts


There is a very small amount of job left to make this module work at the current functional level. Please leave feedback here on my blog or reach out to me on Twitter (@ToreGroneng). The module will be published on PowerShellGallery.com and the link to the repro is here (link to PoshARM).

Cheers

Tore

Comments

  1. Do you have this up on github ?

    ReplyDelete
    Replies
    1. hi, yes is was uploaded to GitHub today, however it is still work in progress. I am in the process of refactoring some of the code. That is almost done, however I am also updating the pester tests. The link to the repro on GitHub is in the last sentence :-)

      Cheers

      Tore

      Delete
  2. Hi Tore! Any chance you can post an example of a template setup with a child resource? For example, a web site with a slot of a resource with a lock. Thanks.

    ReplyDelete
    Replies
    1. Hi, that is one idea. Thank you. The module still need a little love, but it is getting there.

      Delete

Post a Comment

Popular posts from this blog

Monitoring Orchestrator runbook events from Operations Manager

Today I will follow up on my colleague’s post Mr ITblog (Knut Huglen) about monitoring Orchestrator Runbook events.  He has build a nice double up SNMP loopback feature that does self monitoring in Orchestrator resulting in entries written to a special Windows Eventlog. Now we need to raise alerts in SCOM when one of his runbooks fails or sends a platform event, who knows there could be trouble lurking in his paradise.

We are not going to do anything fancy, however these are the steps we will be focusing on today:
Create a Management Pack for our customizations Create rules that collects the events from the orchestrator serverOff we go then and fire up the SCOM console and a powershell window. First we create a MP, I am going to use powershell to do this, however you may use the SCOM console as well (Administration – ManagementPacks – Action: Create Management Pack):



Import the Management Pack into SCOM and move on to the Authoring section in the SCOM console. Create a new rule:



Give the…

Powershell – Log like you mean it

How do you do logging in powershell? Why should you do logging? What should you log? Where do you put your log? How do you remove your log? How do you search your log? All important questions and how you answer then depends upon what your background is like and the preferences you have. This will be a 2 part blog post and this is part 1.


Why should you log?

Well it is not mandatory, however I have 2 reasons:
Help with debugging a script/module/functionSelf documenting script/module/function
Firstly; Do you know any program that does not contain any bugs? Working with IT for the last 2 decades, I cannot name one. When you create scripts/modules/functions, you will create bugs, that is where they live and try to make your life a living mess.

Secondly: Adding a little extra information to your logging will make them self documenting. Do you like writing documentation? Well I normally am not fond of it and use logging while debugging to get two birds with one stone.


What should you log?

Anyt…

Powershell - List information about your WIFI networks

This is just a quick post about this new function I have created. Basically this is a text-output to powershell object output function that uses netsh to query the WIFI information. This illustrates the importance of changing the authentication level on your WIFI-network. No matter if you use WEP/WPA/WPA2 your password is available in clear text in your profile.



Cheers

Tore