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 (





Update 18.01.2017:

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

(

)









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:









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:





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

Import-ARMtemplate will import an template from the clipboard/string or from a file on your computer. Here is how you can use it: 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. Thewill 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:

















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:









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:









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

and the link to the repro is here (

).





Cheers





Tore