Guida introduttiva: Creare un gateway NAT di Azure con Terraform
Introduzione al gateway NAT di Azure con Terraform. Questo file Terraform distribuisce una rete virtuale, una risorsa gateway NAT e una macchina virtuale Ubuntu. La macchina virtuale Ubuntu viene distribuita in una subnet associata alla risorsa gateway NAT.
Lo script genera anche una chiave pubblica SSH casuale e la associa alla macchina virtuale per l'accesso sicuro. La chiave pubblica viene restituita alla fine dell'esecuzione dello script.
Lo script usa i provider Random e AzAPI oltre al provider AzureRM. Il provider casuale viene usato per generare un nome univoco per il gruppo di risorse e la chiave SSH. Il provider AzAPI viene usato per generare la chiave pubblica SSH.
Come per la chiave pubblica, i nomi del gruppo di risorse creato, della rete virtuale, della subnet e del gateway NAT vengono stampati quando viene eseguito lo script.
Terraform consente di definire, visualizzare in anteprima e distribuire l'infrastruttura cloud. Con Terraform è possibile creare file di configurazione usando la sintassi HCL. La sintassi HCL consente di specificare il provider di servizi cloud, ad esempio Azure, e gli elementi che costituiscono l'infrastruttura cloud. Dopo aver creato i file di configurazione, è necessario creare un piano di esecuzione che consenta di visualizzare in anteprima le modifiche apportate all'infrastruttura prima che vengano distribuite. Dopo aver verificato le modifiche, è possibile applicare il piano di esecuzione per distribuire l'infrastruttura.
Prerequisiti
Un account Azure con una sottoscrizione attiva. È possibile creare gratuitamente un account.
Installa e configura Terraform.
Implementare il codice Terraform
Nota
Il codice di esempio per questo articolo si trova nel repository GitHub di Azure Terraform.
Vedere altri articoli e codice di esempio che illustrano come usare Terraform per gestire le risorse di Azure
Creare una directory in cui testare ed eseguire il codice Terraform di esempio e impostarla come directory corrente.
Creare un file denominato
main.tf
e inserire il codice seguente:# Resource Group resource "azurerm_resource_group" "rg" { location = var.resource_group_location name = "${random_pet.prefix.id}-rg" } # Virtual Network resource "azurerm_virtual_network" "my_terraform_network" { name = "${random_pet.prefix.id}-vnet" address_space = ["10.0.0.0/16"] location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name } # Subnet 1 resource "azurerm_subnet" "my_terraform_subnet_1" { name = "subnet-1" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.my_terraform_network.name address_prefixes = ["10.0.0.0/24"] } # Public IP address for NAT gateway resource "azurerm_public_ip" "my_public_ip" { name = "public-ip-nat" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" } # NAT Gateway resource "azurerm_nat_gateway" "my_nat_gateway" { name = "nat-gateway" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name } # Associate NAT Gateway with Public IP resource "azurerm_nat_gateway_public_ip_association" "example" { nat_gateway_id = azurerm_nat_gateway.my_nat_gateway.id public_ip_address_id = azurerm_public_ip.my_public_ip.id } # Associate NAT Gateway with Subnet resource "azurerm_subnet_nat_gateway_association" "example" { subnet_id = azurerm_subnet.my_terraform_subnet_1.id nat_gateway_id = azurerm_nat_gateway.my_nat_gateway.id } # Create public IP for virtual machine resource "azurerm_public_ip" "my_public_ip_vm" { name = "public-ip-vm" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" } # Create Network Security Group and rule resource "azurerm_network_security_group" "my_terraform_nsg" { name = "nsg-1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name security_rule { name = "SSH" priority = 1001 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "22" source_address_prefix = "*" destination_address_prefix = "*" } } # Create network interface resource "azurerm_network_interface" "my_terraform_nic" { name = "nic-1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "my_nic_configuration" subnet_id = azurerm_subnet.my_terraform_subnet_1.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.my_public_ip_vm.id } } # Connect the security group to the network interface resource "azurerm_network_interface_security_group_association" "example" { network_interface_id = azurerm_network_interface.my_terraform_nic.id network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id } # Generate random text for a unique storage account name resource "random_id" "random_id" { keepers = { # Generate a new ID only when a new resource group is defined resource_group = azurerm_resource_group.rg.name } byte_length = 8 } # Create storage account for boot diagnostics resource "azurerm_storage_account" "my_storage_account" { name = "diag${random_id.random_id.hex}" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name account_tier = "Standard" account_replication_type = "LRS" } # Create virtual machine resource "azurerm_linux_virtual_machine" "my_terraform_vm" { name = "vm-1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name network_interface_ids = [azurerm_network_interface.my_terraform_nic.id] size = "Standard_DS1_v2" os_disk { name = "myOsDisk" caching = "ReadWrite" storage_account_type = "Premium_LRS" } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts-gen2" version = "latest" } computer_name = "hostname" admin_username = var.username admin_ssh_key { username = var.username public_key = azapi_resource_action.ssh_public_key_gen.output.publicKey } boot_diagnostics { storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint } } resource "random_pet" "prefix" { prefix = var.resource_group_name_prefix length = 1 }
Creare un file denominato
outputs.tf
e inserire il codice seguente:output "resource_group_name" { description = "The name of the created resource group." value = azurerm_resource_group.rg.name } output "virtual_network_name" { description = "The name of the created virtual network." value = azurerm_virtual_network.my_terraform_network.name } output "subnet_name_1" { description = "The name of the created subnet 1." value = azurerm_subnet.my_terraform_subnet_1.name } output "nat_gateway"{ description = "The name of the created NAT gateway." value = azurerm_nat_gateway.my_nat_gateway.id }
Creare un file denominato
providers.tf
e inserire il codice seguente:terraform { required_providers { azapi = { source = "azure/azapi" version = "~>1.5" } azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features {} }
Creare un file denominato
ssh.tf
e inserire il codice seguente:resource "random_pet" "ssh_key_name" { prefix = "ssh" separator = "" } resource "azapi_resource_action" "ssh_public_key_gen" { type = "Microsoft.Compute/sshPublicKeys@2022-11-01" resource_id = azapi_resource.ssh_public_key.id action = "generateKeyPair" method = "POST" response_export_values = ["publicKey", "privateKey"] } resource "azapi_resource" "ssh_public_key" { type = "Microsoft.Compute/sshPublicKeys@2022-11-01" name = random_pet.ssh_key_name.id location = azurerm_resource_group.rg.location parent_id = azurerm_resource_group.rg.id } output "key_data" { value = azapi_resource_action.ssh_public_key_gen.output.publicKey }
Creare un file denominato
variables.tf
e inserire il codice seguente:variable "resource_group_location" { type = string default = "eastus" description = "Location of the resource group." } variable "resource_group_name_prefix" { type = string default = "rg" description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription." } variable "username" { type = string description = "The username for the local account that will be created on the new VM." default = "azureuser" }
Inizializzare Terraform
Per inizializzare la distribuzione di Terraform, eseguire terraform init. Questo comando scarica il provider di Azure necessario per gestire le risorse di Azure.
terraform init -upgrade
Punti principali:
- Il parametro
-upgrade
aggiorna i plug-in del provider necessari alla versione più recente conforme ai vincoli di versione della configurazione.
Creare un piano di esecuzione Terraform
Eseguire terraform plan per creare un piano di esecuzione.
terraform plan -out main.tfplan
Punti principali:
- Il comando
terraform plan
consente di creare un piano di esecuzione, ma non di eseguirlo. Determina invece le azioni necessarie per creare la configurazione specificata nei file di configurazione. Questo modello consente di verificare se il piano di esecuzione corrisponde alle aspettative prima di apportare modifiche alle risorse effettive. - Il parametro
-out
facoltativo consente di specificare un file di output per il piano. L'uso del parametro-out
garantisce che il piano esaminato sia esattamente quello che viene applicato.
Applicare un piano di esecuzione Terraform
Eseguire terraform apply per applicare il piano di esecuzione all'infrastruttura cloud.
terraform apply main.tfplan
Punti principali:
- Il comando
terraform apply
di esempio presuppone che in precedenza sia stato eseguitoterraform plan -out main.tfplan
. - Se è stato specificato un nome file diverso per il parametro
-out
, usare lo stesso nome file nella chiamata aterraform apply
. - Se non è stato usato il parametro
-out
, chiamareterraform apply
senza parametri.
Verificare i risultati
- Ottenere il nome del gruppo di risorse di Azure.
resource_group_name=$(terraform output -raw resource_group_name)
- Ottenere l'ID del gateway NAT.
nat_gateway=$(terraform output -raw nat_gateway)
- Eseguire az network nat gateway show per visualizzare i dettagli sul gateway NAT.
az network nat gateway show \
--resource-group $resource_group_name \
--ids $nat_gateway
Pulire le risorse
Quando le risorse create tramite Terraform non sono più necessarie, eseguire i passaggi seguenti:
Eseguire terraform plan e specificare il flag
destroy
.terraform plan -destroy -out main.destroy.tfplan
Punti principali:
- Il comando
terraform plan
consente di creare un piano di esecuzione, ma non di eseguirlo. Determina invece le azioni necessarie per creare la configurazione specificata nei file di configurazione. Questo modello consente di verificare se il piano di esecuzione corrisponde alle aspettative prima di apportare modifiche alle risorse effettive. - Il parametro
-out
facoltativo consente di specificare un file di output per il piano. L'uso del parametro-out
garantisce che il piano esaminato sia esattamente quello che viene applicato.
- Il comando
Eseguire terraform apply per applicare il piano di esecuzione.
terraform apply main.destroy.tfplan
Risolvere i problemi di Terraform in Azure
Risolvere i problemi comuni relativi all'uso di Terraform in Azure.