Terraform - Uploading a local PowerShell module to an Azure Automation account
Test environment Ubuntu 20.04, Terraform v0.12.28, provider.azurerm v2.18.0
Azure Automation runbooks are a convinient way to run code in the cloud or on-premises (using Hybrid workers). You create a runbook, create a webhook and your code can be pretty much triggered by any event or system.
I had a scenario where some of my runbooks were using a custom PowerShell module that was not publicly available.
This short article document my approach.
While developping some terraform configuration I noticed the azurerm
provider did not offer a way to upload a PowerShell module into the Automation account. You can only provide a Uri
of a module location,… meaning they expect you make it available somewhere to be picked up. This applies to other tool offerings (ARM, API, …).
However, if you use the Azure Portal, you have the option to upload your module as a zip file. Looks like Microsoft provide a Storage Account in the back end, generate a link and pass it other to Azure Automation to import the file.
This is what you would see in the portal after submitting your file:
Uploading a PSModule to a Storage Account with Terraform
I used Terraform to replicate the Azure Portal functionnality in the following scenario:
- Create a Storage Account
- Create a Blob container
- Upload the file
- Create a SAS key (valid for 180 seconds in my case)
- Provide the link to Azure Automation Account to import the module.
Here is whole workflow, including the dependencies.
azurerm_automation_module Terraform resource
As you can see in the hashicorp documentation, the terraform resource azurerm_automation_module
only provide a uri
parameter for module to import.
resource "azurerm_automation_module" "mymodule" {
name = "mymodule"
resource_group_name = azurerm_resource_group.example.name
automation_account_name = azurerm_automation_account.example.name
module_link {
uri = "https://somewhere/mymodule.1.0.0.zip"
}
}
Code
Show me the code already! Jump to download
In the following I’m using Terraform and the azurerm provider to create the resources needed. Nothing very complicated but a few requirements to be aware of.
Requirements
Authentication
For the authentication to Azure I’m using a Service Principal Name (SPN) which has the appropriate permissions to go and do things on my Subscription.
As an example, you can create an SPN and grant it “Contributor” permissions using the following Az Cli commands:
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/<subID>"
The output will look like this
{
"appId": "<Secret Stuff>", # client_id
"displayName": "azure-cli-2019-05-26-21-21-54",
"name": "http://azure-cli-2019-05-26-21-21-54",
"password": "<Secret Stuff>", # client_secret
"tenant": "<Secret Stuff>" # tenant_id
}
Create the secrets.tfvars.json file
From the previous output, I’m creating a file called secrets.tfvars.json
.
This file will be passed to Terraform at runtime.
{
"appId": "<spn app id>",
"password": "<spn password>",
"tenant": "<tenant id>",
"subscription_id": "<sub id>"
}
If you intend to run terraform in a CI/CD system, you might choose to store these values in a Vault, pull them at runtime and set environment variables recognized by Terraform.
Usage
Once the requirements described above are in place, we can proceed with the following commands:
# Navigate to directory containing the configurations
# Initial configuration/get dependencies
terraform init
# Plan and Apply our changes
terraform plan -var-file "secrets.tfvars.json" -out automation.tfplan
terraform apply "automation.tfplan"
# Destroying the resources
terraform plan -var-file "secrets.tfvars.json" -out automation.tfplan -destroy
terraform apply "automation.tfplan"
terraform plan
terraform apply
Download
The code is available on Github on my terraform
repository.
Leave a comment