Udostępnij przez


Szybki start: tworzenie obwodu usługi ExpressRoute i bramy sieci wirtualnej za pomocą programu Terraform

W tym szybkim przewodniku użyjesz narzędzia Terraform do utworzenia obwodu usługi Azure ExpressRoute oraz powiązanej infrastruktury. Szablon Terraform tworzy kompletną konfigurację ExpressRoute, w tym sieć wirtualną, bramę ExpressRoute, konfigurację obwodu i prywatne peering. Wszystkie zasoby są wdrażane z konfigurowalnymi parametrami, które umożliwiają dostosowanie wdrożenia pod kątem określonych wymagań.

Diagram środowiska wdrażania obwodu usługi Azure ExpressRoute przy użyciu narzędzia Terraform.

Narzędzie Terraform umożliwia definiowanie, wyświetlanie wersji zapoznawczej i wdrażanie infrastruktury chmury. Za pomocą narzędzia Terraform tworzysz pliki konfiguracji przy użyciu składni HCL. Składnia listy HCL umożliwia określenie dostawcy chmury — takiego jak platforma Azure — oraz elementów tworzących infrastrukturę chmury. Po utworzeniu plików konfiguracji utworzysz plan wykonywania , który umożliwia wyświetlenie podglądu zmian infrastruktury przed ich wdrożeniem. Po zweryfikowaniu zmian należy zastosować plan wykonywania w celu wdrożenia infrastruktury.

W tym artykule omówiono sposób wykonywania następujących zadań:

  • Tworzenie grupy zasobów platformy Azure o unikatowej nazwie
  • Tworzenie sieci wirtualnej z podsiecią dla bramy
  • Tworzenie bramy usługi ExpressRoute z konfigurowalnym SKU
  • Tworzenie obwodu usługi ExpressRoute z konfigurowalnymi ustawieniami dostawcy usług
  • Konfigurowanie prywatnego peeringu dla łącza ExpressRoute
  • Identyfikatory zasobów klucza wyjściowego i szczegóły konfiguracji

Wymagania wstępne

Implementowanie kodu narzędzia Terraform

  1. Utwórz katalog, w którym chcesz przetestować i uruchomić przykładowy kod programu Terraform, i ustaw go jako bieżący katalog.

  2. Utwórz plik o nazwie main.tfi wstaw następujący kod:

    # Create Resource Group
    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
      tags     = var.tags
    }
    
    # Random String for unique naming
    resource "random_string" "name" {
      length  = 8
      special = false
      upper   = false
      lower   = true
      numeric = false
    }
    
    # Create Virtual Network
    resource "azurerm_virtual_network" "vnet" {
      name                = "vnet-${random_string.name.result}"
      address_space       = var.virtual_network_address_space
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      tags                = var.tags
    }
    
    # Create ExpressRoute Gateway using Azure Verified Module with HOBO
    module "expressroute_gateway" {
      source  = "Azure/avm-ptn-vnetgateway/azurerm"
      version = "~> 0.10.0"
    
      # Basic Configuration
      location  = azurerm_resource_group.rg.location
      name      = "vgw-${random_string.name.result}"
      parent_id = azurerm_resource_group.rg.id
    
      # ExpressRoute Gateway Configuration
      type                                  = "ExpressRoute"
      sku                                   = var.gateway_sku
      hosted_on_behalf_of_public_ip_enabled = var.enable_hosted_on_behalf_of_public_ip # Enable Azure-managed public IP (HOBO)
    
      # Virtual Network Configuration
      virtual_network_id    = azurerm_virtual_network.vnet.id
      subnet_address_prefix = var.gateway_subnet_address_prefix # GatewaySubnet CIDR
    
      # Optional: Enable telemetry for Azure Verified Module
      enable_telemetry = true
    
      # Express Route Circuit Connection (if circuit is provided)
      express_route_circuits = var.express_route_circuit_id != null ? {
        "primary" = {
          id = var.express_route_circuit_id
          connection = {
            authorization_key = var.express_route_authorization_key
          }
        }
      } : {}
    
      tags = merge(var.tags, {
        environment  = "production"
        project      = "expressroute-hobo"
        gateway_type = "ExpressRoute"
        deployment   = "azure-verified-module"
      })
    
      depends_on = [azurerm_virtual_network.vnet]
    }
    
    # Create ExpressRoute Circuit (if enabled)
    resource "azurerm_express_route_circuit" "circuit" {
      count = var.create_express_route_circuit ? 1 : 0
    
      name                  = "erc-${random_string.name.result}"
      resource_group_name   = azurerm_resource_group.rg.name
      location              = azurerm_resource_group.rg.location
      service_provider_name = var.service_provider_name
      peering_location      = var.peering_location
      bandwidth_in_mbps     = var.bandwidth_in_mbps
    
      sku {
        tier   = var.circuit_sku_tier
        family = var.circuit_sku_family
      }
    
      tags = merge(var.tags, {
        environment = "production"
        project     = "expressroute-hobo"
      })
    }
    
    # Create ExpressRoute Circuit Peering (if circuit is created)
    resource "azurerm_express_route_circuit_peering" "private" {
      count = var.create_express_route_circuit && var.create_private_peering ? 1 : 0
    
      peering_type                  = "AzurePrivatePeering"
      express_route_circuit_name    = azurerm_express_route_circuit.circuit[0].name
      resource_group_name           = azurerm_resource_group.rg.name
      primary_peer_address_prefix   = var.primary_peer_address_prefix
      secondary_peer_address_prefix = var.secondary_peer_address_prefix
      vlan_id                       = var.vlan_id
      peer_asn                      = var.peer_asn
    }
    
  3. Utwórz plik o nazwie outputs.tfi wstaw następujący kod:

    output "resource_group_name" {
      description = "Name of the resource group"
      value       = azurerm_resource_group.rg.name
    }
    
    output "express_route_circuit_id" {
      description = "ID of the ExpressRoute circuit (if created)"
      value       = var.create_express_route_circuit ? azurerm_express_route_circuit.circuit[0].id : null
    }
    
    output "express_route_circuit_service_key" {
      description = "Service key for the ExpressRoute circuit (if created)"
      value       = var.create_express_route_circuit ? azurerm_express_route_circuit.circuit[0].service_key : null
      sensitive   = true
    }
    
    output "gateway_id" {
      description = "ID of the ExpressRoute Virtual Network Gateway"
      value       = module.expressroute_gateway.virtual_network_gateway.id
    }
    
    output "gateway_name" {
      description = "Name of the ExpressRoute Virtual Network Gateway"
      value       = module.expressroute_gateway.virtual_network_gateway.name
    }
    
    output "gateway_subnet_id" {
      description = "ID of the GatewaySubnet created by the module"
      value       = module.expressroute_gateway.subnet.id
    }
    
    output "hosted_on_behalf_of_public_ip_note" {
      description = "Information about the Azure-managed public IP for ExpressRoute gateway"
      value       = "This ExpressRoute Virtual Network Gateway uses an Azure-managed public IP address. The public IP is automatically provisioned and managed by Azure, and is not visible in your subscription's public IP resources. This feature is only available for ExpressRoute gateways, not VPN gateways."
    }
    
    output "public_ip_addresses" {
      description = "Public IP addresses created by the module (empty when using HOBO for ExpressRoute)"
      value       = module.expressroute_gateway.public_ip_addresses
    }
    
    output "virtual_network_id" {
      description = "ID of the virtual network"
      value       = azurerm_virtual_network.vnet.id
    }
    
    output "virtual_network_gateway_connections" {
      description = "Virtual Network Gateway Connections created by the module"
      value       = module.expressroute_gateway.virtual_network_gateway_connections
    }
    
  4. Utwórz plik o nazwie providers.tfi wstaw następujący kod:

    terraform {
      required_version = ">= 1.3"
    
      required_providers {
        azapi = {
          source  = "Azure/azapi"
          version = "~> 2.4"
        }
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~> 4.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~> 3.5"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  5. Utwórz plik o nazwie variables.tfi wstaw następujący kod:

    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 "tags" {
      type        = map(string)
      default     = {}
      description = "A map of tags to assign to all resources."
    }
    
    # Virtual Network Configuration
    variable "virtual_network_address_space" {
      type        = list(string)
      default     = ["10.0.0.0/16"]
      description = "The address space that is used by the virtual network."
    
      validation {
        condition     = length(var.virtual_network_address_space) > 0
        error_message = "At least one address space must be provided."
      }
    }
    
    variable "gateway_subnet_address_prefix" {
      type        = string
      default     = "10.0.0.0/24"
      description = "The address prefix for the GatewaySubnet. Must be at least /29."
    
      validation {
        condition     = can(cidrhost(var.gateway_subnet_address_prefix, 0)) && tonumber(split("/", var.gateway_subnet_address_prefix)[1]) <= 29
        error_message = "gateway_subnet_address_prefix must be a valid CIDR block with at least /29 prefix."
      }
    }
    
    # ExpressRoute Gateway Configuration
    variable "gateway_sku" {
      type        = string
      default     = "ErGw1AZ"
      description = "The SKU of the ExpressRoute Virtual Network Gateway. Valid values: ErGw1AZ, ErGw2AZ, ErGw3AZ, ErGwScale, HighPerformance, Standard, UltraPerformance."
    
      validation {
        condition     = contains(["ErGw1AZ", "ErGw2AZ", "ErGw3AZ", "ErGwScale", "HighPerformance", "Standard", "UltraPerformance"], var.gateway_sku)
        error_message = "gateway_sku must be one of: ErGw1AZ, ErGw2AZ, ErGw3AZ, ErGwScale, HighPerformance, Standard, UltraPerformance."
      }
    }
    
    variable "enable_hosted_on_behalf_of_public_ip" {
      type        = bool
      default     = true
      description = "Enable Azure-managed public IP for the ExpressRoute gateway (HOBO feature). When enabled, Azure manages the public IP internally and it won't appear in your subscription."
    }
    
    # ExpressRoute Circuit Configuration
    variable "create_express_route_circuit" {
      type        = bool
      default     = true
      description = "Whether to create an ExpressRoute circuit. Set to false if you want to connect to an existing circuit."
    }
    
    variable "express_route_circuit_id" {
      type        = string
      default     = null
      description = "ID of an existing ExpressRoute circuit to connect to. Only used if create_express_route_circuit is false."
    }
    
    variable "express_route_authorization_key" {
      type        = string
      default     = null
      description = "Authorization key for connecting to an existing ExpressRoute circuit."
      sensitive   = true
    }
    
    variable "service_provider_name" {
      type        = string
      default     = "Equinix"
      description = "The name of the ExpressRoute circuit service provider."
    }
    
    variable "peering_location" {
      type        = string
      default     = "Washington DC"
      description = "The name of the peering location and not the Azure resource location."
    }
    
    variable "bandwidth_in_mbps" {
      type        = number
      default     = 50
      description = "The bandwidth in Mbps of the ExpressRoute circuit."
    
      validation {
        condition     = contains([50, 100, 200, 500, 1000, 2000, 5000, 10000], var.bandwidth_in_mbps)
        error_message = "bandwidth_in_mbps must be one of: 50, 100, 200, 500, 1000, 2000, 5000, 10000."
      }
    }
    
    variable "circuit_sku_tier" {
      type        = string
      default     = "Standard"
      description = "The service tier of the ExpressRoute circuit SKU."
    
      validation {
        condition     = contains(["Basic", "Local", "Standard", "Premium"], var.circuit_sku_tier)
        error_message = "circuit_sku_tier must be one of: Basic, Local, Standard, Premium."
      }
    }
    
    variable "circuit_sku_family" {
      type        = string
      default     = "MeteredData"
      description = "The billing mode for the ExpressRoute circuit SKU."
    
      validation {
        condition     = contains(["MeteredData", "UnlimitedData"], var.circuit_sku_family)
        error_message = "circuit_sku_family must be either MeteredData or UnlimitedData."
      }
    }
    
    # ExpressRoute Private Peering Configuration
    variable "create_private_peering" {
      type        = bool
      default     = true
      description = "Whether to create Azure Private Peering for the ExpressRoute circuit."
    }
    
    variable "primary_peer_address_prefix" {
      type        = string
      default     = "192.168.10.16/30"
      description = "A /30 subnet for the primary link."
    
      validation {
        condition     = can(cidrhost(var.primary_peer_address_prefix, 0))
        error_message = "primary_peer_address_prefix must be a valid CIDR block."
      }
    }
    
    variable "secondary_peer_address_prefix" {
      type        = string
      default     = "192.168.10.20/30"
      description = "A /30 subnet for the secondary link."
    
      validation {
        condition     = can(cidrhost(var.secondary_peer_address_prefix, 0))
        error_message = "secondary_peer_address_prefix must be a valid CIDR block."
      }
    }
    
    variable "vlan_id" {
      type        = number
      default     = 200
      description = "A valid VLAN ID to establish this peering on."
    
      validation {
        condition     = var.vlan_id >= 1 && var.vlan_id <= 4094
        error_message = "vlan_id must be between 1 and 4094."
      }
    }
    
    variable "peer_asn" {
      type        = number
      default     = 65001
      description = "A valid private ASN for the customer side BGP session."
    
      validation {
        condition     = (var.peer_asn >= 64512 && var.peer_asn <= 65534) || (var.peer_asn >= 4200000000 && var.peer_asn <= 4294967294)
        error_message = "peer_asn must be a valid private ASN (64512-65534 or 4200000000-4294967294)."
      }
    }
    

Inicjowanie narzędzia Terraform

Uruchom narzędzie terraform init, aby zainicjować wdrożenie narzędzia Terraform. To polecenie pobiera dostawcę platformy Azure wymaganego do zarządzania zasobami platformy Azure.

terraform init -upgrade

Kluczowe punkty:

  • Parametr -upgrade uaktualnia niezbędne wtyczki dostawcy do najnowszej wersji, która jest zgodna z ograniczeniami wersji konfiguracji.

Tworzenie planu wykonania programu Terraform

Uruchom terraform plan, aby utworzyć plan wykonania.

terraform plan -out main.tfplan

Kluczowe punkty:

  • Polecenie terraform plan tworzy plan wykonania, ale nie wykonuje go. Zamiast tego określa, jakie akcje są niezbędne do utworzenia konfiguracji określonej w plikach konfiguracji. Ten wzorzec umożliwia sprawdzenie, czy plan wykonania jest zgodny z oczekiwaniami przed wprowadzeniem jakichkolwiek zmian w rzeczywistych zasobach.
  • Opcjonalny -out parametr umożliwia określenie pliku wyjściowego dla planu. Użycie parametru -out gwarantuje, że sprawdzony plan jest dokładnie tym, co jest stosowane.

Stosowanie planu wykonywania narzędzia Terraform

Uruchom terraform apply, aby zastosować plan wykonania w swojej infrastrukturze chmurowej.

terraform apply main.tfplan

Kluczowe punkty:

  • Przykładowe terraform apply polecenie zakłada, że wcześniej uruchomiono terraform plan -out main.tfplanpolecenie .
  • Jeśli określono inną nazwę pliku parametru -out , użyj tej samej nazwy pliku w wywołaniu metody terraform apply.
  • Jeśli parametr nie został użyty, wywołaj metodę -outterraform apply bez żadnych parametrów.

Weryfikowanie wyników

  1. Pobierz nazwę grupy zasobów platformy Azure.

    resource_group_name=$(terraform output -raw resource_group_name)
    
  2. Pobierz nazwę obwodu usługi ExpressRoute.

    circuit_name=$(terraform output -raw expressroute_circuit_name)
    
  3. Pobierz nazwę bramy.

    gateway_name=$(terraform output -raw gateway_name)
    
  4. Uruchom polecenie az network express-route show , aby wyświetlić obwód usługi ExpressRoute.

    az network express-route show --name $circuit_name --resource-group $resource_group_name
    
  5. Uruchom polecenie az network vnet-gateway show , aby wyświetlić bramę sieci wirtualnej platformy Azure.

    az network vnet-gateway show --name $gateway_name --resource-group $resource_group_name
    

Czyszczenie zasobów

Jeśli zasoby utworzone za pomocą narzędzia Terraform nie są już potrzebne, wykonaj następujące czynności:

  1. Uruchom terraform plan i określ flagę destroy.

    terraform plan -destroy -out main.destroy.tfplan
    

    Kluczowe punkty:

    • Polecenie terraform plan tworzy plan wykonania, ale nie wykonuje go. Zamiast tego określa, jakie akcje są niezbędne do utworzenia konfiguracji określonej w plikach konfiguracji. Ten wzorzec umożliwia sprawdzenie, czy plan wykonania jest zgodny z oczekiwaniami przed wprowadzeniem jakichkolwiek zmian w rzeczywistych zasobach.
    • Opcjonalny -out parametr umożliwia określenie pliku wyjściowego dla planu. Użycie parametru -out gwarantuje, że sprawdzony plan jest dokładnie tym, co jest stosowane.
  2. Uruchom terraform apply, aby zastosować plan wykonania.

    terraform apply main.destroy.tfplan
    

Rozwiązywanie problemów z programem Terraform na platformie Azure

Rozwiązywanie typowych problemów podczas korzystania z programu Terraform na platformie Azure.

Następne kroki

Zobacz więcej artykułów na temat bramy sieci wirtualnej platformy Azure.

Aby dowiedzieć się, jak połączyć sieć wirtualną z obwodem, przejdź do samouczków usługi ExpressRoute.