Guia de Início Rápido: criar um Firewall do Azure com vários endereços IP públicos – Terraform
Neste guia de início rápido, você usará o Terraform para implantar um Firewall do Azure com vários endereços IP públicos usando um prefixo de endereço IP público. O firewall implantado tem regras de coleção de regras NAT que permitem conexões RDP com duas máquinas virtuais do Windows Server 2019.
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.
Para obter mais informações sobre o Firewall do Azure com vários endereços IP públicos, confira Implantar um Firewall do Azure com vários endereços IP públicos usando o Azure PowerShell.
Neste artigo, você aprenderá como:
- Crie um valor aleatório (a ser usado no nome do grupo de recursos) usando random_pet
- Crie uma senha aleatória para a VM do Windows usando random_password
- Criar um grupo de recursos do Azure usando azurerm_resource_group
- Crie um prefixo IP público do Azure usando azurerm_public_ip_prefix
- Crie um IP público do Azure utilizando azurerm_public_ip
- Crie uma Rede Virtual do Azure utilizando azurerm_virtual_network
- Criar uma sub-rede do Azure usando azurerm_subnet
- Criar um adaptador de rede usando azurerm_network_interface
- Crie um grupo de segurança de rede (para conter uma lista de regras de segurança de rede) usando azurerm_network_security_group
- Crie uma associação entre um Adaptador de Rede e o Grupo de Segurança de Rede usando – azurerm_network_interface_security_group_association
- Crie uma Máquina virtual do Windows usando azurerm_windows_virtual_machine
- Crie uma Política de Firewall do Azure usando azurerm_firewall_policy
- Crie um grupo de coleta de regras de Política de Firewall do Azure usando azurerm_firewall_policy_rule_collection_group
- Crie um Firewall do Azure usando azurerm_firewall
- Crie uma tabela de rotas usando azurerm_route_table
- Crie uma associação entre a tabela de rotas e a sub-rede usando – azurerm_subnet_route_table_association
Pré-requisitos
Implementar o código do Terraform
Observação
O código de exemplo deste artigo está localizado no repositório do GitHub do Azure Terraform. Você pode exibir o arquivo de log que contém os resultados do teste das versões atuais e anteriores do Terraform.
Veja mais artigos e exemplos de código mostrando como usar o Terraform para gerenciar recursos do Azure
Crie um diretório em que você vai testar o código de exemplo do Terraform, depois transforme-o no diretório atual.
Crie um arquivo chamado
providers.tf
e insira o seguinte código:terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features { virtual_machine { delete_os_disk_on_deletion = true skip_shutdown_and_force_delete = true } } }
Crie um arquivo chamado
main.tf
e insira o seguinte código:resource "random_pet" "rg_name" { prefix = var.resource_group_name_prefix } resource "random_password" "password" { count = 2 length = 20 min_lower = 1 min_upper = 1 min_numeric = 1 min_special = 1 special = true } resource "azurerm_resource_group" "rg" { name = random_pet.rg_name.id location = var.resource_group_location } resource "azurerm_public_ip_prefix" "pip_prefix" { name = "pip-prefix" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku = "Standard" prefix_length = 31 } resource "azurerm_public_ip" "pip_azfw" { name = "pip-azfw" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku = "Standard" allocation_method = "Static" public_ip_prefix_id = azurerm_public_ip_prefix.pip_prefix.id } resource "azurerm_public_ip" "pip_azfw_2" { name = "pip-azfw-1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku = "Standard" allocation_method = "Static" public_ip_prefix_id = azurerm_public_ip_prefix.pip_prefix.id } resource "azurerm_virtual_network" "azfw_vnet" { name = "azfw-vnet" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name address_space = ["10.10.0.0/16"] } resource "azurerm_subnet" "azfw_subnet" { name = "AzureFirewallSubnet" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.azfw_vnet.name address_prefixes = ["10.10.0.0/26"] } resource "azurerm_subnet" "backend_subnet" { name = "subnet-backend" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.azfw_vnet.name address_prefixes = ["10.10.1.0/24"] } resource "azurerm_network_interface" "backend_nic" { count = 2 name = "nic-backend-${count.index + 1}" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "ipconfig-backend-${count.index + 1}" subnet_id = azurerm_subnet.backend_subnet.id private_ip_address_allocation = "Dynamic" } } resource "azurerm_network_security_group" "backend_nsg" { name = "nsg-backend" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name security_rule { name = "RDP" priority = 300 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "3389" source_address_prefix = "*" destination_address_prefix = "*" } } resource "azurerm_network_interface_security_group_association" "vm_backend_nsg_association" { count = 2 network_interface_id = azurerm_network_interface.backend_nic[count.index].id network_security_group_id = azurerm_network_security_group.backend_nsg.id } resource "azurerm_windows_virtual_machine" "vm_backend" { count = 2 name = "vm-backend-${count.index + 1}" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = var.virtual_machine_size admin_username = var.admin_username admin_password = random_password.password[count.index].result network_interface_ids = [azurerm_network_interface.backend_nic[count.index].id] os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "MicrosoftWindowsServer" offer = "WindowsServer" sku = "2019-Datacenter" version = "latest" } } resource "azurerm_firewall_policy" "azfw_policy" { name = "azfw-policy" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location sku = var.firewall_sku_tier threat_intelligence_mode = "Alert" } resource "azurerm_firewall_policy_rule_collection_group" "policy_rule_collection_group" { name = "RuleCollectionGroup" firewall_policy_id = azurerm_firewall_policy.azfw_policy.id priority = 300 application_rule_collection { name = "web" priority = 100 action = "Allow" rule { name = "wan-address" protocols { type = "Http" port = 80 } protocols { type = "Https" port = 443 } destination_fqdns = ["getmywanip.com"] source_addresses = ["*"] } rule { name = "google" protocols { type = "Http" port = 80 } protocols { type = "Https" port = 443 } destination_fqdns = ["www.google.com"] source_addresses = ["10.10.1.0/24"] } rule { name = "wupdate" protocols { type = "Http" port = 80 } protocols { type = "Https" port = 443 } destination_fqdn_tags = ["WindowsUpdate"] source_addresses = ["*"] } } nat_rule_collection { name = "Coll-01" action = "Dnat" priority = 200 rule { name = "rdp-01" protocols = ["TCP"] translated_address = "10.10.1.4" translated_port = "3389" source_addresses = ["*"] destination_address = azurerm_public_ip.pip_azfw.ip_address destination_ports = ["3389"] } rule { name = "rdp-02" protocols = ["TCP"] translated_address = "10.10.1.5" translated_port = "3389" source_addresses = ["*"] destination_address = azurerm_public_ip.pip_azfw.ip_address destination_ports = ["3389"] } } } resource "azurerm_firewall" "fw" { name = "azfw" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku_name = "AZFW_VNet" sku_tier = var.firewall_sku_tier ip_configuration { name = "azfw-ipconfig" subnet_id = azurerm_subnet.azfw_subnet.id public_ip_address_id = azurerm_public_ip.pip_azfw.id } ip_configuration { name = "azfw-ipconfig-2" public_ip_address_id = azurerm_public_ip.pip_azfw_2.id } firewall_policy_id = azurerm_firewall_policy.azfw_policy.id } resource "azurerm_route_table" "rt" { name = "rt-azfw-eus" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name disable_bgp_route_propagation = false route { name = "azfw" address_prefix = "0.0.0.0/0" next_hop_type = "VirtualAppliance" next_hop_in_ip_address = "10.10.0.4" } } resource "azurerm_subnet_route_table_association" "jump_subnet_rt_association" { subnet_id = azurerm_subnet.backend_subnet.id route_table_id = azurerm_route_table.rt.id }
Crie um arquivo chamado
variables.tf
e insira o seguinte código:variable "resource_group_location" { type = string description = "Location for all resources." default = "eastus" } variable "resource_group_name_prefix" { type = string description = "Prefix for the Resource Group Name that's combined with a random id so name is unique in your Azure subcription." default = "rg" } variable "firewall_sku_tier" { type = string description = "Firewall SKU." default = "Premium" # Valid values are Standard and Premium validation { condition = contains(["Standard", "Premium"], var.firewall_sku_tier) error_message = "The SKU must be one of the following: Standard, Premium" } } variable "virtual_machine_size" { type = string description = "Size of the virtual machine." default = "Standard_D2_v3" } variable "admin_username" { type = string description = "Value of the admin username." default = "azureuser" }
Crie um arquivo chamado
outputs.tf
e insira o seguinte código:output "resource_group_name" { value = azurerm_resource_group.rg.name } output "backend_admin_password" { sensitive = true value = azurerm_windows_virtual_machine.vm_backend[*].admin_password }
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 oterraform 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 paraterraform apply
. - Se você não usou o parâmetro
-out
, chameterraform apply
sem nenhum parâmetro.
Verifique os resultados
Obtenha o nome do grupo de recursos do Azure.
resource_group_name=$(terraform output -raw resource_group_name)
Execute az network ip-group list para exibir os dois novos Grupos de IP.
az network ip-group list --resource-group $resource_group_name
Limpar os recursos
Quando você não precisar mais dos recursos criados por meio o Terraform, execute as seguintes etapas:
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.
- O comando
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