Início Rápido: criar uma topologia de rede em malha com o Gerenciador de Rede Virtual do Azure usando o Terraform

Comece a usar o Gerenciador de Rede Virtual do Azure usando o Terraform para provisionar a conectividade para todas as suas redes virtuais.

Neste início rápido, você implanta três redes virtuais e usa o Gerenciador de Rede Virtual do Azure para criar uma topologia de rede em malha. Em seguida, verifique se a configuração de conectividade foi aplicada. Você pode escolher entre uma implantação com um escopo de assinatura ou um escopo de grupo de gerenciamento. Saiba mais sobre escopos do gerenciador de rede.

Importante

O Gerenciador de Rede Virtual do Azure está em disponibilidade geral para o Gerenciamento de Redes Virtuais, configurações de conectividade do tipo hub e spoke e configurações de segurança com regras de administração de segurança. As configurações de conectividade de malha permanecem em versão prévia pública.

Essa versão prévia é fornecida sem um contrato de nível de serviço e não é recomendada para cargas de trabalho de produção. Alguns recursos podem não ter suporte ou podem ter restrição de recursos. Para obter mais informações, consulte Termos de Uso Complementares de Versões Prévias do Microsoft Azure.

O Terraform permite a definição, a visualização e a implantação da infraestrutura de nuvem. Usando o Terraform, você cria arquivos de configuração usando sintaxe de HCL. A sintaxe da HCL permite que você especifique o provedor de nuvem, como o Azure, e os elementos que compõem sua infraestrutura de nuvem. Depois de criar os arquivos de configuração, você cria um plano de execução que permite visualizar as alterações de infraestrutura antes de serem implantadas. Depois de verificar as alterações, aplique o plano de execução para implantar a infraestrutura.

Neste artigo, você aprenderá como:

Pré-requisitos

Implementar o código do Terraform

Este exemplo de código implementará o Gerenciador de Rede Virtual do Azure no escopo da assinatura.

  1. Crie um diretório no qual testar e executar o código de exemplo do Terraform e faça dele o diretório atual.

  2. Crie um arquivo chamado providers.tf e insira o seguinte código:

    terraform {
      required_version = ">=1.0"
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = ">= 3.56.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    provider "azurerm" {
      features {}
    }
    
  3. Crie um arquivo chamado main.tf e insira o seguinte código:

    
    # Create the 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
    }
    
    # Create three virtual networks
    resource "random_string" "prefix" {
      length = 4
      special = false
      upper = false
    }
    
    resource "random_pet" "virtual_network_name" {
      prefix = "vnet-${random_string.prefix.result}"
    }
    resource "azurerm_virtual_network" "vnet" {
      count = 3
    
      name                = "${random_pet.virtual_network_name.id}-0${count.index}"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      address_space       = ["10.${count.index}.0.0/16"]
    }
    
    # Add a subnet to each virtual network
    
    resource "azurerm_subnet" "subnet_vnet" {
      count = 3
    
      name                 = "default"
      virtual_network_name = azurerm_virtual_network.vnet[count.index].name
      resource_group_name  = azurerm_resource_group.rg.name
      address_prefixes     = ["10.${count.index}.0.0/24"]
    }
    
    # Create a Virtual Network Manager instance
    
    data "azurerm_subscription" "current" {
    }
    
    resource "azurerm_network_manager" "network_manager_instance" {
      name                = "network-manager"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      scope_accesses      = ["Connectivity"]
      description         = "example network manager"
      scope {
        subscription_ids = [data.azurerm_subscription.current.id]
      }
    }
    
    # Create a network group
    
    resource "azurerm_network_manager_network_group" "network_group" {
      name               = "network-group"
      network_manager_id = azurerm_network_manager.network_manager_instance.id
    }
    
    # Add three virtual networks to a network group as dynamic members with Azure Policy
    
    resource "random_pet" "network_group_policy_name" {
      prefix = "network-group-policy"
    }
    
    resource "azurerm_policy_definition" "network_group_policy" {
      name         = "${random_pet.network_group_policy_name.id}"
      policy_type  = "Custom"
      mode         = "Microsoft.Network.Data"
      display_name = "Policy Definition for Network Group"
    
      metadata = <<METADATA
        {
          "category": "Azure Virtual Network Manager"
        }
      METADATA
    
      policy_rule = <<POLICY_RULE
        {
          "if": {
            "allOf": [
              {
                  "field": "type",
                  "equals": "Microsoft.Network/virtualNetworks"
              },
              {
                "allOf": [
                  {
                  "field": "Name",
                  "contains": "${random_pet.virtual_network_name.id}"
                  }
                ]
              }
            ]
          },
          "then": {
            "effect": "addToNetworkGroup",
            "details": {
              "networkGroupId": "${azurerm_network_manager_network_group.network_group.id}"
            }
          }
        }
      POLICY_RULE
    }
    
    resource "azurerm_subscription_policy_assignment" "azure_policy_assignment" {
      name                 = "${random_pet.network_group_policy_name.id}-policy-assignment"
      policy_definition_id = azurerm_policy_definition.network_group_policy.id
      subscription_id      = data.azurerm_subscription.current.id
    }
    
    # Create a connectivity configuration
    
    resource "azurerm_network_manager_connectivity_configuration" "connectivity_config" {
      name                  = "connectivity-config"
      network_manager_id    = azurerm_network_manager.network_manager_instance.id
      connectivity_topology = "Mesh"
      applies_to_group {
        group_connectivity = "None"
        network_group_id   = azurerm_network_manager_network_group.network_group.id
      }
    }
    
    
    # Commit deployment
    
    resource "azurerm_network_manager_deployment" "commit_deployment" {
      network_manager_id = azurerm_network_manager.network_manager_instance.id
      location           = azurerm_resource_group.rg.location
      scope_access       = "Connectivity"
      configuration_ids  = [azurerm_network_manager_connectivity_configuration.connectivity_config.id]
    }
    
  4. Crie um arquivo chamado variables.tf e insira o seguinte código:

    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
      default     = "rg"
    }
    
  5. Crie um arquivo chamado outputs.tf e insira o seguinte código:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "virtual_network_names" {
      value = azurerm_virtual_network.vnet[*].name
    }
    

Implementar o código do Terraform

Este exemplo de código implementará o Gerenciador de Rede Virtual do Azure no escopo do grupo de gerenciamento.

  1. Crie um diretório no qual testar e executar o código de exemplo do Terraform e faça dele o diretório atual.

  2. Crie um arquivo chamado providers.tf e insira o seguinte código:

    terraform {
      required_version = ">=1.0"
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~> 3.56.0, < 4.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    provider "azurerm" {
      features {}
    }
    
  3. Crie um arquivo chamado main.tf e insira o seguinte código:

    # Create the 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
    }
    
    # Create three virtual networks
    resource "random_string" "prefix" {
      length  = 4
      special = false
      upper   = false
    }
    
    resource "random_pet" "virtual_network_name" {
      prefix = "vnet-${random_string.prefix.result}"
    }
    resource "azurerm_virtual_network" "vnet" {
      count = 3
    
      name                = "${random_pet.virtual_network_name.id}-0${count.index}"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      address_space       = ["10.${count.index}.0.0/16"]
    }
    
    # Add a subnet to each virtual network
    
    resource "azurerm_subnet" "subnet_vnet" {
      count = 3
    
      name                 = "default"
      virtual_network_name = azurerm_virtual_network.vnet[count.index].name
      resource_group_name  = azurerm_resource_group.rg.name
      address_prefixes     = ["10.${count.index}.0.0/24"]
    }
    
    data "azurerm_subscription" "current" {
    }
    
    # Create a Management Group
    
    resource "random_pet" "management_group_name" {
      prefix = "AVNM-management-group"
    }
    
    resource "azurerm_management_group" "mg" {
      display_name = random_pet.management_group_name.id
    
      subscription_ids = [
        data.azurerm_subscription.current.subscription_id,
      ]
    }
    
    data "azurerm_client_config" "this" {}
    
    resource "azurerm_role_assignment" "management_group_owner" {
      principal_id         = coalesce(var.msi_id, data.azurerm_client_config.this.object_id)
      scope                = azurerm_management_group.mg.id
      role_definition_name = "Contributor"
    }
    
    # register Microsoft.Network to the Management Group
    
    resource "null_resource" "register_rp_to_mg" {
      provisioner "local-exec" {
        command = "az provider register --namespace Microsoft.Network -m ${azurerm_management_group.mg.name}"
      }
      depends_on = [azurerm_role_assignment.management_group_owner]
    }
    
    resource "time_sleep" "wait_5_seconds" {
      create_duration = "5s"
      depends_on      = [null_resource.register_rp_to_mg]
    }
    
    # Create a Virtual Network Manager instance
    
    resource "azurerm_network_manager" "network_manager_instance" {
      name                = "network-manager"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      scope_accesses      = ["Connectivity"]
      description         = "example network manager"
      scope {
        management_group_ids = [azurerm_management_group.mg.id]
      }
      depends_on = [time_sleep.wait_5_seconds]
    }
    
    # Create a network group
    
    resource "azurerm_network_manager_network_group" "network_group" {
      name               = "network-group"
      network_manager_id = azurerm_network_manager.network_manager_instance.id
    }
    
    # Add three virtual networks to a network group as dynamic members with Azure Policy
    
    resource "random_pet" "network_group_policy_name" {
      prefix = "network-group-policy"
    }
    
    resource "azurerm_policy_definition" "network_group_policy" {
      name         = random_pet.network_group_policy_name.id
      policy_type  = "Custom"
      mode         = "Microsoft.Network.Data"
      display_name = "Policy Definition for Network Group"
    
      metadata = <<METADATA
        {
          "category": "Azure Virtual Network Manager"
        }
      METADATA
    
      policy_rule = <<POLICY_RULE
        {
          "if": {
            "allOf": [
              {
                  "field": "type",
                  "equals": "Microsoft.Network/virtualNetworks"
              },
              {
                "allOf": [
                  {
                  "field": "Name",
                  "contains": "${random_pet.virtual_network_name.id}"
                  }
                ]
              }
            ]
          },
          "then": {
            "effect": "addToNetworkGroup",
            "details": {
              "networkGroupId": "${azurerm_network_manager_network_group.network_group.id}"
            }
          }
        }
      POLICY_RULE
    }
    
    resource "azurerm_subscription_policy_assignment" "azure_policy_assignment" {
      name                 = "${random_pet.network_group_policy_name.id}-policy-assignment"
      policy_definition_id = azurerm_policy_definition.network_group_policy.id
      subscription_id      = data.azurerm_subscription.current.id
    }
    
    # Create a connectivity configuration
    
    resource "azurerm_network_manager_connectivity_configuration" "connectivity_config" {
      name                  = "connectivity-config"
      network_manager_id    = azurerm_network_manager.network_manager_instance.id
      connectivity_topology = "Mesh"
      applies_to_group {
        group_connectivity = "None"
        network_group_id   = azurerm_network_manager_network_group.network_group.id
      }
    }
    
    
    # Commit deployment
    
    resource "azurerm_network_manager_deployment" "commit_deployment" {
      network_manager_id = azurerm_network_manager.network_manager_instance.id
      location           = azurerm_resource_group.rg.location
      scope_access       = "Connectivity"
      configuration_ids  = [azurerm_network_manager_connectivity_configuration.connectivity_config.id]
    }
    
  4. Crie um arquivo chamado variables.tf e insira o seguinte código:

    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
      default     = "rg"
    }
    
    variable "msi_id" {
      type    = string
      description = "(Optional) Manage identity id that be used as authentication method. Defaults to `null`."
      default = null
    }
    
  5. Crie um arquivo chamado outputs.tf e insira o seguinte código:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "virtual_network_names" {
      value = azurerm_virtual_network.vnet[*].name
    }
    

Inicializar Terraform

Execute terraform init para inicializar a implantação do Terraform. Esse comando baixa o provedor do Azure necessário para gerenciar seus recursos do Azure.

terraform init -upgrade

Pontos principais:

  • O parâmetro -upgrade atualiza os plug-ins do provedor necessários para a versão mais recente que esteja em conformidade com as restrições de versão da configuração.

Criar um plano de execução Terraform

Execute o comando terraform plan para criar um plano de execução.

terraform plan -out main.tfplan

Pontos principais:

  • O comando terraform plan cria um plano de execução, mas não o executa. Em vez disso, ele determina quais ações são necessárias para criar a configuração especificada em seus arquivos de configuração. Esse padrão permite que você verifique se o plano de execução corresponde às suas expectativas antes de fazer qualquer alteração nos recursos reais.
  • O parâmetro opcional -out permite que você especifique um arquivo de saída para o plano. Usar o parâmetro -out garante que o plano que você examinou seja exatamente o que é aplicado.

Aplicar um plano de execução do Terraform

Execute terraform apply para aplicar o plano de execução à sua infraestrutura de nuvem.

terraform apply main.tfplan

Pontos principais:

  • O exemplo de comando do terraform apply pressupõe que você executou o terraform plan -out main.tfplan anteriormente.
  • Se você especificou um nome de arquivo diferente para o parâmetro -out, use esse mesmo nome de arquivo na chamada para terraform apply.
  • Se você não usou o parâmetro -out, chame terraform apply sem nenhum parâmetro.

Verifique os resultados

  1. Obtenha o nome do grupo de recursos do Azure.

    resource_group_name=$(terraform output -raw resource_group_name)
    
  2. Obtenha os nomes das redes virtuais.

    terraform output virtual_network_names
    
  3. Para cada nome de rede virtual impresso na etapa anterior, execute az network manager list-effective-connectivity-config para imprimir as configurações efetivas (aplicadas). Substitua o espaço reservado <virtual_network_name> pelo nome da Vnet.

    az network manager list-effective-connectivity-config \
      --resource-group $resource_group_name \
      --vnet-name <virtual_network_name>
    

Limpar os recursos

Quando você não precisar mais dos recursos criados por meio o Terraform, execute as seguintes etapas:

  1. Execute terraform plan e especifique o sinalizador destroy.

    terraform plan -destroy -out main.destroy.tfplan
    

    Pontos principais:

    • O comando terraform plan cria um plano de execução, mas não o executa. Em vez disso, ele determina quais ações são necessárias para criar a configuração especificada em seus arquivos de configuração. Esse padrão permite que você verifique se o plano de execução corresponde às suas expectativas antes de fazer qualquer alteração nos recursos reais.
    • O parâmetro opcional -out permite que você especifique um arquivo de saída para o plano. Usar o parâmetro -out garante que o plano que você examinou seja exatamente o que é aplicado.
  2. Execute a aplicação do Terraform para aplicar o plano de execução.

    terraform apply main.destroy.tfplan
    

Solucionar problemas do Terraform no Azure

Solucionar problemas comuns ao usar o Terraform no Azure

Próximas etapas