Automating Azure Automation Accounts - Part 2 - Creating the custom module
Now that the manual stuff was out of the way, it’s time to set up the custom PowerShell module.
Part 2 - Setting up a PowerShell Module for Automation Account
Introduction:
This article is part of a series on integrating Azure Automation Accounts with Azure DevOps. You can check out Part 1 first if you’d like.
Problem:
Following up from my previous post, I now have these things set up:
- An Azure DevOps Organization
- An Azure DevOps Repository (
AutomationRunbooks
) - An Azure Automation Account
- Source control configured to pull from the repo
I can’t stand having to keep track of multiple copies of code (the DRY principal), so I needed a way to share code between multiple runbooks. In order to accomplish this, I decided to create a PowerShell Module and use that to share code (additional notes below) across runbooks.
Solution
Creating a custom module seemed easy, but there’s some nuance to it when you have to deploy in an Automation Account. I loosely followed a few articles like this one when I was started working on this, but these are the basic steps I took:
- Open VSCode and use the terminal (with PowerShell) to navigate to your desired directory
- Create and navigate to a new folder for your module
md AutomationModule; cd AutomationModule;
- Create a new module manifest file (and open it)
New-ModuleManifest -Path .\AutomationModule.psd1; code .\AutomationModule.psd1;
- Edit the manifest as follows:
- Replace
RootModule
(~line 12) withRootModule = 'AutomationModule.psm1
- Replace
FunctionsToExport
(~line 72) withFunctionsToExport = '*'
The original value caused issues when I uploaded the module and imported it - Replace
CmdletsToExport
(~line 72) withCmdletsToExport = '*'
- Replace
AliasesToExport
(~line 72) withAliasesToExport = '*'
- Update other properties as desired
- Replace
- Create a new module script
code AutomationModule.psm1
- I used what I found to be a common style of importing/exporting functions in a module (the Public/Private method) ```PowerShell Write-Verbose ”Loading AutomationModule”;
# Load Private functions ## These are internal to the module and can’t be accessed outside of it $(Get-ChildItem -Path $PSScriptRoot\Private*.ps1) | %{ . $_.FullName; }
# Load Public functions ## These will be loaded and exported as functions available to any script that imports this module $(Get-ChildItem -Path $PSScriptRoot\Public*.ps1) | %{ Write-Verbose ”- $($.FullName) | $($.BaseName)”; . $.FullName; Export-ModuleMember -Function $.BaseName -Verbose; } ```
- Create Private and Public folders in the root of your module directory along with any additional functions that serve each of those purposes
mkdir Private; mkdir Public;
- Test the module manifest to ensure it’s valid
Test-ModuleManifest -Path AutomationModule.psd1;
Now that the module has been created and tested, I needed to uploaded it to my Automation Account. In order to do that, I had to perform a few steps:
- Compress just the module files (ignore zip file if we run this again)
# Compress all the files in the directory except for any existing zip file we've already created for this module Get-ChildItem -Path . -Exclude @('AutomationModule.zip') |Compress-Archive -DestinationPath AutomationModule.zip -Confirm:$false -Force;
- In the Automation Account, navigate to the Modules section
- Select Add a module and upload the newly created zip file
- The modules list will show the uploaded module with a importing status. This may take a few minutes or to import and should be successful
Notes :
When uploading a module to the Automation Account, you may notice that the file uploads to an Azure Storage account, after which it’s imported. We will need to duplicate this process manually when we set up a deployment pipeline in Azure DevOps.
One big thing to remember is that once a module is uploaded to the automation account, there’s no way to download it or look at it’s contents. You can delete the module or upload a new version, but that’s it. Keep that in mind as you consider what code you want to include in your module vs directly in your runbooks. My recommendation is to only put shared (& well tested) code in a module. That way you won’t need to constantly be uploading new versions and when you’re trying to debug your runbooks, you won’t be flying blind.
Conclusion
To wrap up Part 2, we’ll review what we’ve done:
- Create a new PowerShell Module in VSCode
- Upload the module to an Automation Account
In Part 3, I’ll show you how to automate the deployment of the module to an automation account any time a new commit is made to the master branch.
Comments