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)
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:
To summarize an ARM template consists of these main building blocks:
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
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.
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.
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:
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.
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.
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:
For working with ARM templates, we have the following cmdlets:
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:
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.
Yes, there it is with proper indention and everything.
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:
Please contact me if you have other suggestions or ideas. I cannot think of everything.
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
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: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
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: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 PowerShellGallery.com and the link to the repro is here (link to PoshARM).
Cheers
Tore
Do you have this up on github ?
ReplyDeletehi, 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 :-)
DeleteCheers
Tore
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.
ReplyDeleteHi, that is one idea. Thank you. The module still need a little love, but it is getting there.
Delete