Compartir a través de


Inicio rápido: Uso de Terraform para configurar zonas DNS privadas en Azure

En este inicio rápido, usará Terraform para crear zonas DNS privadas, interfaces de red, máquinas virtuales Windows, un registro DNS privado, grupos de seguridad de red y una regla de seguridad de red en Azure.

Terraform habilita la definición, vista previa e implementación de la infraestructura en la nube. Con Terraform, se crean archivos de configuración mediante la sintaxis de HCL. La sintaxis de HCL permite especificar el proveedor de la nube, como Azure, y los elementos que componen la infraestructura de la nube. Después de crear los archivos de configuración, se crea un plan de ejecución que permite obtener una vista previa de los cambios de infraestructura antes de implementarlos. Una vez que compruebe los cambios, aplique el plan de ejecución para implementar la infraestructura.

  • Cree un grupo de recursos de Azure con un nombre único.
  • Establezca una red virtual con un nombre y una dirección especificados.
  • Configure una subred dentro de la red virtual creada.
  • Cree una zona DNS privada.
  • Genere contraseñas aleatorias para las máquinas virtuales.
  • Cree dos interfaces de red.
  • Cree dos máquinas virtuales Windows y conecte las interfaces de red.
  • Cree un registro A DNS privado.
  • Cree un grupo de seguridad de red y una regla de seguridad de red para permitir el tráfico ICMP.
  • Genera los nombres y las credenciales de administrador de las máquinas virtuales.

Requisitos previos

Implementación del código de Terraform

  1. Cree un directorio en el que probar y ejecutar el código de ejemplo de Terraform y conviértalo en el directorio actual.

  2. Cree un archivo llamado main.tf e inserte el siguiente código:

    # Resource Group
    resource "random_pet" "rg_name" {
      separator = "-"
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = "${var.resource_group_name_prefix}-${random_pet.rg_name.id}"
    }
    
    # Random String for unique naming
    resource "random_string" "name" {
      length  = 8
      special = false
      upper   = false
      lower   = true
      numeric = false
    }
    
    # Virtual Network
    resource "azurerm_virtual_network" "vnet" {
      name                = "vnet-${random_string.name.result}"
      address_space       = var.address_space
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Subnet
    resource "azurerm_subnet" "subnet" {
      name                 = "subnet-${random_string.name.result}"
      resource_group_name  = azurerm_resource_group.rg.name
      virtual_network_name = azurerm_virtual_network.vnet.name
      address_prefixes     = var.address_prefixes
    }
    
    # Private DNS Zone
    resource "azurerm_private_dns_zone" "dns_zone" {
      name                = var.private_dns_zone_name
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Private DNS Zone Virtual Network Link
    resource "azurerm_private_dns_zone_virtual_network_link" "dsn_vnet_link" {
      name                  = "dns-vnet-link-${random_string.name.result}"
      resource_group_name   = azurerm_resource_group.rg.name
      private_dns_zone_name = azurerm_private_dns_zone.dns_zone.name
      virtual_network_id    = azurerm_virtual_network.vnet.id
    }
    
    # Random Passwords for VMs
    resource "random_password" "vm1_admin_password" {
      length  = 16
      special = true
    }
    
    resource "random_password" "vm2_admin_password" {
      length  = 16
      special = true
    }
    
    # Network Interfaces
    resource "azurerm_network_interface" "nic1" {
      name                = "nic1-${random_string.name.result}"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      ip_configuration {
        name                          = "internal"
        subnet_id                     = azurerm_subnet.subnet.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    resource "azurerm_network_interface" "nic2" {
      name                = "nic2-${random_string.name.result}"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      ip_configuration {
        name                          = "internal"
        subnet_id                     = azurerm_subnet.subnet.id
        private_ip_address_allocation = "Dynamic"
      }
    }
    
    # Windows Virtual Machines
    resource "azurerm_windows_virtual_machine" "vm1" {
      name                = "vm1-${random_string.name.result}"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      size                = "Standard_F2"
      admin_username      = var.admin_username
      admin_password      = random_password.vm1_admin_password.result
      network_interface_ids = [
        azurerm_network_interface.nic1.id,
      ]
    
      os_disk {
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
      source_image_reference {
        publisher = "MicrosoftWindowsServer"
        offer     = "WindowsServer"
        sku       = "2019-Datacenter"
        version   = "latest"
      }
    
      # Make idempotent
      vm_agent_platform_updates_enabled = true
    }
    
    resource "azurerm_windows_virtual_machine" "vm2" {
      name                = "vm2-${random_string.name.result}"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      size                = "Standard_F2"
      admin_username      = var.admin_username
      admin_password      = random_password.vm1_admin_password.result
      network_interface_ids = [
        azurerm_network_interface.nic2.id,
      ]
    
      os_disk {
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
      source_image_reference {
        publisher = "MicrosoftWindowsServer"
        offer     = "WindowsServer"
        sku       = "2019-Datacenter"
        version   = "latest"
      }
    
      # Make idempotent
      vm_agent_platform_updates_enabled = true
    }
    
    # Private DNS A Record
    resource "azurerm_private_dns_a_record" "pdar" {
      name                = "test"
      zone_name           = azurerm_private_dns_zone.dns_zone.name
      resource_group_name = azurerm_resource_group.rg.name
      ttl                 = 300
      records             = [azurerm_windows_virtual_machine.vm1.private_ip_address]
    }
    
    # Network Security Group
    resource "azurerm_network_security_group" "nsg" {
      name                = "nsg-${random_string.name.result}"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Network Security Rule
    resource "azurerm_network_security_rule" "nsr_icmp" {
      name                        = "Allow-ICMP"
      priority                    = 100
      direction                   = "Inbound"
      access                      = "Allow"
      protocol                    = "Icmp"
      source_port_range           = "*"
      destination_port_range      = "*"
      source_address_prefix       = "*"
      destination_address_prefix  = "*"
      resource_group_name         = azurerm_resource_group.rg.name
      network_security_group_name = azurerm_network_security_group.nsg.name
    }
    
  3. Cree un archivo llamado outputs.tf e inserte el siguiente código:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "windows_virtual_machine_1_name" {
      value = azurerm_windows_virtual_machine.vm1.name
    }
    
    output "windows_virtual_machine_2_name" {
      value = azurerm_windows_virtual_machine.vm2.name
    }
    
    output "windows_virtual_machine_1_password" {
      value     = azurerm_windows_virtual_machine.vm1.admin_password
      sensitive = true
    }
    
    output "windows_virtual_machine_2_password" {
      value     = azurerm_windows_virtual_machine.vm2.admin_password
      sensitive = true
    }
    
    output "windows_virtual_machine_1_admin_username" {
      value     = azurerm_windows_virtual_machine.vm1.admin_username
      sensitive = true
    }
    
    output "windows_virtual_machine_2_admin_username" {
      value     = azurerm_windows_virtual_machine.vm2.admin_username
      sensitive = true
    }
    
  4. Cree un archivo llamado providers.tf e inserte el siguiente código:

    terraform {
      required_version = ">=1.0"
    
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  5. Cree un archivo llamado variables.tf e inserte el siguiente código:

    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 "address_space" {
      type = list(string)
      default = ["10.0.0.0/16"]
      description = "The address space that is used the virtual network."
    }
    
    variable "address_prefixes" {
      type = list(string)
      default = ["10.0.2.0/24"]
      description = "The address prefixes to use for the subnet"
    }
    
    variable "private_dns_zone_name" {
      type = string
      default = "private.contoso.com"
      description = "The name of the Private DNS Zone. Must be a valid domain name. Changing this value forces a new resource to be created."
    }
    
    variable "admin_username" {
      type = string
      default = "adminuser"
      description = "The username for the Windows virtual machines."
    }
    

Inicialización de Terraform

Para inicializar la implementación de Terraform, ejecute terraform init. Este comando descarga el proveedor de Azure necesario para administrar los recursos de Azure.

terraform init -upgrade

Puntos clave:

  • El parámetro -upgrade actualiza los complementos de proveedor necesarios a la versión más reciente que cumpla con las restricciones de versión de la configuración.

Creación de un plan de ejecución de Terraform

Ejecute terraform plan para crear un plan de ejecución.

terraform plan -out main.tfplan

Puntos clave:

  • El comando terraform plan crea un plan de ejecución, pero no lo ejecuta. En su lugar, determina qué acciones son necesarias para crear la configuración especificada en los archivos de configuración. Este patrón le permite comprobar si el plan de ejecución coincide con sus expectativas antes de realizar cambios en los recursos reales.
  • El parámetro -out opcional permite especificar un archivo de salida para el plan. El uso del parámetro -out garantiza que el plan que ha revisado es exactamente lo que se aplica.

Aplicación de un plan de ejecución de Terraform

Ejecute terraform apply para aplicar el plan de ejecución a su infraestructura en la nube.

terraform apply main.tfplan

Puntos clave:

  • El comando terraform apply de ejemplo asume que ejecutó terraform plan -out main.tfplan previamente.
  • Si especificó un nombre de archivo diferente para el parámetro -out, use ese mismo nombre de archivo en la llamada a terraform apply.
  • Si no ha utilizado el parámetro -out, llame a terraform apply sin ningún parámetro.

Verificación de los resultados

  1. Ejecute az network private-dns zone list para ver todas las zonas DNS y encontrar la suya.

    az network private-dns zone list --output table
    
  2. Ejecute az network private-dns zone show para ver el grupo de recursos asociado a la zona DNS.

    az network private-dns zone show --name $dnsZoneName --resource-group $resourceGroupName
    

Limpieza de recursos

Cuando ya no necesite los recursos creados a través de Terraform, realice los pasos siguientes:

  1. Ejecute el comando terraform plan y especifique la marca destroy.

    terraform plan -destroy -out main.destroy.tfplan
    

    Puntos clave:

    • El comando terraform plan crea un plan de ejecución, pero no lo ejecuta. En su lugar, determina qué acciones son necesarias para crear la configuración especificada en los archivos de configuración. Este patrón le permite comprobar si el plan de ejecución coincide con sus expectativas antes de realizar cambios en los recursos reales.
    • El parámetro -out opcional permite especificar un archivo de salida para el plan. El uso del parámetro -out garantiza que el plan que ha revisado es exactamente lo que se aplica.
  2. Ejecute terraform apply para aplicar el plan de ejecución.

    terraform apply main.destroy.tfplan
    

Solución de problemas de Terraform en Azure

Solución de problemas comunes al usar Terraform en Azure.

Pasos siguientes