Configurazione di macchine Linux su Azure tramite DSC

In un articolo precedente (https://www.ictpower.it/guide/installare-e-configurare-powershell-desired-state-configuration-for-linux.htm) abbiamo visto come configurare un ambiente per il deploy automatico di packages tramite Desired State Configuration for Linux su client e server nella nostra rete locale.

Vediamo cosa succede nel caso in cui l’esigenza è quella di configurare delle macchine linux che si trovano invece sul cloud di Microsoft, da tutti conosciuto con il nome di Azure. Per questo esempio utilizzeremo una macchina Debian, creandola utilizzando uno dei template disponibili; per creare le risorse su Azure è necessario possedere una sottoscrizione attiva.

Iniziamo proprio creando le risorse necessarie su Azure, effettuiamo quindi il login su https://portal.azure.com e selezioniamo dal menu:

Nuovo -> Calcolo -> Ubuntu Server 16.04 LTS

Quindi facciamo click su Crea per avviare la configurazione di una macchina virtuale Ubuntu.

Un semplice wizard richiederà di compilare tutte le informazioni necessarie, quali tecnologia dei dischi da utilizzare, nome macchina, modalità di autenticazione e gruppo di risorse a cui associare la VM. Sceglieremo poi le risorse hardware, la configurazione della rete ed eventuali servizi aggiuntivi. In pochi minuti una notifica sulla pagina web del portale ci informerà del completamento dell’operazione, e la nostra macchina sarà raggiungibile tramite collegamento ssh direttamente sull’ip pubblico assegnato.

Il wizard chiede di assegnare un nome al gruppo di risorse che conterrà la macchina Ubuntu e tutti i servizi correlati (storage, rete, ecc…); questo nome verrà utilizzato in seguito per creare altre risorse. Per il mio esempio il nome del gruppo di risorse è LinuxDSC.

Allo stato attuale le versioni di OMIserver e dell’agent DSC non permettono il deploy corretto delle configurazioni nel caso queste prevedano l’installazione di pacchetti software. Essendo il nostro scopo proprio quello di installare dei servizi sulla macchina linux remota, è neccessario procedere all’aggiornamento dei due pacchetti. L’operazione è molto semplice e possiamo effettuarla direttamente connettendoci via SSH alla macchina remota. Io ho utilizzato Windows Bash, ma possiamo utilizzare putty o un qualsiasi altri client ssh.

Connettiamoci via SSH quindi all’IP pubblico che troviamo sul portale Azure, relativo alla nostra VM, ed eseguiamo sulla macchina linux i seguenti comandi per scaricare nella cartella /tmp le versioni (ad oggi) più recenti di OMI server e PowerShell DSC:

sudo wget https://github.com/Microsoft/omi/releases/download/v1.1.0-0/omi-1.1.0.ssl_100.x64.deb -P /tmp

sudo wget https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases/download/v1.1.1-294/dsc-1.1.1-294.ssl_100.x64.deb -P /tmp

e li installiamo con:

sudo dpkg -i /tmp/omi-1.1.0.ssl_100.x64.deb /tmp/dsc-1.1.1-294.ssl_100.x64.deb

Possiamo verificare di avere le versioni corrette con i comandi:

sudo dpkg -l | grep dscsudo dpkg -l | grep omi

 

E’ possibile anche avviare una sessione SSH utilizzando PowerShell, ma è necessario installare un modulo aggiuntivo chiamato Posh-SSH, per aggiungere il supporto a questo protocollo. Il modulo è eventualmente disponibile sul sito PowerShell Gallery a questo indirizzo:

https://www.powershellgallery.com/packages/Posh-SSH/1.7.7

Per l’installazione, in ogni caso, è sufficiente aprire PowerShell come amministratore ed eseguire:

Install-Module -Name Posh-SSH

Volendo utilizzare i cmd-let di PowerShell per gestire la nostra sottoscrizione Azure abbiamo bisogno di installare anche i moduli Azure PowerShell, scaricando ed installando il pacchetto disponibile a questo link:

http://aka.ms/webpi-azps

A questo punto possiamo effettuare il login su Azure utilizzando ilcomando

Add-AzureRmAccount

Dopo aver inserito le credenziali, PowerShell ci risponde con i dettagli della sottoscrizione:

Nel caso esistano più sottoscrizioni con lo stesso account possiamo selezionare quella da utilizzare con i seguenti comandi:

#Connessione ad Azure

Add-AzureRmAccount

#Selezione subscription

$subscription (Get-AzureRmSubscription  Out-GridView -Title ‘Select an Azure Subscription …’  -PassThru)

Set-AzureRmContext -SubscriptionId $subscription.subscriptionId -TenantId $subscription.TenantID

E’ necessario quindi creare un ulteriore “Account di archiviazione” o “Storage Account” per ospitare le configurazioni DSC. Utilizziamo anche qui Azure PowerShell specificando il nome del nostro Resource Group, il nome del nuovo storageaccount da creare e la location. I valori disponibili per la variabile $Location ad oggi sono i seguenti: eastus, eastus2, eastus2stage, westus, westeurope, eastasia, southeastasia, japaneast, japanwest, northcentralus, southcentralus, centralus, northeurope, brazilsouth, australiaeast, australiasoutheast, southindia, centralindia, westindia, canadaeast, canadacentral, westus2, westcentralus, uksouth, ukwest, koreacentral, koreasouth

$ResourceGroupName “LinuxDSC”

$storageaccountName “dscdisk”

$Location “westeurope”

New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $storageaccountName -Type Standard_LRS -Location $Location

Al termine dell’elaborazione ci verrà restituito un messaggio di conferma

Possiamo verificare che il nuovo storage account è disponibile sul portale Azure:

Creiamo ora un container all’interno dello storage account; per non appesantire la guida creiamo il container con “Permission -Off” rendendo accessibile il container solo al proprietario. Essendo le variabili già definite eseguiamo:

Set-AzureRmCurrentStorageAccount -ResourceGroupName $ResourceGroupName -Name $storageaccountName

New-AzureStorageContainer -Name linuxdsc -Permission Off

Il container è subito disponibile, e ce lo conferma la risposta nella PowerShell

Ora prepariamo la nostra macchina per eseguire il push della configurazione, nel mio caso sto utilizzando una macchina con Windows 10 Pro. Abbiamo bisogno di installare il modulo DSC for Linux, quindi eseguiamo da una PowerShell con diritti amministrativi il comando:

Install-Module –name nx

In alternativa è possibile effettuare il download del pacchetto MSI da:

https://www.microsoft.com/en-us/download/details.aspx?id=46919

ed installarlo utilizzando le opzioni predefinite. L’installazione provvederà ad aggiungere il modulo nx, necessario per l’utilizzo di DSC for Linux nella cartella

%USERPROFILE%\Documents\WindowsPowerShell\Modules

Tutto è pronto per la preparazione di uno script di configurazione, che per l’occasione consisterà nell’installazione automatizzata del servizio httpd sulla nostra macchina Azure con sistema operativo Ubuntu. Lo script è molto semplice, e va eseguito direttamente da PowerShell. Consiste in una prima parte di dichiarazione della configurazione ed una seconda in cui viene eseguito il comando per generare il file .mof che DSC utilizzerà per eseguire il push sulla macchina remota.

Personalmente ho avuto un po’ di problemi nell’incollare lo script nella finestra PowerShell poiché venivano stranamente aggiunti caratteri in modo casuale corrompendo il testo incollato. Non sapendo se il problema dipende da qualcosa di particolare nella mia situazione, mostro comunque il workaround utilizzato.

Ho incollato lo script direttamente nell’ISE e salvato in formato .ps1, quindi ho richiamato l’esecuzione dello script direttamente da PowerShell. Per aprire l’ISE è sufficiente cercare PowerShell ISE nella barra della ricerca di Windows, o lanciare il comando ISE da PowerShell.

Lo script utilizzato è il seguente:

Configuration
ubuntuconf {


Import-DscResource -Module nx


Node “localhost” {

    nxPackage
Apache {

        PackageManager ‘Apt’

        Ensure ‘Present’

        Name ‘apache2’

    }

}

}

ubuntuconf -OutputPath: “C:\temp”

Salviamo lo script ad esempio con il nome conf.ps1 e lo eseguiamo da PowerShell:

.\conf.ps1

Verrà creato un file chiamato <nomehost>.mof nella directory indicata nello script; questo file è il modello che DSC confronterà con lo stato attuale della macchina da configurare, effettuando in maniera automatizzata le eventuali operazioni di adeguamento. Nel nostro caso, ad esempio, si assicurerà che il pacchetto apache2 sia installato.

Trasferiamo questo file all’interno del container che abbiamo creato su Azure con il comando PowerShell:

Set-AzureStorageBlobContent -Container linuxdsc -File C:\temp\localhost.mof

Anche in questo caso possiamo verificare dal portale Azure che il nostro contenitore include il file .mof che abbiamo appena inviato

Ora è necessario configurare i privilegi di accesso su questo file per fare in modo che la nostra macchina Ubuntu sia in grado di leggerlo. A costo di complicare un po’ la procedura evitiamo di ottenere un link pubblico impostando l’accesso con autenticazione tramite Shared Access Signatures (SAS), creando un opportuno token. Possiamo impostare un limite di tempo per la validità di questo token, e per questo esempio imposteremo 1 mese.

$templateuri New-AzureStorageBlobSASToken -Container linuxdsc -Blob ‘localhost.mof’ -Permission -ExpiryTime (Get-Date).AddMonths(1) -FullUri

Il comando

echo $templateuri

ci restituirà il valore da utilizzare nello script DSC descritto successivamente. Infine otteniamo l’elenco delle chiavi disponibili con il commando:

Invoke-AzureRmResourceAction -ResourceGroupName $ResourceGroupName -ResourceType Microsoft.Storage/storageAccounts -ResourceName $StorageAccountname -Action listKeys -ApiVersion 2015-05-01-preview -Force -OutVariable keys

Essendo sufficiente al nostro scopo la key1, per ottenere la chiave da utilizzare nel prossimo script possiamo eseguire eseguire da PowerShell:

$keys[0].key1

Siamo pronti quindi ad effettuare il deploy della nostra configurazione eseguendo uno script PowerShell DSC; per personalizzare lo script abbiamo bisogno di tenere presente le variabili relative allo storage account ed alle chiavi che permettono la lettura del file mof. Le variabili sono:

StorageAccountName (il nome dell’account archivio creato nel primo step), StorageAccountKey (La key1 restituita dal comando precedente), FileUri (Il valore restituito dopo l’upload del file mof), vmname (il nome della risorsa della macchina virtuale su Azure)

Eseguiamo il cmd-let per conoscere l’ultima versione di DSCforLinux disponibile

$extensionName ‘DSCForLinux’

$publisher ‘Microsoft.OSTCExtensions’

Get-AzureRmVMExtensionImage -PublisherName Microsoft.OSTCExtensions -Location $location -Type DSCForLinux

E settiamo la variabile version utilizzando questa versione

$version ‘2.2’

Poi settiamo le variabili relative all’autenticazione:

$privateConfig 

‘{

“StorageAccountName”: “linuxdsc”,

“StorageAccountKey”: “//storageaccountkey//”

}’

$publicConfig ‘{

“Mode”: “Push”,

“FileUri”: “//fileuri//”

}’

E finalmente lanciamo il deploy del modello che avevamo creato sulla vm Linux su Azure, avendo cura di settare la variabile $vmName indicando il nome della VM su Azure, nel mio caso:

$vmName=“LNXClient01”

Set-AzureRmVMExtension -ResourceGroupName $ResourceGroupName -VMName $vmName -Location $location -Name $extensionName -Publisher $publisher -ExtensionType $extensionName -TypeHandlerVersion $version -SettingString $publicConfig -ProtectedSettingString $privateConfig

Un messaggio di OK ci conferma l’avvenuto deploy della configurazione. In questo caso abbiamo installato il pacchetto apache2 (Webserver apache) sulla nostra macchina di test.

Nel caso si verificassero degli errori è possibile analizzare i log direttamente sulla macchina Linux; possiamo trovare informazioni dettagliate sulle operazioni relative a DSC nel file /var/log/azure/DSCForLinux/<versione>/extension.log

Per verificare il funzionamento del servizio creiamo dal portale Azure una regola di firewall all’interno delle risorse di tipo “Gruppo sicurezza di rete” per consentire le connessioni sulla porta 80 (servizio http), e proviamo ad aprire un browser navigando direttamente sull’ip pubblico della nostra macchina.

Il webserver è attivo e raggiungibile dall’esterno

Possiamo ora divertirci a provare infinite configurazioni, ricordando che DSC è in grado di effettuare tantissime operazioni sulla macchina client, fra le quali gestione di file e cartelle, installazione e rimozione di pacchetti, gestione gruppi e utenti ed esecuzione di script.

Personalmente credo che questa funzionalità abbia un potenziale davvero enorme, e sembra quasi incredibile come su una infrastruttura proprietaria Microsoft sia possibile utilizzare servizi di automazione completamente Open Source.