Compartir a través de


Creación de una máquina virtual Windows en Azure mediante Ansible

En este artículo se muestra cómo implementar una máquina virtual de Windows Server 2019 en Azure con Ansible.

En este artículo aprenderá a:

  • Crear un grupo de recursos
  • Crear una red virtual, una dirección IP pública, un grupo de seguridad de red y una interfaz de red
  • Implementar una máquina virtual con Windows Server
  • Conectarse a la máquina virtual mediante WinRM
  • Ejecutar un cuaderno de Ansible para configurar Windows IIS

Requisitos previos

  • Suscripción de Azure: si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.

Adición de compatibilidad con WinRM a Ansible

Para comunicarse a través de WinRM, el servidor de control de Ansible necesita el paquete de Python pywinrm.

Ejecute el siguiente comando en el servidor de Ansible para instalar pywinrm:

pip install "pywinrm>=0.3.0"

Para más información sobre, consulte Administración remota de Windows para Ansible.

Crear un grupo de recursos

Cree un cuaderno de estrategias de Ansible denominado azure_windows_vm.yml y copie el siguiente contenido en él:

---
- name: Create Azure VM
  hosts: localhost
  connection: local
  tasks:

  - name: Create resource group
    azure_rm_resourcegroup:
      name: myResourceGroup
      location: eastus

Puntos clave:

  • Si se establece hosts en localhost y connection como _local_ se ejecuta el cuaderno de estrategias localmente en el servidor de Ansible.

Creación de la red virtual y la subred

Agregue las siguientes tareas al cuaderno de azure_windows_vm.yml estrategias de Ansible para crear una red virtual:

  - name: Create virtual network
    azure_rm_virtualnetwork:
      resource_group: myResourceGroup
      name: vNet
      address_prefixes: "10.0.0.0/16"

  - name: Add subnet
    azure_rm_subnet:
      resource_group: myResourceGroup
      name: subnet
      address_prefix: "10.0.1.0/24"
      virtual_network: vNet

Crear una dirección IP pública

Agregue las siguientes tareas al azure_windows_vm.yml cuaderno de estrategias para crear una dirección IP pública:

  - name: Create public IP address
    azure_rm_publicipaddress:
      resource_group: myResourceGroup
      allocation_method: Static
      name: pip
    register: output_ip_address

  - name: Output public IP
    debug:
      msg: "The public IP is {{ output_ip_address.state.ip_address }}"

Puntos clave:

  • El módulo register de Ansible se usa para almacenar la salida de azure_rm_publicipaddress en una variable denominada output_ip_address.
  • El debug módulo se usa para generar la dirección IP pública de la máquina virtual en la consola.

Creación de un grupo de seguridad de red y una NIC

El grupo de seguridad de red define qué tráfico se permite y cuál no para acceder a la máquina virtual.

Para abrir los puertos WinRM y HTTP, agregue las siguientes tareas al cuaderno de estrategias de Ansible azure_windows_vm.yml:

  - name: Create Network Security Group
    azure_rm_securitygroup:
      resource_group: myResourceGroup
      name: networkSecurityGroup
      rules:
        - name: 'allow_rdp'
          protocol: Tcp
          destination_port_range: 3389
          access: Allow
          priority: 1001
          direction: Inbound
        - name: 'allow_web_traffic'
          protocol: Tcp
          destination_port_range:
            - 80
            - 443
          access: Allow
          priority: 1002
          direction: Inbound
        - name: 'allow_powershell_remoting'
          protocol: Tcp
          destination_port_range: 
            - 5985
            - 5986
          access: Allow
          priority: 1003
          direction: Inbound

  - name: Create a network interface
    azure_rm_networkinterface:
      name: nic
      resource_group: myResourceGroup
      virtual_network: vNet
      subnet_name: subnet
      security_group: networkSecurityGroup
      ip_configurations:
        - name: default
          public_ip_address_name: pip
          primary: True

Puntos clave:

  • Las tarjetas de interfaz de red virtuales conectan la máquina virtual a su red virtual, dirección IP pública y grupo de seguridad de red.
  • azure_rm_securitygroup crea un grupo de seguridad de red de Azure para permitir el tráfico de WinRM desde el servidor de Ansible al host remoto permitiendo los puertos 5985 y 5986.

Creación de una máquina virtual

A continuación, cree una máquina virtual que use todos los recursos que ha creado en las secciones anteriores de este artículo.

Agregue la siguiente tarea al cuaderno de estrategias de Ansible azure_windows_vm.yml:

  - name: Create VM
    azure_rm_virtualmachine:
      resource_group: myResourceGroup
      name: win-vm
      vm_size: Standard_DS1_v2
      admin_username: azureuser
      admin_password: "{{ password }}"
      network_interfaces: nic
      os_type: Windows
      image:
          offer: WindowsServer
          publisher: MicrosoftWindowsServer
          sku: 2019-Datacenter
          version: latest
    no_log: true

El valor admin_password de {{ password }} es una variable de Ansible que contiene la contraseña de la máquina virtual Windows. Para rellenar de forma segura esa variable, agregue una entrada var_prompts al principio del cuaderno de estrategias.

- name: Create Azure VM
  hosts: localhost
  connection: local
  vars_prompt:
    - name: password
      prompt: "Enter local administrator password"
  tasks:

Puntos clave:

  • Evite almacenar datos confidenciales como texto sin formato. Use var_prompts para rellenar variables en tiempo de ejecución. Agregue no_log: true para evitar que las contraseñas se registren.

Configuración del agente de escucha de WinRM

Ansible usa PowerShell para conectarse y configurar los hosts remotos de Windows mediante WinRM.

Para configurar WinRM, agregue la siguiente extensión azure_rm_virtualmachineextension:

  - name: Create VM script extension to enable HTTPS WinRM listener
    azure_rm_virtualmachineextension:
      name: winrm-extension
      resource_group: myResourceGroup
      virtual_machine_name: win-vm
      publisher: Microsoft.Compute
      virtual_machine_extension_type: CustomScriptExtension
      type_handler_version: '1.9'
      settings: '{"fileUris": ["https://raw.githubusercontent.com/ansible/ansible-documentation/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"],"commandToExecute": "powershell -ExecutionPolicy Unrestricted -File ConfigureRemotingForAnsible.ps1"}'
      auto_upgrade_minor_version: true

Ansible no se puede conectar a la máquina virtual hasta que WinRM esté completamente configurado.

Agregue las siguientes tareas al cuaderno de estrategias para esperar la conexión de WinRM:

  - name: Get facts for one Public IP
    azure_rm_publicipaddress_info:
      resource_group: myResourceGroup
      name: pip
    register: publicipaddresses

  - name: set public ip address fact
    set_fact: publicipaddress="{{ publicipaddresses | json_query('publicipaddresses[0].ip_address')}}"

  - name: wait for the WinRM port to come online
    wait_for:
      port: 5986
      host: '{{ publicipaddress }}'
      timeout: 600

Puntos clave:

  • El módulo azure_rm_virtualmachineextension permite ejecutar un script de PowerShell localmente en Windows Azure. La ejecución del script ConfigureRemotingForAnsible.ps1 de PowerShell configura WinRM mediante la creación de certificados autofirmados y la apertura de los puertos necesarios para que Ansible se conecte.
  • El módulo azure_rm_publicipaddress_info consulta la dirección IP pública de Azure y, a continuación, set_fact almacena la salida en una variable para que la use el módulo wait_for.

Cuaderno de Ansible de ejemplo completo

Esta sección enumera el cuaderno de Ansible de ejemplo completo que creó en el transcurso de este artículo.

---
- name: Create Azure VM
  hosts: localhost
  connection: local
  vars_prompt:
    - name: password
      prompt: "Enter local administrator password"
  tasks:

  - name: Create resource group
    azure_rm_resourcegroup:
      name: myResourceGroup
      location: eastus

  - name: Create virtual network
    azure_rm_virtualnetwork:
      resource_group: myResourceGroup
      name: vNet
      address_prefixes: "10.0.0.0/16"

  - name: Add subnet
    azure_rm_subnet:
      resource_group: myResourceGroup
      name: subnet
      address_prefix: "10.0.1.0/24"
      virtual_network: vNet

  - name: Create public IP address
    azure_rm_publicipaddress:
      resource_group: myResourceGroup
      allocation_method: Static
      name: pip
    register: output_ip_address

  - name: Output public IP
    debug:
      msg: "The public IP is {{ output_ip_address.state.ip_address }}"
  
  - name: Create Network Security Group
    azure_rm_securitygroup:
      resource_group: myResourceGroup
      name: networkSecurityGroup
      rules:
        - name: 'allow_rdp'
          protocol: Tcp
          destination_port_range: 3389
          access: Allow
          priority: 1001
          direction: Inbound
        - name: 'allow_web_traffic'
          protocol: Tcp
          destination_port_range:
            - 80
            - 443
          access: Allow
          priority: 1002
          direction: Inbound
        - name: 'allow_powershell_remoting'
          protocol: Tcp
          destination_port_range: 
            - 5985
            - 5986
          access: Allow
          priority: 1003
          direction: Inbound

  - name: Create a network interface
    azure_rm_networkinterface:
      name: nic
      resource_group: myResourceGroup
      virtual_network: vNet
      subnet_name: subnet
      security_group: networkSecurityGroup
      ip_configurations:
        - name: default
          public_ip_address_name: pip
          primary: True

  - name: Create VM
    azure_rm_virtualmachine:
      resource_group: myResourceGroup
      name: win-vm
      vm_size: Standard_DS1_v2
      admin_username: azureuser
      admin_password: "{{ password }}"
      network_interfaces: nic
      os_type: Windows
      image:
          offer: WindowsServer
          publisher: MicrosoftWindowsServer
          sku: 2019-Datacenter
          version: latest
    no_log: true

  - name: Create VM script extension to enable HTTPS WinRM listener
    azure_rm_virtualmachineextension:
      name: winrm-extension
      resource_group: myResourceGroup
      virtual_machine_name: win-vm
      publisher: Microsoft.Compute
      virtual_machine_extension_type: CustomScriptExtension
      type_handler_version: '1.9'
      settings: '{"fileUris": ["https://raw.githubusercontent.com/ansible/ansible-documentation/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"],"commandToExecute": "powershell -ExecutionPolicy Unrestricted -File ConfigureRemotingForAnsible.ps1"}'
      auto_upgrade_minor_version: true

  - name: Get facts for one Public IP
    azure_rm_publicipaddress_info:
      resource_group: myResourceGroup
      name: pip
    register: publicipaddresses

  - name: set public ip address fact
    set_fact: publicipaddress="{{ publicipaddresses | json_query('publicipaddresses[0].ip_address')}}"

  - name: wait for the WinRM port to come online
    wait_for:
      port: 5986
      host: '{{ publicipaddress }}'
      timeout: 600

Conexión a la máquina virtual Windows

Cree un nuevo cuaderno de estrategias de Ansible denominado connect_azure_windows_vm.yml y copie el siguiente contenido en el cuaderno de estrategias:

---
- hosts: all
  vars_prompt:
    - name: ansible_password
      prompt: "Enter local administrator password"
  vars:
    ansible_user: azureuser
    ansible_connection: winrm
    ansible_winrm_transport: ntlm
    ansible_winrm_server_cert_validation: ignore
  tasks:

  - name: Test connection
    win_ping:

Ejecute el cuaderno de estrategias de Ansible.

ansible-playbook connect_azure_windows_vm.yml -i <publicIPaddress>,

Reemplace <publicIPaddress> por la dirección de la máquina virtual.

Puntos clave:

  • La configuración de Ansible determina cómo se conecta Ansible y se autentica en hosts remotos. Las variables que debe definir para conectarse a un host de Windows dependen del tipo de conexión de WinRM y de la opción de autenticación que haya elegido. Para más información, consulte Conexión a un host de Windows y Opciones de autenticación de Windows.
  • Agregar una coma después de que la dirección IP pública omita el analizador de inventario de Ansible. Esta técnica permite ejecutar cuadernos de estrategias sin un archivo de inventario.

Limpieza de recursos

  1. Guarde el código siguiente como delete_rg.yml.

    ---
    - hosts: localhost
      tasks:
        - name: Deleting resource group - "{{ name }}"
          azure_rm_resourcegroup:
            name: "{{ name }}"
            state: absent
          register: rg
        - debug:
            var: rg
    
  2. Ejecute el cuaderno de estrategias mediante el comando ansible-playbook. Reemplace el marcador de posición por el nombre del grupo de recursos que se va a eliminar. Se eliminarán todos los recursos del grupo de recursos.

    ansible-playbook delete_rg.yml --extra-vars "name=<resource_group>"
    

    Puntos clave:

    • Debido a la variable register y a la sección debug del cuaderno de estrategias, los resultados se muestran cuando finaliza el comando.

Pasos siguientes