Previously in Note to self…
I’ve been discussing how my first Logic App deployment package was not exactly what I’ve envisaged. So when I had a chance to revamp it, I jumped into the opportunity. You can read about that here.
Logic App Template Generator
I’ve decided to use Jeff Hollan’s Logic App Template Generator – a PowerShell utility that Jeff created sometime ago and have made available on GitHub. Jeff’s PowerShell module have a two cmdlets:Get-LogicAppTemplate: this cmdlet generates the template of a logic app passed as parameter.
- Get-ParameterTemplate: this cmdlet generates the parameters of an ARM template passed as parameter.
Installing the Template Generator
Installing the component is as easy as forking the code and building. But be aware that it requires a couple of components:
Once the component is installed, you need to import the module for your PowerShell session:
Import-Module <path to local repository>\LogicAppTemplateCreator\LogicAppTemplate\bin\Debug\LogicAppTemplate.dll
After importing, the cmdlets are ready to be used. Notice that as much of the other commands that interact with Azure, you need to be logged into Azure first. You can do that by simply executing the following command:
Login-AzureRMAccount
A Resource Group Logic App Template Generator
With the component installed and working fine, it was now time to create a script that execute the following steps:
- Load a list of logic apps from a resource group
- For each logic app
- Create a new folder to host the logic app templates
- Create the Logic App Template and save in the new folder created
- Create the Parameter file and save in the new folder created
Loading a list of logic apps from a resource group
This can be achieved with a couple of PowerShell cmdlets:
Get-AzureRmSubscription -SubscriptionName $subscriptionname | Select-AzureRmSubscription Find-AzureRmResource -ResourceGroupNameContains $resourcegroup -ResourceType Microsoft.Logic/workflows
In the script above, the first line find a subscription $subscription in your list of subscriptions and select that subscription. From that point on, cmdlets will reference that subscription. The second line find all resources in a resource group $resourcegroup whose type is Microsoft.Logic/workflows.
Extracting templates for each command
With the list of logic apps retrieved, we can now loop through the result set and create
ForEach-Object{ $logicappfolder = [IO.Path]::GetFullPath((Join-Path $destination $_.Name)) md $logicappfolder -Force | Out-Null $destinationfile = $(Join-path $logicappfolder ($_.Name + ".json")) $destinationparmfile = $(Join-path $logicappfolder ($_.Name + ".param.json")) armclient token $_.SubscriptionId | Get-LogicAppTemplate -LogicApp $_.Name -ResourceGroup $_.ResourceGroupName -SubscriptionId $_.SubscriptionId -TenantName $tenantname -Verbose | Out-File $destinationfile -Force Get-ParameterTemplate -TemplateFile $destinationfile | Out-File $destinationparmfile -Force}
The code above runs pipped on the result of the previous code snippet. Within that snippet we execute the following operations:
- Define and create a new logic app folder.
- Define the names of both logic app template and parameter files.
- Extract the template of a logic app, saving the result to the folder
- Extrat the parameter file, saving the result to the folder.
The lines highlighted are at the core of the snippet, using the cmdlets implemented by the Logic App Template Generator. ARM Client is used to aqcuire an authentication token which is used by Get-LogicAppTemplate to access the resource group.
Putting everything together
The final script looks like this:
param([string] $subscriptionname, [string] $tenantname, [string] $resourcegroup, [string] $destination) # Import the Logic Apps Template Module # $module = resolve-path ".\..\bin\Debug\LogicAppTemplate.dll" Import-Module $module # Create required folders # md -Force $destination | Out-Null # Select the correct subscription # Get-AzureRmSubscription -SubscriptionName $subscriptionname | Select-AzureRmSubscription | Out-Null Write-Host # Gets a list of logic app Find-AzureRmResource -ResourceGroupNameContains $resourcegroup -ResourceType Microsoft.Logic/workflows | ForEach-Object{ Write-Host $("Creating {0} Logic App Template" -f $_.Name) # Define the destination folder # $logicappfolder = [IO.Path]::GetFullPath((Join-Path $destination $_.Name)) md $logicappfolder -Force | Out-Null # Define the destination file names # $destinationfile = $(Join-path $logicappfolder ($_.Name + ".json")) $destinationparmfile = $(Join-path $logicappfolder ($_.Name + ".param.json")) # Create Logic App Template # armclient token $_.SubscriptionId | Get-LogicAppTemplate -LogicApp $_.Name -ResourceGroup $_.ResourceGroupName -SubscriptionId $_.SubscriptionId -TenantName $tenantname -Verbose | Out-File $destinationfile -Force # Generate the Parameter File # Get-ParameterTemplate -TemplateFile $destinationfile | Out-File $destinationparmfile -Force} Write-Host
Using the script
In order to use the script (which is now added to Jeff’s repository under cmdlets) you just need to follow the steps below:
- Open PowerShell console
- Navigate to <path to local repository>\LogicAppTemplateCreator\LogicAppTemplate\Cmdlets\
- Execute the following command:
./Get-RGLogicAppsTemplate.ps1 "<mysubscription" "<mytenant>" "<myresourcegroup>" "<mypath>"
Where:
- mysubscription is the name of the subscription containing the resource group (e.g. Contoso Development)
- mytenant is the name of the tenant that the subscription is associated to (e.g. contoso.onmicrosoft.com)
- myresourcegroup is the name of the resource group containing the logic apps to export (e.g. Sample Application RG)
- mypath is the name of the folder where the subfolders and logic apps will be created. If the folder doesn’t exists it will be created.
A sample call would look like this:
./Get-RGLogicAppsTemplate.ps1 "Contoso Development" "contoso.onmicrosoft.com" "Sample Application" "c:\sampleapplication"
Next Steps
With this exercise I was able to create parse a resource group and generate logic apps templates for each one of them. So I am now one step closer of my final goal of having a full set project with individual templates that can be deployed either by themselves or as a package.
To do this, I need to dynamically create a nested template. And that is the topic of my next post.
Leave a Reply