Project to deploy software to Azure VMs using Azure Automation DSC and Azure Storage to host source files.
- Create the following Prerequisites
- Create Azure Automation Account
- Create an Azure Storage Account File share to host msi/installation source files
- Get the Storage Account Access Credentials
- Add Credentials to Azure Automation Assets
- Import Runbook & Publish
- Add configuration to State DSC
- add a schedule to runbook
- Create Configuration scripts
- Get credential for Azure Automation
- use credential in related configs
- Deploy config to node
-
Create an Azure automation account
-
Import following modules
- Az.Accounts : Browse the gallery and add
- Az.Automation: Browse the gallery and add
- ServerApps: Add the zip file in the project modules diretory
-
Get the Run As Credentials ![Get](./Images/GetRunAsCredentials.png = 100x100)
-
Set the Azure Run As Account to be a contributer
Below is a high level view of the solution
## CreateAzure AutomationWe use Azure Automation to push configuration to VMs
-
Create DSC Config
-
Ensure MsiSettings exits under variables.
- If MsiSettings is not available under variables not create a new one
Connect-AzAccount $MsiSettings = @( @{MsiFile = '7z1900-x64.msi'; ProductID = '23170F69-40C1-2702-1900-000001000000'; Name = '7-Zip 19.00 (x64 edition)'; Arguments = '/norestart'}, @{MsiFile = 'googlechromestandaloneenterprise64.msi'; ProductID = '09D53CC6-0A7A-3BE2-B558-542159936402'; Name = 'Google Chrome'} ) new-AZAutomationVariable -AutomationAccountName 'StateConfig-Contoso' -ResourceGroupName 'EastUS' -Name 'MsiSettings' -Value $MsiSettings -Encrypted $false
- to update existing Msisettings edit the below and run
Connect-AzAccount $MsiSettings = @( @{MsiFile = '7z1900-x64.msi'; ProductID = '23170F69-40C1-2702-1900-000001000000'; Name = '7-Zip 19.00 (x64 edition)'; Arguments = '/norestart'}, @{MsiFile = 'googlechromestandaloneenterprise64.msi'; ProductID = '09D53CC6-0A7A-3BE2-B558-542159936402'; Name = 'Google Chrome'} ) Set-AZAutomationVariable -AutomationAccountName 'StateConfig-Contoso' -ResourceGroupName 'EastUS' -Name 'MsiSettings' -Value $MsiSettings -Encrypted $false
-
Connect the Node
- We need a general-purposev2 type Storage Account to host Installation Sources (msi). Sample Storage Account configuration is as follows.
- Create an azure file share
- Get the Storage Account Name and Keys
- Add Keys to Azure Automation Credentials
- Add Credentials to Azure Automation DSC Config
List default Resources available
Get-DscResource -Module PSDesiredStateConfiguration
List Configurable Properties for a Resource
Get-DscResource -Name WindowsFeature -Syntax
WindowsFeature [String] #ResourceName
{
Name = [string]
[Credential = [PSCredential]]
[DependsOn = [string[]]]
[Ensure = [string]{ Absent | Present }]
[IncludeAllSubFeature = [bool]]
[LogPath = [string]]
[PsDscRunAsCredential = [PSCredential]]
[Source = [string]]
}
Sample Windows Feature Config
configuration TestConfig
{
Node IsWebServer
{
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
IncludeAllSubFeature = $true
}
}
Node NotWebServer
{
WindowsFeature IIS
{
Ensure = 'Absent'
Name = 'Web-Server'
}
}
}
To Use Azure Automation Credentials in a script; To mount drive
Use Azure Automation Credentials in DSC Config use the following sample.
Configuration CredentialSample
{
Import-DscResource -ModuleName PSDesiredStateConfiguration
$Cred = Get-AutomationPSCredential 'SomeCredentialAsset'
Node $AllNodes.NodeName
{
File ExampleFile
{
SourcePath = '\\Server\share\path\file.ext'
DestinationPath = 'C:\destinationPath'
Credential = $Cred
}
}
}
Package Resource Syntax
Package [string] #ResourceName
{
Name = [string]
Path = [string]
ProductId = [string]
[ Arguments = [string] ]
[ Credential = [PSCredential] ]
[ LogPath = [string] ]
[ ReturnCode = [UInt32[]] ]
[ DependsOn = [string[]] ]
[ Ensure = [string] { Absent | Present } ]
[ PsDscRunAsCredential = [PSCredential] ]
}
To get the Storage Account Credentials (keys)
$resourceGroupName = 'SystemCenter'
$storageAccountName = 'contosofileserver'
$fileShareName = 'Products'
$AccessKey = 'cMFf6HKrhrDdFRH+TKnOqDhz8atKEzt4iYFwmYzVfd0UhgAogc5AMH3mOgWM+K+GQdPQ7ujqyrtSP3x3Gip3nQ=='
$storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName
$storageAccountKeys = Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName
$password = ConvertTo-SecureString -String $storageAccountKeys[0].Value -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential -ArgumentList "AZURE\$($storageAccount.StorageAccountName)", $password
$connectTestResult = Test-NetConnection -ComputerName azureautomationwithemre.file.core.windows.net -Port 445
if ($connectTestResult.TcpTestSucceeded) {
# Save the password so the drive will persist on reboot
cmd.exe /C "cmdkey /add:`"azureautomationwithemre.file.core.windows.net`" /user:`"Azure\azureautomationwithemre`" /pass:`"GYuI8CRDJCAnRrgmTqA1myfNNl0FsbbpBugrMCVug05nKkjGvvH+ddkvS7rAI0XzyjP6ui8EHxU24nvtge2jTQ==`""
# Mount the drive
New-PSDrive -Name Z -PSProvider FileSystem -Root "\\azureautomationwithemre.file.core.windows.net\installationsources"-Persist
} else {
Write-Error -Message "Unable to reach the Azure storage account via port 445. Check to make sure your organization or ISP is not blocking port 445, or use Azure P2S VPN, Azure S2S VPN, or Express Route to tunnel SMB traffic over a different port."
}
Getting Credential Asset from Azure Automation Sample
$myCredential = Get-AutomationPSCredential -Name 'MyCredential'
$userName = $myCredential.UserName
$securePassword = $myCredential.Password
$password = $myCredential.GetNetworkCredential().Password
To connect a node in a workflow use the following cmdlet.
Register-AzureRmAutomationDscNode
-AzureVMName <String>
[-NodeConfigurationName <String>]
[-ConfigurationMode <String>]
[-ConfigurationModeFrequencyMins <Int32>]
[-RefreshFrequencyMins <Int32>]
[-RebootNodeIfNeeded <Boolean>]
[-ActionAfterReboot <String>]
[-AllowModuleOverwrite <Boolean>]
[-AzureVMResourceGroup <String>]
[-AzureVMLocation <String>]
[-ResourceGroupName] <String>
[-AutomationAccountName] <String>
[-DefaultProfile <IAzureContextContainer>]
[<CommonParameters>]
Getting Varible in Azure Automation
Get-AzAutomationVariable -ResourceGroupName 'EASTUS' -AutomationAccountName 'StateConfig-Contoso' -Name 'MsiSettings'
- Azure Storage
- how to use files in Azure Storage File Server
- Azure Autamation State Configuration
- Azure Automation Credential
- Azure Automation Credential assets
- Azure Table Storage Powershell
- ComputerManagementDsc
- Authoring Powerhell Composite Resources
- Using DSC Composite Resources - Tutorial
- Connect to Azure using Azure Automation