使用 Terraform 在 Azure 中创建辐射网络

Terraform 支持云基础结构的定义、预览和部署。 使用 Terraform,可以使用 HCL 语法创建配置文件。 利用 HCL 语法,可指定 Azure 这样的云提供程序和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证了更改后,请应用该执行计划以部署基础结构。

本文将实现两个独立的分支网络以演示工作负载的分离。 网络使用中心虚拟网络共享公用资源。 辐射可以用来隔离其自己的 VNet 中的工作负荷,独立于其他辐射进行管理。 每个工作负荷可以包括多个层,并具有通过 Azure 负载均衡器连接的多个子网。

在这篇文章中,你将学会如何:

  • 在中心辐射型拓扑中实现分支 VNet
  • 在分支网络中创建虚拟机
  • 与中心网络建立虚拟网络对等互连

1.配置环境

  • Azure 订阅:如果没有 Azure 订阅,请在开始之前创建 一个免费帐户

2. 实现 Terraform 代码

此部分创建两个分支脚本。 每个脚本定义一个辐射状虚拟网络和一个用于工作负载的虚拟机。 然后创建一个从中心到分支的对等互连虚拟网络。

  1. 将本系列第一篇文章中创建的示例目录设为当前目录。

  2. 创建名为 spoke1.tf 的文件并插入下列代码:

    locals {
      spoke1-location       = "eastus"
      spoke1-resource-group = "spoke1-vnet-rg-${random_string.suffix.result}"
      prefix-spoke1         = "spoke1"
    }
    
    resource "azurerm_resource_group" "spoke1-vnet-rg" {
      name     = local.spoke1-resource-group
      location = local.spoke1-location
    }
    
    resource "azurerm_virtual_network" "spoke1-vnet" {
      name                = "spoke1-vnet"
      location            = azurerm_resource_group.spoke1-vnet-rg.location
      resource_group_name = azurerm_resource_group.spoke1-vnet-rg.name
      address_space       = ["10.1.0.0/16"]
    
      tags = {
        environment = local.prefix-spoke1
      }
    }
    
    resource "azurerm_subnet" "spoke1-mgmt" {
      name                 = "mgmt"
      resource_group_name  = azurerm_resource_group.spoke1-vnet-rg.name
      virtual_network_name = azurerm_virtual_network.spoke1-vnet.name
      address_prefixes     = ["10.1.0.64/27"]
    }
    
    resource "azurerm_subnet" "spoke1-workload" {
      name                 = "workload"
      resource_group_name  = azurerm_resource_group.spoke1-vnet-rg.name
      virtual_network_name = azurerm_virtual_network.spoke1-vnet.name
      address_prefixes     = ["10.1.1.0/24"]
    }
    
    resource "azurerm_virtual_network_peering" "spoke1-hub-peer" {
      name                      = "spoke1-hub-peer"
      resource_group_name       = azurerm_resource_group.spoke1-vnet-rg.name
      virtual_network_name      = azurerm_virtual_network.spoke1-vnet.name
      remote_virtual_network_id = azurerm_virtual_network.hub-vnet.id
    
      allow_virtual_network_access = true
      allow_forwarded_traffic      = true
      allow_gateway_transit        = false
      use_remote_gateways          = true
      depends_on                   = [azurerm_virtual_network.spoke1-vnet, azurerm_virtual_network.hub-vnet, azurerm_virtual_network_gateway.hub-vnet-gateway]
    }
    
    resource "azurerm_network_interface" "spoke1-nic" {
      name                 = "${local.prefix-spoke1}-nic"
      location             = azurerm_resource_group.spoke1-vnet-rg.location
      resource_group_name  = azurerm_resource_group.spoke1-vnet-rg.name
      enable_ip_forwarding = true
    
      ip_configuration {
        name                          = local.prefix-spoke1
        subnet_id                     = azurerm_subnet.spoke1-mgmt.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_virtual_machine" "spoke1-vm" {
      name                  = "${local.prefix-spoke1}-vm"
      location              = azurerm_resource_group.spoke1-vnet-rg.location
      resource_group_name   = azurerm_resource_group.spoke1-vnet-rg.name
      network_interface_ids = [azurerm_network_interface.spoke1-nic.id]
      vm_size               = var.vmsize
    
      storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04-LTS"
        version   = "latest"
      }
    
      storage_os_disk {
        name              = "myosdisk1"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Standard_LRS"
      }
    
      os_profile {
        computer_name  = "${local.prefix-spoke1}-vm"
        admin_username = var.username
        admin_password = local.password
      }
    
      os_profile_linux_config {
        disable_password_authentication = false
      }
    
      tags = {
        environment = local.prefix-spoke1
      }
    }
    
    resource "azurerm_virtual_network_peering" "hub-spoke1-peer" {
      name                         = "hub-spoke1-peer"
      resource_group_name          = azurerm_resource_group.hub-vnet-rg.name
      virtual_network_name         = azurerm_virtual_network.hub-vnet.name
      remote_virtual_network_id    = azurerm_virtual_network.spoke1-vnet.id
      allow_virtual_network_access = true
      allow_forwarded_traffic      = true
      allow_gateway_transit        = true
      use_remote_gateways          = false
      depends_on                   = [azurerm_virtual_network.spoke1-vnet, azurerm_virtual_network.hub-vnet, azurerm_virtual_network_gateway.hub-vnet-gateway]
    }
    
  3. 创建名为 spoke2.tf 的文件并插入下列代码:

    locals {
      spoke2-location       = "eastus"
      spoke2-resource-group = "spoke2-vnet-rg-${random_string.suffix.result}"
      prefix-spoke2         = "spoke2"
    }
    
    resource "azurerm_resource_group" "spoke2-vnet-rg" {
      name     = local.spoke2-resource-group
      location = local.spoke2-location
    }
    
    resource "azurerm_virtual_network" "spoke2-vnet" {
      name                = "${local.prefix-spoke2}-vnet"
      location            = azurerm_resource_group.spoke2-vnet-rg.location
      resource_group_name = azurerm_resource_group.spoke2-vnet-rg.name
      address_space       = ["10.2.0.0/16"]
    
      tags = {
        environment = local.prefix-spoke2
      }
    }
    
    resource "azurerm_subnet" "spoke2-mgmt" {
      name                 = "mgmt"
      resource_group_name  = azurerm_resource_group.spoke2-vnet-rg.name
      virtual_network_name = azurerm_virtual_network.spoke2-vnet.name
      address_prefixes     = ["10.2.0.64/27"]
    }
    
    resource "azurerm_subnet" "spoke2-workload" {
      name                 = "workload"
      resource_group_name  = azurerm_resource_group.spoke2-vnet-rg.name
      virtual_network_name = azurerm_virtual_network.spoke2-vnet.name
      address_prefixes     = ["10.2.1.0/24"]
    }
    
    resource "azurerm_virtual_network_peering" "spoke2-hub-peer" {
      name                      = "${local.prefix-spoke2}-hub-peer"
      resource_group_name       = azurerm_resource_group.spoke2-vnet-rg.name
      virtual_network_name      = azurerm_virtual_network.spoke2-vnet.name
      remote_virtual_network_id = azurerm_virtual_network.hub-vnet.id
    
      allow_virtual_network_access = true
      allow_forwarded_traffic      = true
      allow_gateway_transit        = false
      use_remote_gateways          = true
      depends_on                   = [azurerm_virtual_network.spoke2-vnet, azurerm_virtual_network.hub-vnet, azurerm_virtual_network_gateway.hub-vnet-gateway]
    }
    
    resource "azurerm_network_interface" "spoke2-nic" {
      name                 = "${local.prefix-spoke2}-nic"
      location             = azurerm_resource_group.spoke2-vnet-rg.location
      resource_group_name  = azurerm_resource_group.spoke2-vnet-rg.name
      enable_ip_forwarding = true
    
      ip_configuration {
        name                          = local.prefix-spoke2
        subnet_id                     = azurerm_subnet.spoke2-mgmt.id
        private_ip_address_allocation = "Dynamic"
      }
    
      tags = {
        environment = local.prefix-spoke2
      }
    }
    
    resource "azurerm_virtual_machine" "spoke2-vm" {
      name                  = "${local.prefix-spoke2}-vm"
      location              = azurerm_resource_group.spoke2-vnet-rg.location
      resource_group_name   = azurerm_resource_group.spoke2-vnet-rg.name
      network_interface_ids = [azurerm_network_interface.spoke2-nic.id]
      vm_size               = var.vmsize
    
      storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04-LTS"
        version   = "latest"
      }
    
      storage_os_disk {
        name              = "myosdisk1"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Standard_LRS"
      }
    
      os_profile {
        computer_name  = "${local.prefix-spoke2}-vm"
        admin_username = var.username
        admin_password = local.password
      }
    
      os_profile_linux_config {
        disable_password_authentication = false
      }
    
      tags = {
        environment = local.prefix-spoke2
      }
    }
    
    resource "azurerm_virtual_network_peering" "hub-spoke2-peer" {
      name                         = "hub-spoke2-peer"
      resource_group_name          = azurerm_resource_group.hub-vnet-rg.name
      virtual_network_name         = azurerm_virtual_network.hub-vnet.name
      remote_virtual_network_id    = azurerm_virtual_network.spoke2-vnet.id
      allow_virtual_network_access = true
      allow_forwarded_traffic      = true
      allow_gateway_transit        = true
      use_remote_gateways          = false
      depends_on                   = [azurerm_virtual_network.spoke2-vnet, azurerm_virtual_network.hub-vnet, azurerm_virtual_network_gateway.hub-vnet-gateway]
    }
    

Azure 上的 Terraform 故障排除

排查在 Azure 上使用 Terraform 时的常见问题

后续步骤