Esercitazione: Come usare cloud-init per personalizzare una macchina virtuale Linux in Azure al primo avvio
Si applica a: ✔️ macchine virtuali di Linux ✔️ set di scalabilità flessibili
In un'esercitazione precedente si è appreso come eseguire una connessione SSH a una macchina virtuale (VM) e come installare manualmente NGINX. Per creare macchine virtuali in modo rapido e coerente, di norma è consigliabile una qualche forma di automazione. Un approccio comune per personalizzare una macchina virtuale al primo avvio consiste nell'usare cloud-init. In questa esercitazione si apprenderà come:
- Creare un file di configurazione cloud-init
- Creare una macchina virtuale che usa un file cloud-init
- Visualizzare un'esecuzione dell'app Node.js dopo aver creato la macchina virtuale
- Usare Key Vault per archiviare in modo sicuro i certificati
- Automatizzare le distribuzioni sicure di NGINX con cloud-init
Se si sceglie di installare e usare l'interfaccia della riga di comando in locale, per questa esercitazione è necessario eseguire l'interfaccia della riga di comando di Azure versione 2.0.30 o successiva. Eseguire az --version
per trovare la versione. Se è necessario eseguire l'installazione o l'aggiornamento, vedere Installare l'interfaccia della riga di comando di Azure.
Panoramica di cloud-init
Cloud-init è un approccio diffuso per personalizzare una macchina virtuale Linux al primo avvio. Cloud-init consente di installare pacchetti e scrivere file o configurare utenti e impostazioni di sicurezza. Quando cloud-init viene eseguito durante il processo di avvio iniziale non vi sono altri passaggi o agenti necessari per applicare la configurazione.
Cloud-init funziona anche fra distribuzioni. Ad esempio, non si usa apt-get install o yum install per installare un pacchetto. In alternativa, è possibile definire un elenco di pacchetti da installare. Cloud-init userà automaticamente lo strumento di gestione del pacchetto nativo per la distribuzione selezionata.
Microsoft collabora con i partner per promuovere l'inclusione e il funzionamento di cloud-init con le immagini da essi fornite per Azure. Per informazioni dettagliate sul supporto di cloud-init per ogni distribuzione, vedere Supporto di cloud-init per le macchine virtuali in Azure.
Creare un file di configurazione cloud-init
Per visualizzare cloud-init in azione, creare una macchina virtuale, installare NGINX ed eseguire una semplice app Node.js "Hello World". La configurazione cloud-init seguente installa i pacchetti necessari, crea un'applicazione Node.js, quindi inizializza e avvia l'applicazione.
Al prompt di Bash o in Cloud Shell creare un file denominato cloud-init.txt e incollare la configurazione seguente. Ad esempio, digitare sensible-editor cloud-init.txt
per creare il file e visualizzare un elenco degli editor disponibili. Assicurarsi che l'intero file cloud-init venga copiato correttamente, in particolare la prima riga:
#cloud-config
package_upgrade: true
packages:
- nginx
- nodejs
- npm
write_files:
- owner: www-data:www-data
path: /etc/nginx/sites-available/default
defer: true
content: |
server {
listen 80;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
- owner: azureuser:azureuser
path: /home/azureuser/myapp/index.js
defer: true
content: |
var express = require('express')
var app = express()
var os = require('os');
app.get('/', function (req, res) {
res.send('Hello World from host ' + os.hostname() + '!')
})
app.listen(3000, function () {
console.log('Hello world app listening on port 3000!')
})
runcmd:
- service nginx restart
- cd "/home/azureuser/myapp"
- npm init
- npm install express -y
- nodejs index.js
Per altre informazioni sulle opzioni di configurazione di cloud-init, vedere gli esempi di configurazione di cloud-init.
Crea macchina virtuale
Per poter creare una macchina virtuale è prima necessario creare un gruppo di risorse con il comando az group create. Nell'esempio seguente viene creato un gruppo di risorse denominato myResourceGroupAutomate nella posizione eastus:
az group create --name myResourceGroupAutomate --location eastus
Creare quindi una macchina virtuale con il comando az vm create. Usare il parametro --custom-data
per specificare il file di configurazione di cloud-init. Se il file è stato salvato all'esterno della directory di lavoro corrente, specificare il percorso completo della configurazione cloud-init.txt . L'esempio seguente crea una VM denominata myVM:
az vm create \
--resource-group myResourceGroupAutomate \
--name myAutomatedVM \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data cloud-init.txt
Per creare la macchina virtuale, installare i pacchetti e avviare l'applicazione sono necessari alcuni minuti. Sono presenti attività in background la cui esecuzione continua dopo che l'interfaccia della riga di comando di Azure è tornata al prompt. Potrebbe trascorrere ancora qualche minuto prima che sia possibile accedere all'app. Dopo aver creato la macchina virtuale, prendere nota del publicIpAddress
visualizzato dall'interfaccia della riga di comando di Azure. Questo indirizzo viene usato per accedere all'app Node.js tramite un Web browser.
Per consentire al traffico Web di raggiungere la macchina virtuale, aprire la porta 80 da Internet con il comando az vm open_port:
az vm open-port --port 80 --resource-group myResourceGroupAutomate --name myAutomatedVM
Testare l'app Web
È ora possibile aprire un Web browser e immettere http://<publicIpAddress> nella barra degli indirizzi. Fornire il proprio indirizzo IP pubblico dal processo di creazione della macchina virtuale. L'app Node.js viene visualizzata come illustrato nell'esempio seguente:
Inserire certificati da Key Vault
Questa sezione facoltativa illustra come archiviare in modo protetto i certificati in Azure Key Vault e inserirli durante la distribuzione della macchina virtuale. Anziché usare un'immagine personalizzata che includa i certificati integrati, questo processo assicura che i certificati aggiornati vengano inseriti in una macchina virtuale al primo avvio. Durante il processo, il certificato non lascia mai la piattaforma Azure e non viene mai esposto in uno script, in una cronologia della riga di comando o in un modello.
Azure Key Vault consente di proteggere chiavi crittografiche e segreti, come certificati e password. Key Vault semplifica il processo di gestione delle chiavi e consente di mantenere il controllo delle chiavi che accedono ai dati e li crittografano. Questo scenario introduce alcuni concetti chiave di Key Vault per creare e usare un certificato, sebbene non rappresenti una panoramica esaustiva sull'uso di Key Vault.
I passaggi seguenti mostrano come sia possibile:
- Creare un Azure Key Vault
- Generare o caricare un certificato in Key Vault
- Creare una chiave privata dal certificato da inserire in una macchina virtuale
- Creare una macchina virtuale e inserire il certificato
Creare un Azure Key Vault
Innanzitutto, creare un Key Vault con il comando az keyvault create e abilitarlo all'uso quando si distribuisce una macchina virtuale. Ogni Key Vault deve avere un nome univoco in lettere minuscole. Nell'esempio seguente sostituire mykeyvault
con il nome univoco del proprio Key Vault:
keyvault_name=mykeyvault
az keyvault create \
--resource-group myResourceGroupAutomate \
--name $keyvault_name \
--enabled-for-deployment
Generare certificati e archiviarli in Key Vault
Per la produzione è necessario importare un certificato valido firmato da un provider attendibile con il comando az keyvault certificate import. Per questa esercitazione, l'esempio seguente illustra come sia possibile generare un certificato autofirmato con il comando az keyvault certificate create che usi i criteri dei certificati predefiniti:
az keyvault certificate create \
--vault-name $keyvault_name \
--name mycert \
--policy "$(az keyvault certificate get-default-policy --output json)"
Preparare i certificati per l'uso con macchine virtuali
Per usare il certificato durante il processo di creazione della macchina virtuale, ottenere l'ID del certificato con il comando az keyvault secret list-versions. La macchina virtuale richiede che il certificato abbia un formato specifico per inserirlo all'avvio, quindi è necessario convertire il certificato con il comando az vm secret format. L'esempio seguente assegna l'output di questi comandi a delle variabili per semplificarne l'uso nei passaggi successivi:
secret=$(az keyvault secret list-versions \
--vault-name $keyvault_name \
--name mycert \
--query "[?attributes.enabled].id" --output tsv)
vm_secret=$(az vm secret format --secret "$secret" --output json)
Creare una configurazione cloud-init per proteggere NGINX
Quando si crea una macchina virtuale, certificati e chiavi vengono archiviati nella directory /var/lib/waagent/ protetta. Per automatizzare l'aggiunta del certificato alla macchina virtuale e la configurazione di NGINX, è possibile usare una configurazione di cloud-init aggiornata dall'esempio precedente.
Creare un file denominato cloud-init-secured.txt e incollare la configurazione seguente. Se si usa Cloud Shell, creare il file di configurazione cloud-init in questa posizione e non nel computer locale. Ad esempio, digitare sensible-editor cloud-init-secured.txt
per creare il file e visualizzare un elenco degli editor disponibili. Assicurarsi che l'intero file cloud-init venga copiato correttamente, in particolare la prima riga:
#cloud-config
package_upgrade: true
packages:
- nginx
- nodejs
- npm
write_files:
- owner: www-data:www-data
path: /etc/nginx/sites-available/default
defer: true
content: |
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/mycert.cert;
ssl_certificate_key /etc/nginx/ssl/mycert.prv;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
- owner: azureuser:azureuser
path: /home/azureuser/myapp/index.js
defer: true
content: |
var express = require('express')
var app = express()
var os = require('os');
app.get('/', function (req, res) {
res.send('Hello World from host ' + os.hostname() + '!')
})
app.listen(3000, function () {
console.log('Hello world app listening on port 3000!')
})
runcmd:
- secretsname=$(find /var/lib/waagent/ -name "*.prv" | cut -c -57)
- mkdir /etc/nginx/ssl
- cp $secretsname.crt /etc/nginx/ssl/mycert.cert
- cp $secretsname.prv /etc/nginx/ssl/mycert.prv
- service nginx restart
- cd "/home/azureuser/myapp"
- npm init
- npm install express -y
- nodejs index.js
Creare una macchina virtuale protetta
Creare quindi una macchina virtuale con il comando az vm create. I dati del certificato sono inseriti da Key Vault con il parametro --secrets
. Come nell'esempio precedente, si seleziona anche la configurazione cloud-init con il parametro --custom-data
:
az vm create \
--resource-group myResourceGroupAutomate \
--name myVMWithCerts \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data cloud-init-secured.txt \
--secrets "$vm_secret"
Per creare la macchina virtuale, installare i pacchetti e avviare l'applicazione sono necessari alcuni minuti. Sono presenti attività in background la cui esecuzione continua dopo che l'interfaccia della riga di comando di Azure è tornata al prompt. Potrebbe trascorrere ancora qualche minuto prima che sia possibile accedere all'app. Dopo aver creato la macchina virtuale, prendere nota del publicIpAddress
visualizzato dall'interfaccia della riga di comando di Azure. Questo indirizzo viene usato per accedere all'app Node.js tramite un Web browser.
Per consentire al traffico Web protetto di raggiungere la macchina virtuale, aprire la porta 443 da Internet con il comando az vm open-port:
az vm open-port \
--resource-group myResourceGroupAutomate \
--name myVMWithCerts \
--port 443
Testare l'applicazione Web protetta
È ora possibile aprire un Web browser e immettere https://<publicIpAddress> nella barra degli indirizzi. Fornire il proprio indirizzo IP pubblico come illustrato nell'output del processo di creazione della macchina virtuale riportato in precedenza. Accettare l'avviso di sicurezza se è stato usato un certificato autofirmato.
Il sito protetto NGINX e la app Node.js sono visualizzati come illustrato nell'esempio seguente:
Passaggi successivi
In questa esercitazione vengono configurate macchine virtuali al primo avvio con cloud-init. Contenuto del modulo:
- Creare un file di configurazione cloud-init
- Creare una macchina virtuale che usa un file cloud-init
- Visualizzare un'esecuzione dell'app Node.js dopo aver creato la macchina virtuale
- Usare Key Vault per archiviare in modo sicuro i certificati
- Automatizzare le distribuzioni sicure di NGINX con cloud-init
Passare all'esercitazione successiva per imparare a creare immagini di macchine virtuali personalizzate.