Schnellstart: Erstellen eines Azure NAT Gateway mithilfe von Terraform

Erste Schritte mit Azure NAT Gateway mithilfe von Terraform. Mit dieser Terraform-Datei werden ein virtuelles Netzwerk, eine NAT-Gatewayressource und eine Ubuntu-VM bereitgestellt. Der virtuelle Ubuntu-Computer wird in einem Subnetz bereitgestellt, das der NAT-Gatewayressource zugeordnet ist.

Das Skript generiert auch einen zufälligen öffentlichen SSH-Schlüssel und ordnet ihn der VM für den sicheren Zugriff zu. Der öffentliche Schlüssel wird am Ende der Skriptausführung ausgegeben.

Das Skript verwendet zusätzlich zum AzureRM-Anbieter die Anbieter Random und AzAPI. Der Zufallsanbieter wird verwendet, um einen eindeutigen Namen für die Ressourcengruppe und den SSH-Schlüssel zu generieren. Der AzAPI-Anbieter wird verwendet, um den öffentlichen SSH-Schlüssel zu generieren.

Wie bei dem öffentlichen Schlüssel werden die Namen der erstellten Ressourcengruppe, des virtuellen Netzwerks, des Subnetzs und des NAT-Gateways gedruckt, wenn das Skript ausgeführt wird.

Mit Terraform können Sie eine Cloudinfrastruktur definieren, eine Vorschau der Cloudinfrastruktur anzeigen und die Cloudinfrastruktur bereitstellen. Terraform ermöglicht das Erstellen von Konfigurationsdateien mit HCL-Syntax. Mit der HCL-Syntax können Sie den Cloudanbieter (beispielsweise Azure) und die Elemente angeben, aus denen sich Ihre Cloudinfrastruktur zusammensetzt. Nach der Erstellung Ihrer Konfigurationsdateien erstellen Sie einen Ausführungsplan, mit dem Sie eine Vorschau Ihrer Infrastrukturänderungen anzeigen können, bevor diese bereitgestellt werden. Nach der Überprüfung der Änderungen wenden Sie den Ausführungsplan an, um die Infrastruktur bereitzustellen.

Diagramm von Ressourcen, die im Schnellstart „NAT-Gateway“ erstellt wurden.

Voraussetzungen

Implementieren des Terraform-Codes

Hinweis

Der Beispielcode für diesen Artikel befindet sich im Azure Terraform-GitHub-Repository.

Betrachten Sie die weiteren Artikel und Beispielcodes zur Verwendung von Terraform zum Verwalten von Azure-Ressourcen.

  1. Erstellen Sie ein Verzeichnis, in dem der Terraform-Beispielcode getestet und ausgeführt werden soll, und legen Sie es als aktuelles Verzeichnis fest.

  2. Erstellen Sie eine Datei namens main.tf, und fügen Sie den folgenden Code ein:

    # 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 = jsondecode(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
    }
    
  3. Erstellen Sie eine Datei namens outputs.tf, und fügen Sie den folgenden Code ein:

    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
    }
    
  4. Erstellen Sie eine Datei namens providers.tf, und fügen Sie den folgenden Code ein:

    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 {}
    }
    
  5. Erstellen Sie eine Datei namens ssh.tf, und fügen Sie den folgenden Code ein:

    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 = jsondecode(azapi_resource_action.ssh_public_key_gen.output).publicKey
    }
    
  6. Erstellen Sie eine Datei namens variables.tf, und fügen Sie den folgenden Code ein:

    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"
    }
    

Initialisieren von Terraform

Führen Sie zum Initialisieren der Terraform-Bereitstellung terraform init aus. Mit diesem Befehl wird der Azure-Anbieter heruntergeladen, der zum Verwalten Ihrer Azure-Ressourcen erforderlich ist.

terraform init -upgrade

Die wichtigsten Punkte:

  • Der Parameter -upgrade aktualisiert die erforderlichen Anbieter-Plug-Ins auf die neueste Version, die den Versionseinschränkungen der Konfiguration entspricht.

Erstellen eines Terraform-Ausführungsplans

Führen Sie terraform plan aus, um einen Ausführungsplan zu erstellen.

terraform plan -out main.tfplan

Die wichtigsten Punkte:

  • Durch den Befehl terraform plan wird ein Ausführungsplan erstellt, aber nicht ausgeführt. Stattdessen werden die Aktionen ermittelt, die erforderlich sind, um die in Ihren Konfigurationsdateien angegebene Konfiguration zu erstellen. Mit diesem Muster können Sie überprüfen, ob der Ausführungsplan Ihren Erwartungen entspricht, bevor Sie Änderungen an den eigentlichen Ressourcen vornehmen.
  • Der optionale Parameter -out ermöglicht die Angabe einer Ausgabedatei für den Plan. Durch die Verwendung des Parameters -out wird sichergestellt, dass genau der von Ihnen überprüfte Plan angewendet wird.

Anwenden eines Terraform-Ausführungsplans

Führen Sie terraform apply aus, um den Ausführungsplan auf Ihre Cloudinfrastruktur anzuwenden.

terraform apply main.tfplan

Die wichtigsten Punkte:

  • Der Beispielbefehl terraform apply setzt voraus, dass Sie zuvor terraform plan -out main.tfplan ausgeführt haben.
  • Wenn Sie einen anderen Dateinamen für den Parameter -out angegeben haben, verwenden Sie denselben Dateinamen im Aufruf von terraform apply.
  • Wenn Sie den Parameter -out nicht verwendet haben, rufen Sie terraform apply ohne Parameter auf.

Überprüfen der Ergebnisse

  1. Rufen Sie den Namen der Azure-Ressourcengruppe ab.
resource_group_name=$(terraform output -raw resource_group_name)
  1. Rufen Sie das NAT Gateway auf.
    nat_gateway=$(terraform output -raw nat_gateway)
  1. Führen Sie az network nat gateway show, um Details zum NAT-Gateway anzuzeigen.
az network nat gateway show \
    --resource-group $resource_group_name \
    --ids $nat_gateway

Bereinigen von Ressourcen

Wenn Sie die über Terraform erstellten Ressourcen nicht mehr benötigen, führen Sie die folgenden Schritte aus:

  1. Führen Sie terraform plan aus, und geben Sie das Flag destroy an.

    terraform plan -destroy -out main.destroy.tfplan
    

    Die wichtigsten Punkte:

    • Durch den Befehl terraform plan wird ein Ausführungsplan erstellt, aber nicht ausgeführt. Stattdessen werden die Aktionen ermittelt, die erforderlich sind, um die in Ihren Konfigurationsdateien angegebene Konfiguration zu erstellen. Mit diesem Muster können Sie überprüfen, ob der Ausführungsplan Ihren Erwartungen entspricht, bevor Sie Änderungen an den eigentlichen Ressourcen vornehmen.
    • Der optionale Parameter -out ermöglicht die Angabe einer Ausgabedatei für den Plan. Durch die Verwendung des Parameters -out wird sichergestellt, dass genau der von Ihnen überprüfte Plan angewendet wird.
  2. Führen Sie zum Anwenden des Ausführungsplans den Befehl terraform apply aus.

    terraform apply main.destroy.tfplan
    

Problembehandlung für Terraform in Azure

Behandeln Sie allgemeine Probleme bei der Verwendung von Terraform in Azure.

Nächste Schritte