Using an Azure Automation Account Runbook to create and email a Duo report with SendGrid

I received a lot of great feedback for my previous Azure Function App with Logic App posts, which demonstrated how to create HTML reports that were scheduled to be mailed out at the end of the one. A common question that I received after the posts was whether it was possible to create these reports with Azure Automation Accounts and Runbooks. The answer is certainly, yes, and I would like to demonstrate this with another report I had created for providing a count of the amount of users provisioned in Cisco Duo, which is commonly used for providing 2-factor authentication.

Along with using an Azure Automation Account for reports, I would also like to use this post to demonstrate the following:

  1. How to import custom PowerShell Module into an Automation Account (we’ll be using a the Duo PowerShell module that Matt Egan has created and shared via his GitHub: https://github.com/mbegan/Duo-PSModule)
  2. How to use a Automation Account Runbook to generate a report
  3. Storing and retrieving a secret in Azure Key Vault (we’ll be storing the API key for SendGrid in an Azure Key Vault)
  4. Using SendGrid to the report via email

Step #1 – Create an Automation Account

The first step is to create an Automation Account that we’ll be using to host the Runbook to generate the report and use SendGrid to send it out. We’ll be storing the SendGrid API key in an Azure Key Vault and therefore need to grant access to those keys for the Automation Account and that’s why this needs to be created first.

grant access to those keys for the

eed the Automation Account’s System

We’ll need the Automation Account’s System assigned Object (principal) ID to grant it permissions to access the Key Vault secret so navigate to the Identity blade and copy the Object (principal) ID that will be used in the following steps:

Key Vault secret so navigate to the

Step #2 – Create an Azure Key Vault, add SendGrid API Key as Secret, grant Automation Account permissions to read secret

With the Automation Account created, proceed to create an Azure Key Vault if you do not already have one:

The preferred way for the Access configuration

The preferred way for the Access configuration today is Azure role-based access control so our Automation Account will only be able to access a specific secret. The older Vault access policy requires permissions to be granted to the whole vault, which makes it difficult to secure other secrets in the vault. Proceed to select Azure role-based access control as the Permission model under the Access Policy menu:

t and create the Azure Key Vault

Customize the settings as required or leave them as default and create the Azure Key Vault.

used to create the new vault will

The account used to create the new vault will not have any permissions to the vault so attempting to perform any operations areas such as Secrets will display the message: You are unauthorized to view these contents.

Secrets will display the message

Proceed to grant the account you’re logged in as through the Access control (IAM) blade > Add role assignment:

earch for Key Vault Administrator and grant the permission

Search for Key Vault Administrator and grant the permission:

created, we can now

te permissions to the vault

With the appropriate permissions to the vault assigned, proceed to create a new Secret to store the SendGrid API Key:

appropriate permissions to the vault assigned,

Click on the SendGrid secret:

retrieve the secret. Click on the

With the secret created, we can now grant the Automation Account the ability to retrieve the secret. Click on the SendGrid secret:

Access Control (IAM) blade,

In the SendGrid secret, navigate to Access Control (IAM) blade, Add, then Add role assignment:

Access Control (IAM) blade, Add,

Select Key Vault Secrets User as the role

Select Key Vault Secrets User as the role:

Managed identity, then locate the Automation

Select Managed identity, then locate the Automation Account and select it:

roceed to assign the permissions

Proceed to assign the permissions:

should now have permissions to retrieve the SendGrid

The Automation Account should now have permissions to retrieve the SendGrid secret value;

Step #3 – Import the custom Duo PowerShell Module

Rather than attempt to write the PowerShell code required to authenticate with the Duo Admin API (https://duo.com/docs/adminapi) with a HMAC signature, then call the API methods, we’ll be using Matt Egan’s PowerShell module he has shared with the community years ago that still works today https://github.com/mbegan/Duo-PSModule

The Duo PowerShell module Matt Egan provided does not simply upload into Azure Automation’s Modules blade as the psd1 file references to the Duo_org.ps1 file that is mean to store the information required to connect to the Duo API.

Neil Sabol has a great write up that explains this and how to workaround the issue so I’ll be using his method to demonstrate the configuration: https://blog.neilsabol.site/post/importing-duo-psmodule-mfa-powershell-module-azure-automation/

The method I’ll be using is not to upload a blank Duo_org.ps1 file but rather comment all references to it in the Duo.psd1 file. You can find the updated file here in my GitHub: https://github.com/terenceluk/Azure/blob/main/Automation%20Runbook/Duo/Duo.psd1

Proceed to download the Duo.psd1 and Duo.psm1 from my GitHub https://github.com/terenceluk/Azure/tree/main/Automation%20Runbook/Duo, zip them up into a package named Duo.zip (make sure Duo.zip is the file name) then import them into the Automation Account Modules:

7.1 as the Runtime version sok with 7.1 as the Runt

I haven’t had much luck with 7.1 as the Runtime version so proceed to select 5.1 as the Runtime version:

Confirm the module has successfully imported

Initiate the import:

see if the module imported properly is by

Confirm the module has successfully imported:

hat the available cmdlets are displayed

One of the ways to check and see if the module imported properly is by clicking into the module and verify that the available cmdlets are displayed:

API requires authentication

Step #4 – Create a Protected Application in Duo and add authentication information as Automation Account encrypted variables

Using the Duo Admin API requires authentication so we’ll need to create a protected application in the Duo Admin portal as described in the document here: https://duo.com/docs/adminapi

portal as described in theSecret key, and API hostname

Copy the Integration key, Secret key, and API hostname as we’ll need them to create the encrypted variables in the following steps, and grant the application the required permissions:

Automation Account, navigate to create

Proceed to the Automation Account, navigate to create the following variables:

  1. MyDuoDirectoryID
  2. MyDuoIntegrationKey
  3. MyDuoSecretKey
  4. MyDuoAPIHostname

Directory ID can be located

**Note that the Duo Directory ID can be located by navigating to: Users > Directory Syncs, select the configured directory then copy the key under the heading Admin API directory key:

hen copy the key under the

permissions created and configured

Step #5 – Create the runbook to generate a report of the users and email via SendGrid

With all the components and permissions created and configured, the last step is to create the runbook and put the code in that will build the report and use the SendGrid API to send the email report. From within the Automation Account, navigate to the Runbooks blade:

email report. From within the A

Click on Create a runbook:

will be displayed where we can paste

Fill in the required fields:

following PowerShell Runbook will be displayed where we

The following PowerShell Runbook will be displayed where we can paste the PowerShell script to be executed:

fromEmailAddress

The script I will be using to generate and email the report can be found here: https://github.com/terenceluk/Azure/blob/main/Automation%20Runbook/Email-Duo-User-Count-and-List.ps1

Customize the following variables:

$VaultName = “kv-Production” # Azure Key Vault Name

$destEmailAddress = “tluk@contoso.com” # From address

$fromEmailAddress = “duoreport@contoso.com” # To address

$subject = “Duo User Report” # Email Subject

<h2>Client: Contoso Limited</h2>

Proceed to paste the code into the runbook:

paste the code into the runbook

Proceed to click Save:

button to bring up the test window

Before publishing the Runbook, click on the Test pane button to bring up the test window, then click on the Start button to test the runbook:

Confirm that the test successfully completes

email sent contains the expected report as such

Confirm that the test successfully completes:

contains the expected report

Verify that the email sent contains the expected report as such:

publish the report once we’ve confirmed that the report

Proceed to publish the report once we’ve confirmed that the report is delivered:

runbook according to when

The last step is to schedule this runbook according to when the report should be ran so proceed to click on the Schedules blade and then Add a schedule:

Click on Link a schedule to your runbook

Click on Link a schedule to your runbook:

Click on Add a Schedule

Click on Add a Schedule:

desired schedule

Configure the desired schedule (the settings in the screenshot is configured to run on the last day of the month):

pane should now display

The schedules pane should now display the configured schedule and its next run time:

pane should now display the configured

That’s it. Hope this helps anyone who might be looking for information on how to configure the various components demonstrated in this post.