Azure Bastion in una Landing Zone Azure con Terraform: accesso amministrativo sicuro senza IP pubblici

Azure Bastion fornisce accesso RDP e SSH alle macchine virtuali direttamente dal portale Azure, senza necessita’ di assegnare IP pubblici alle VM ne’ di esporre le porte 3389 e 22 verso Internet. Collocato nell’hub di una topologia hub & spoke, un’unica istanza di Bastion serve le VM di tutti gli spoke grazie al peering, con notevole risparmio rispetto a un’istanza per spoke.

Questa guida descrive il deployment con Terraform di Azure Bastion Standard tramite gli Azure Verified Modules (AVM), nel resource group rg-hub-itn (subscription Connectivity, region Italy North). Presuppone la Hub Virtual Network gia’ deployata con la subnet AzureBastionSubnet.

Cos’è Bastion e perché implementarlo

Per amministrare una macchina virtuale (aprire il desktop remoto su Windows con RDP, o una sessione a riga di comando su Linux con SSH) serve raggiungerla dalla rete. Il modo tradizionale, ma pericoloso, e’ assegnare alla VM un indirizzo IP pubblico e aprire le porte di gestione (3389 per RDP, 22 per SSH) verso Internet. Quelle porte esposte sono pero’ uno dei bersagli piu’ attaccati in assoluto: bot e attaccanti le scandagliano in continuazione cercando password deboli.

Azure Bastion risolve il problema facendo da ponte sicuro. E’ un servizio gestito che vive nell’hub e permette di connettersi alle VM direttamente dal portale Azure, attraverso il browser. Le macchine non hanno bisogno di alcun IP pubblico e le porte di gestione restano chiuse verso Internet: la connessione avviene tutta all’interno della rete Azure, in modo cifrato e tracciato.

I motivi principali per implementare Bastion sono:

  • Nessun IP pubblico sulle VM – si elimina la superficie di attacco piu’ comune, perche’ le macchine non sono raggiungibili da Internet.
  • Porte di gestione chiuse – RDP e SSH non sono mai esposti verso l’esterno, azzerando il rischio di attacchi di forza bruta su quelle porte.
  • Accesso semplice e controllato – la connessione parte dal portale con le normali credenziali Azure, quindi si applicano autenticazione e permessi centralizzati.
  • Un’unica istanza per tutti – collocato nell’hub, un solo Bastion serve le VM di tutti gli spoke grazie al peering, senza doverne installare uno per ogni rete.

Prerequisito: la subnet AzureBastionSubnet

Azure Bastion richiede una subnet dedicata denominata esattamente AzureBastionSubnet, con prefisso di almeno /26. Nel piano di indirizzamento dell’hub questa subnet e’ 10.0.0.64/26 ed e’ definita in network.tf. Il nome e’ case-sensitive e non modificabile.

ATTENZIONE: Se la subnet non si chiama esattamente AzureBastionSubnet o e’ piu’ piccola di /26, il deployment di Bastion fallisce. La subnet non deve contenere altre risorse.

Passo 1: L’host Azure Bastion

Bastion e’ creato con il modulo AVM avm-res-network-bastionhost in SKU Standard. Lo SKU Standard aggiunge rispetto al Basic funzionalita’ come copia-incolla file, IP connect, tunneling nativo e scaling automatico. L’host e’ distribuito sulle availability zones 1, 2, 3 per l’alta disponibilita’.

Il modulo crea automaticamente l’indirizzo IP pubblico Standard necessario (pip-bas-hub-itn) tramite il flag create_public_ip, collegandolo alla AzureBastionSubnet. Il file completo bastion.tf:

Passo 2: L’output del bastion

Il file outputs.tf espone il resource ID dell’host, utile per riferimenti in altri moduli o per verifiche.

Passo 3: Applicare e verificare

Dopo terraform init, applicare il piano. Il provisioning di Bastion richiede tipicamente diversi minuti.

ATTENZIONE: Azure Bastion Standard comporta un costo orario fisso piu’ un costo per le unita’ di scaling, indipendentemente dall’utilizzo. In ambienti non produttivi valutare lo SKU Basic o lo spegnimento quando non necessario.

Al termine, aprire rg-hub-itn nel portale e verificare la presenza di bas-hub-itn (Bastion) e del relativo Public IP pip-bas-hub-itn.

Figura 1: il contenuto di rg-hub-itn: si riconoscono bas-hub-itn (Bastion) e il Public IP pip-bas-hub-itn.

Verifica del deployment

Il deployment di Bastion e’ completo quando:

  • bas-hub-itn e’ in stato Succeeded con SKU Standard e zone 1/2/3.
  • pip-bas-hub-itn e’ associato all’host.
  • Dal portale, selezionando una VM di uno spoke in peering, e’ disponibile il pulsante Connect > Bastion.

COMPLETATO: Azure Bastion e’ operativo nell’hub. Le VM degli spoke sono raggiungibili in RDP/SSH dal portale senza IP pubblici ne’ porte di gestione esposte a Internet.

Conclusioni

Abbiamo deployato Azure Bastion Standard nell’hub, con IP pubblico gestito automaticamente dal modulo e distribuzione su tre zone di disponibilita’. Centralizzarlo nell’hub e’ la scelta che massimizza il risparmio, servendo tutti gli spoke con un’unica istanza.

NOTA: Come evoluzione, valutare l’abilitazione delle funzionalita’ Standard aggiuntive come il native client support per connessioni via Azure CLI, e definire policy RBAC per limitare chi puo’ usare Bastion verso le VM sensibili.