Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure Automation #125

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions PSDeploy/PSDeploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ ARM:
Script: ARM.ps1
Description: Uses Azure Resource Manager PowerShell cmdlets to deploy a template to Microsoft Azure or Azure Stack

AzureAutomation:
Script: AzureAutomation.ps1
Description: Deploy a runbook to Azure Automation

Chocolatey:
Script: Chocolatey.ps1
Description: Uses Chocolatey on the local computer to push packages to a Chocolatey repository.
Expand Down
88 changes: 88 additions & 0 deletions PSDeploy/PSDeployScripts/AzureAutomation.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<#
.SYNOPSIS
Deploy a Powershell Runbook to Azure Automation.
.DESCRIPTION
Deploy a Powershell Runbook to Azure Automation.
.PARAMETER Deployment
Deployment to run
.PARAMETER ResourceGroupName
Resource Group to deploy to
.PARAMETER AutomationAccountName
Automation Account to deploy to
.PARAMETER AzureServicePrincipalCredential
Credential of Azure Service Principal
User is Application (client) ID
Password is Secret string / Application Password
.PARAMETER AzureTenantID
Tenant ID of Service Principal
.PARAMETER RunbookType
Type of runbook being deployed, one of "PowerShell", "GraphicalPowerShell", "PowerShellWorkflow", "GraphicalPowerShellWorkflow", "Python2"
.PARAMETER CreateRunbook
If true, will create runbook if it doesn't already exist, otherwise runbook must already exist


#>
[cmdletbinding()]
param (
[ValidateScript({ $_.PSObject.TypeNames[0] -eq 'PSDeploy.Deployment' })]
[psobject[]]$Deployment,

[Parameter(Mandatory)][string]$ResourceGroupName,

[Parameter(Mandatory)][string]$AutomationAccountName,

[Parameter(Mandatory)][pscredential]$AzureServicePrincipalCredential,

[Parameter(Mandatory)][string]$AzureTenantID,

[Parameter(Mandatory)]
[ValidateSet("PowerShell", "GraphicalPowerShell", "PowerShellWorkflow", "GraphicalPowerShellWorkflow", "Python2")]
[string]$RunbookType,

[bool]$CreateRunbook
)

try
{
Write-Verbose "Connecting to Azure"
$null = Connect-AzAccount -Credential $AzureServicePrincipalCredential -ServicePrincipal -Tenant $AzureTenantID -ErrorAction Stop
}
catch
{
throw "Unable to connect to Azure with credentials provided $_"
}
foreach ($deploy in $Deployment)
{
If ($deploy.SourceExists)
{
if($Deploy.SourceType -eq 'File')
{
$rbname = (Split-Path $deploy.source -Leaf).split('.')[0]
Write-Verbose "looking for runbook $rbname"
$get = Get-AzAutomationRunbook -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -ErrorAction SilentlyContinue -Name $rbname
Write-Verbose "got $($get.count) runbooks"
if ((-not $get) -and (-not $CreateRunbook))
{
Write-Warning "Runbook $rbname does not exist, please create before deploying or specify CreateRunbook"
}
else
{
try
{
Write-Verbose "Import-AzAutomationRunbook -Path $($deploy.source) -Type $RunbookType -Published -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Force -ErrorAction Stop"
$null = Import-AzAutomationRunbook -Path $deploy.source -Type $RunbookType -Published -ResourceGroupName $ResourceGroupName -AutomationAccountName $AutomationAccountName -Force -ErrorAction Stop
}
catch
{
Write-Warning "Unable to update Runbook $_"
}
}
}
else
{
Write-Warning "This can ony be used to deploy individual scripts, not directories"
}
}
}

$null = Disconnect-AzAccount
44 changes: 44 additions & 0 deletions docs/Example-AzureAutomation-Deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Azure Automation

## Prerequisites

This DeploymentType uses the [Az module](https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az) to connect to Azure and deploy runbooks.
Because it's meant to run as part of a build pipeline, it requires a service principal to be created with a password (not certificate).

[Creating a Service Principal with the Az module](https://docs.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps)

[Creating a Service Principal with the Azure Portal](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal)

## Options

All options, except the CreateRunbook switch, are Mandatory

* **ResourceGroupName:** Resource Group to deploy runbook to
* **AutomationAccountName:** Automation Account to deploy runbook to
* **AzureServicePrincipalCredential:** Credential of Azure Service Principal, User is Application (client) ID, Password is Secret string / Application Password
* **AzureTenantID:** Tenant ID of Service Principal
* **RunbookType:** Type of runbook being deployed, one of "PowerShell", "GraphicalPowerShell", "PowerShellWorkflow", "GraphicalPowerShellWorkflow", "Python2"
* **CreateRunbook:** Boolean, if true, will create runbook if it doesn't already exist, otherwise runbook must already exist

## Examples

```Powershell
Deploy ExampleDeployment {
By AzureAutomation {
$cred = Get-Credential
FromSource Runbook.ps1
To AzureAutomation
WithOptions @{
ResourceGroupName = "examplegroup"
AutomationAccountName = "example-account"
AzureServicePrincipalCredential = $cred
AzureTenantID = "6b3607b4-375b-447f-9fa1-34e452e1a91b"
RunbookType = "PowerShell"
}
}
}
```

Because each runbook requires a runbook type, FromSource can only be an individual script, not a whole directory.
The To will always be AzureAutomation.
This example gets the login credentials interactively, to use this in a pipeline you would need to generate the credential object another way.