Automação do Azure com Windows PowerShell Desired State Configuration

Para criar a rede virtual é necessário primeiro criar o gama do endereçamento da rede com o cmdlet New-AzureRmVirtualNetworkSubnetConfig, depois pode criar a rede com o cmdlet New-AzureRmVirtualNetwork e definir a subnet criada.

#
+----------------------------------------------------------------+
| Virtual Network |
+----------------------------------------------------------------+
#>
# -- Create Subnet --
$Subnet = New-AzureRmVirtualNetworkSubnetConfig -Name "PSPTLAB" -AddressPrefix 10.0.0.0/24
# -- Create VNet with Subnet --
$Vnet = New-AzureRmVirtualNetwork -Name "PSPTLABVNet" -ResourceGroupName $ResourceGroup -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $Subnet -verbose
Azure com PowerShell: cmdlet New-AzureRmVirtualNetwork
cmdlet New-AzureRmVirtualNetwork

Com a rede virtual criada pode criar o endereço público no Azure que é definido como Instance-level public IP address (PIP) o cmdlet é New-AzureRmPublicIpAddress deve definir se pretende um endereço estático ou dinâmico.

# -- Create a Instance-level public IP address (PIP) for Network interface controller (NIC) --

$PublicIp = New-AzureRmPublicIpAddress -Name "PIP" -ResourceGroupName $ResourceGroup -Location $location -AllocationMethod Dynamic
Azure com PowerShell: cmdlet New-AzureRmPublicIpAddress
cmdlet New-AzureRmPublicIpAddress

Agora pode criar a placa de rede com o cmdlet New-AzureRmNetworkInterface é necessário definir a identificação do endereço público.

# -- Create NIC with PIP and Subnet --

$NIC = New-AzureRmNetworkInterface -Name "NIC" -ResourceGroupName $ResourceGroup -Location $location -SubnetId $Vnet.Subnets[0].Id -PublicIpAddressId $PublicIp.Id
Azure com PowerShell: cmdlet New-AzureRmNetworkInterface
cmdlet New-AzureRmNetworkInterface

Com a rede virtual criada pode criar a máquina virtual, a criação da mesma depende todos os serviços anteriores sem os quais não funciona. O Azure disponibiliza várias imagens de sistemas operativos não só da Microsoft mas também de outras marcas como o Red Hat, por exemplo, o utilizador é livre de escolher o que pretende, o valor que vai pagar, mensalmente, já inclui todo o licenciamento. Tal como a conta de armazenamento há também vários tipos de máquinas virtuais e todas elas são diferentes, pode consultar em https://azure.microsoft.com/pt-pt/pricing/details/virtual-machines/. Vou utilizar uma máquina Standard da série Dv2 destinada a computação para fins gerais de próxima geração com o sistema operativo Microsoft Windows Server 2012 R2 Datacenter. Para qualquer sistema operativo é preciso definir uma conta de administrador e as suas credenciais de acesso em PowerShell. Pode definir de duas formas.

  • Solicitar os dados ao utilizador com o cmdlet Get-Credential –Message e o script fica em standby até serem inseridas as credencias.
    Azure com PowerShell: cmdlet Get-Credential
    cmdlet Get-Credential
  • Definir uma variável e converter para um string protegida com o cmlet ConvertTo-SecureString.
    Azure com PowerShell: System.Management.Automation.PSCredential
    System.Management.Automation.PSCredential

Como se pretende automação vai ser utilizada a segunda opção mas se partilhar o script com alguém lembre-se de apagar a palavra passe, nome de utilizador e de administração. O nome de utilizador que estou a utilizar é itpro. Existem nomes que são reservados para o Azure como Admin e Root. Para além das credenciais, na criação da máquina virtual vão definir-se todos os serviços criados anteriormente. O processo de criação é mais complexo e vai ser utilizado vários cmdlets. O New-AzureRmVMConfig é para criar uma configuração da máquina virtual. O Set-AzureRmVMOperatingSystem é para definir a identificação da máquina, credenciais de acesso, atualizações automáticas e outras definições. O Set-AzureRmVMSourceImage define a imagem que se pretende utilizar; a Microsoft oferece imensas imagens. O seguinte cmdlet permite pesquisar as imagens existentes através PowerShell Get-AzureRmVmImageOfferMenu pode experimentar com a opção 13, 367, 1. Nem todas as imagens estão disponíveis em todas as regiões.

Por exemplo as máquinas virtuais da Symantec não estão disponíveis no Norte da Europa.

Azure com PowerShell: Imagens Symantec no norte da Europa
Imagens Symantec no norte da Europa

Ao selecionar Oeste dos EUA já tem máquinas virtuais disponíveis.

Azure com PowerShell: Imagens Symantec no oeste dos EUA
Imagens Symantec no oeste dos EUA

O Add-AzureRmVMNetworkInterface vai adicionar a placa de rede criada. O Set-AzureRmVMOSDisk vai criar o disco virtual na conta de armazenamento. Por fim para criar a máquina virtual utiliza-se o cmdlet New-AzureRmVM definindo a configuração e localização geográfica.

<#
+----------------------------------------------------------------+
| Virtual Machine |
+----------------------------------------------------------------+
#>
# -- Virtual Machine Settings --
$VMName = "PSPTLABVM"
$VMSize = "Standard_DS1_v2"
$VMPublisherName = "MicrosoftWindowsServer"
$VMPublisherOffer = "WindowsServer"
$VMSkus = "2012-R2-Datacenter"
$VMOSDiskName = "PSPTLABVMOsDisk"
# -- Create a PSCredential for Local Administrator Account --
#$cred = Get-Credential -Message "Type the name and password of the local administrator account."
# -- Create a PSCredential for Local Administrator Account from a Clear Text Password --
$SecurePassword = ConvertTo-SecureString "{INSERT THE PASSWORD" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ("itpro", $SecurePassword);
# -- Create the Virtual Machine --
$VM = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VM = Set-AzureRmVMOperatingSystem -VM $VM -Windows -ComputerName $VMName -Credential $Credential -ProvisionVMAgent -WinRMHttp -EnableAutoUpdate
#$VM = Set-AzureRmVMOperatingSystem -VM $VM -Windows -ComputerName $VMName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$VM = Set-AzureRmVMSourceImage -VM $VM -PublisherName $VMPublisherName -Offer $VMPublisherOffer -Skus $VMSkus -Version "latest"
$VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $NIC.Id
$VM = Set-AzureRmVMOSDisk -VM $VM -Name $VMOSDiskName -VhdUri "https://psptlabstorageaccount.blob.core.windows.net/vhds/psptlabvmosdisk1.vhd" -CreateOption fromImage
New-AzureRmVM -ResourceGroupName $ResourceGroup -Location $location -VM $VM –Verbose
Azure com PowerShell: cmdlet New-AzureRmVM
cmdlet New-AzureRmVM

Com a máquina configurada vai ser instado o Internet Information Services (IIS) por DSC.

Para utilizar o DSC no Azure são necessários vários passos. O script é enviado para ser publicado no Azure, antes de ser publicado é verificado a sua configuração, após a validação o script fica publicado no Azure Automation DSC LifeCycle e pode ser utilizado em qualquer máquina virtual no Azure.

Scriptenviada aRespositórioconfiguraServidor

O script é enviado para o repositório.

O repositório importa e valida o scrip e faz a configuração da informação.

Implementa a configuração do script que se encontra no repositório.

Os scripts podem ter mais de uma configuração e serem aplicados em mais do que uma máquina. Mas, antes de publicar, é necessário compreender a estrutura do ficheiro DSC que é constituído por blocos.

Ambiente da configuraçãoConfiguração, que contem a identificação da configuração.
Configuration ConfigName
{
  ...
Parâmetros que são usados na configuração. Este grupo é opcional.
param(
    [Parameter(Mandatory=$true)]
    [String[]]$Param7
)
Configuração estruturalImplantar a configuração nas máquinas definidas. Pode ter um ou mais blocos.
Node localhost
{
Recurso que pretende configurar. Pode ter um ou mais blocos. O recurso é a propriedade do cmdlet Get-WindowsFeature
WindowsFeature IIS {
  Name = "Web-Server"
  Ensure = "Present"
}
...
Automação de idempotentes
(Propriedade de uma operação de poder ser aplicada mais do que uma vez sem que o resultado se altere)
foreach -parallel ($featureName in $Name)
{
  $feature = Get-WindowsFeature -Name $featureName
  if(($Ensure -eq "Present") -and (!$feature.Installed))
  {
    Install-WindowsFeature -Name $featureName
  }
  ...
}
...

Estes são os módulos disponíveis no DSC, é recomendado que instale os que necessita para utilizar Intellisense na criação dos scripts.

Azure com PowerShell: cmdlet Get-DSCResource
cmdlet Get-DSCResource

Se usar algum destes módulos é necessário definir a sua importação no script a ser utilizado na máquina de destino. Por exemplo para definições na firewall Import-DSCResource -ModuleName xNetworking. O x nos módulos com o xNetworking significa experimental. Estes recursos são corrigidos e monitorizados pelos autores do módulo.

O DSC não funciona apenas no Windows Server também funciona em máquinas clientes como o Windows 10 Pro.

Azure com PowerShell: comando winver e cmdlet Get-DscLocalConfigurationManager
comando winver e cmdlet Get-DscLocalConfigurationManager

Um dos requisitos necessários para trabalhar com DSC é saber qual a versão do PowerShell que está a ser utilizada e pode verificar-se com o cmdlet $PSVersionTable.PSVersion. O DSC foi implementado na versão 4 no Windows 10 build 14393 é utilizada a versão 5.

Azure com PowerShell: cmdlet PSVersionTable
cmdlet PSVersionTable

O que significa que estamos a usar a framewrok Windows Management Framework (WMF) 5 esta framework contem o Windows Remote Management, Windows PowerShell e Background Intelligent Transfer Service e introduz o Windows PowerShell OneGet. Em 27 de janeiro de 2017 foi lançada a versão 5.1 que é compatível com o sistema operativo Windows 7, Windows 8.1, Windows Server 2008 R2, Windows Server 2012, e Windows Server 2012 R2, Windows Server 2016 as novidades das nova versão são publicadas no blog oficial da equipa https://blogs.msdn.microsoft.com/powershell e no MSDN em https://msdn.microsoft.com/en-us/powershell/.

Antes de utilizar o DSC no Windows 8 e Windows Server 2012 R2 é necessário verificar se tem instalado a correção KB2894179, KB2883200, e KB2894029 para instalar pode executar o cmdlet Get-Hotfix para instalar o KB2883200 execute Get-Hotfix –Id KB2883200.

Este é o conteúdo do ficheiro DSC para instalar o IIS.

Ambiente da configuraçãoConfiguração com identificação DSCIIS.
Configuration DSCIIS
{
Configuração estruturalImplantar a configuração na própria máquina local.
node "localhost"
{
Instalação do IIS.
WindowsFeature IIS
{
Ensure = "Present"
Name = "Web-Server"
}
}
}

Guarde o ficheiro com o nome DSCIIS.ps1 na mesma localização do script de automação.

Pode confirmar a configuração disponível com o cmdlet Get-Command que vai mostrar o conteúdo do script, os parâmetros, a informação ao utilizador e outras informações.

Get-Command .\DSCIIS.ps1 | Format-List *
Azure com PowerShell: cmdlet Get-Command
cmdlet Get-Command

A equipa da Microsoft Windows PowerShell tem um repositório central no GitHuB de recursos do DSC em https://github.com/PowerShell/DscResources.

Voltando ao script de automação a primeira tarefa é a validação e publicação, utiliza-se o cmdlet Publish-AzureRmVMDscConfiguration. O script vai primeiro ser validado antes de ser enviado. Se o mesmo não passar a validação retorna o tipo do erro e a localização do erro.

Azure com PowerShell: cmdlet Publish-AzureRmVMDscConfiguration erro no script
cmdlet Publish-AzureRmVMDscConfiguration erro no script

Por defeito todos os scripts publicados vão estar no container windows-powershell-dsc que é criado automaticamente. Se não pretender utilizar o container por defeito pode criar um e definir o mesmo no cmdlet. Pode consultar todos os ficheiros que estão no container no portal do Azure, PowerShell, Visual Studio ou Explorador de Armazenamento/Storage Explorer compatível com sistemas operativos Microsoft, Linux e Mac que está disponível nas transferências na página do Azure em https://azure.microsoft.com/pt-pt/downloads/.

<#
+----------------------------------------------------------------+
| Desired State Configuration (DSC) |
| Install Internet Information Services (IIS) |
+----------------------------------------------------------------+
#>
# -- Publish DSC --
#Remove-AzureStorageBlob -Blob DSCIIS.ps1.zip -Container windows-powershell-dsc -Context $StorageContext -Verbose
Publish-AzureRmVMDscConfiguration -ConfigurationPath ".\DSCIIS.ps1" -ResourceGroupName $ResourceGroup -StorageAccountName $StorageAccountName -Verbose
# -- View Published Blob File --
#Get-AzureStorageBlob -Blob DSCIIS.ps1.zip -Container windows-powershell-dsc -Context $StorageContext -ErrorAction Stop
Azure com PowerShell: cmdlet Publish-AzureRmVMDscConfiguration
cmdlet Publish-AzureRmVMDscConfiguration

Com o DSC corretamente validado e publicado podemos aplicar em qualquer máquina virtual para aplicar utiliza-se o cmdlet Set-AzureRmVMDscExtension é necessário definir a conta de armazenamento, o container onde está o script, o nome do script e da máquina virtual. Um ponto importante é definir a versão da extensão do DSC. Após aplicar na máquina é necessário atualizar a mesma.

# -- Configure DSC in the VM --
$DSCArchiveStorageAccountName = "windows-powershell-dsc"
$DSCExtVersion = "2.8" #Version 1.0 to 2.3 was retired
Set-AzureRmVMDscExtension -ResourceGroupName $ResourceGroup -VMName $VMName -ConfigurationArchiveBlob “DSCIIS.ps1.zip” -ArchiveStorageAccountName $StorageAccount.StorageAccountName -ArchiveResourceGroupName $StorageAccount.ResourceGroupName -ArchiveContainerName $DSCArchiveStorageAccountName -ConfigurationName “DSCIIS” -Version $DSCExtVersion -AutoUpdate:$true -Force
Get-AzureRmVM -Name $VMName -ResourceGroupName $ResourceGroup | Update-AzureRmVM
# -- Remove DSC From the VM --
#Remove-AzureRmVMDscExtension -ResourceGroupName $ResourceGroup -VMName $VMName –verbose
Azure com PowerShell: Set-AzureRmVMDscExtension
Set-AzureRmVMDscExtension

Enquanto o DSC está a ser aplicado pode monitorizar a sua aplicação com o cmdlet Get-AzureRmVMDscExtensionStatus em que tem que definir o nome da máquina e a que grupo de recursos pertence. Não pode executar esta verificação na mesma janela de PowerShell tem que abrir uma nova janela de linha de comandos, Windows PowerShell ou PowerShell ISE. Fazer uma nova autenticação no Azure RM e executar o cmdlet.

$VMName = "PSPTLABVM"
$ResourceGroup = "PSPTLAB"
Get-AzureRmVMDscExtensionStatus -VMName $VMName -ResourceGroupName $ResourceGroup -Verbose
Azure com PowerShell: cmdlet Get-AzureRmVMDscExtensionStatus
cmdlet Get-AzureRmVMDscExtensionStatus

Publicado na edição 55 (PDF) da Revista PROGRAMAR.