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:

  • Creación de un grupo de recursos
  • Creación de una red virtual, una dirección IP pública, un grupo de seguridad de red y una interfaz de red
  • Implementación de una máquina virtual de Windows Server
  • Conexión a la máquina virtual mediante WinRM
  • Ejecución de un cuaderno de estrategias de Ansible para configurar Windows IIS

Prerrequisitos

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

Agregar compatibilidad con WinRM a Ansible

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

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

pip install "pywinrm>=0.3.0"

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

Creación de un grupo de recursos

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

---
- 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 azure_windows_vm.yml playbook 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 Ansible register 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 no puede acceder a la máquina virtual.

Para abrir los puertos WinRM y HTTP, agregue las siguientes tareas al playbook 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:

  • Una tarjeta de interfaz de red virtual conecta la máquina virtual a su red virtual, dirección IP pública y grupo de seguridad.
  • 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 al permitir el puerto 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 azure_windows_vm.yml Ansible:

  - 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 admin_password valor 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 var_prompts entrada 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 en un registro.

Configurar el agente de escucha de WinRM

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

Para configurar WinRM, agregue el siguiente archivo ext 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é totalmente 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 azure_rm_virtualmachineextension módulo permite ejecutar un script de PowerShell localmente en Azure Windows. La ejecución del ConfigureRemotingForAnsible.ps1 script de PowerShell configura WinRM mediante la creación de certificados autofirmados y la apertura de los puertos necesarios para que Ansible se conecte.
  • El azure_rm_publicipaddress_info módulo consulta la dirección IP pública de Azure y, a continuación, set_fact almacena la salida en una variable para que el módulo lo wait_for use.

Cuaderno de estrategias de Ansible de ejemplo completo

En esta sección se enumeran todos los cuadernos de estrategias de Ansible de ejemplo que ha creado 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 por <publicIPaddress> la dirección de la máquina virtual.

Puntos clave:

  • La configuración de Ansible determina cómo Ansible se conecta y autentica en hosts remotos. Las variables que necesita definir para conectarse a un host de Windows dependen del tipo de conexión winRM y de la opción de autenticación que haya elegido. Para obtener 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 la dirección IP pública elude 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 la sección debug del manual de operaciones, los resultados se muestran cuando finaliza el comando.

Pasos siguientes