다음을 통해 공유


Ansible을 사용하여 Azure에서 Windows 가상 머신 만들기

이 문서에서는 Ansible을 사용하여 Azure에서 Windows Server 2019 VM을 배포하는 방법을 보여 줍니다.

이 문서에서는 다음 방법을 설명합니다.

  • 리소스 그룹 만들기
  • 가상 네트워크, 공용 IP, 네트워크 보안 그룹 및 네트워크 인터페이스 만들기
  • Windows Server 가상 머신 배포
  • WinRM을 통해 가상 머신에 커넥트
  • Ansible 플레이북을 실행하여 Windows IIS 구성

필수 조건

  • Azure 구독: Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.
  • Azure 서비스 주체: appId, displayName, 암호테넌트 값을 기록하여 서비스 주체만듭니다.

Ansible에 WinRM 지원 추가

WinRM을 통해 통신하려면 Ansible 제어 서버에 Python 패키지 pywinrm가 필요합니다.

Ansible 서버에서 다음 명령을 실행하여 설치 pywinrm합니다.

pip install "pywinrm>=0.3.0"

자세한 내용은 Ansible용 Windows 원격 관리를 참조하세요.

리소스 그룹 만들기

Ansible 플레이북을 azure_windows_vm.yml 만들고 다음 내용을 플레이북에 복사합니다.

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

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

주요 정보:

  • localhostconnection설정하고 hosts Ansible 서버에서 플레이북을 로컬로 실행합니다_local_.

가상 네트워크 및 서브넷 만들기

Ansible 플레이북에 azure_windows_vm.yml 다음 작업을 추가하여 가상 네트워크를 만듭니다.

  - 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

공용 IP 주소 만들기

다음 작업을 플레이북에 azure_windows_vm.yml 추가하여 공용 IP 주소를 만듭니다.

  - 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 }}"

주요 정보:

  • Ansible register 모듈은 라는 output_ip_address변수에서 azure_rm_publicipaddress 출력을 저장하는 데 사용됩니다.
  • debug 모듈은 VM의 공용 IP 주소를 콘솔에 출력하는 데 사용됩니다.

네트워크 보안 그룹 및 NIC 만들기

네트워크 보안 그룹은 VM에 도달할 수 있는 트래픽과 허용되지 않는 트래픽을 정의합니다.

WinRM 및 HTTP 포트를 열려면 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

주요 정보:

  • 가상 네트워크 인터페이스 카드 VM을 가상 네트워크, 공용 IP 주소 및 보안 그룹에 연결합니다.
  • azure_rm_securitygroup은 포트 59855986을 허용하여 Ansible 서버에서 원격 호스트로의 WinRM 트래픽을 허용하는 Azure 네트워크 보안 그룹을 만듭니다.

가상 머신 만들기

다음으로, 이 문서의 이전 섹션에서 만든 모든 리소스를 사용하는 가상 머신을 만듭니다.

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

{{ password }}admin_password Windows VM 암호를 포함하는 Ansible 변수입니다. 해당 변수를 안전하게 채웁히려면 플레이북의 시작 부분에 항목을 추가 var_prompts 합니다.

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

주요 정보:

  • 중요한 데이터를 일반 텍스트로 저장하지 않습니다. 런타임에 변수를 채우는 데 사용합니다 var_prompts . 암호가 로그되지 않도록 no_log: true를 추가합니다.

WinRM 수신기 구성

Ansible은 PowerShell을 사용하여 WinRM을 통해 Windows 원격 호스트를 연결하고 구성합니다.

WinRM을 구성하려면 다음 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

WinRM이 완전히 구성될 때까지 Ansible은 VM에 연결할 수 없습니다.

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

주요 정보:

  • azure_rm_virtualmachineextension 모듈을 사용하면 Azure Windows에서 로컬로 PowerShell 스크립트를 실행할 수 있습니다. PowerShell 스크립트를 ConfigureRemotingForAnsible.ps1 실행하면 자체 서명된 인증서를 만들고 Ansible이 연결하는 데 필요한 포트를 열어 WinRM을 구성합니다.
  • 모듈은 azure_rm_publicipaddress_info Azure에서 공용 IP 주소를 쿼리한 다음 set_fact 모듈에서 사용할 변수에 출력을 wait_for 저장합니다.

전체 샘플 Ansible 플레이북

이 섹션에서는 이 문서의 과정을 통해 빌드한 전체 샘플 Ansible 플레이북을 나열합니다.

---
- 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

Windows 가상 머신에 연결

새 Ansible 플레이북을 connect_azure_windows_vm.yml 만들고 다음 내용을 플레이북에 복사합니다.

---
- 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:

Ansible 플레이북을 실행합니다.

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

가상 머신의 주소로 대체 <publicIPaddress> 합니다.

주요 정보:

  • Ansible의 구성은 Ansible이 원격 호스트에 연결하고 인증하는 방법을 결정합니다. Windows 호스트에 연결하기 위해 정의해야 하는 변수는 WinRM 연결 유형 및 선택한 인증 옵션에 따라 달라집니다. 자세한 내용은 Windows 호스트Windows 인증 옵션에 커넥트 참조하세요.
  • 공용 IP 주소 후 쉼표 추가는 Ansible의 인벤토리 파서가 무시됩니다. 이 기술을 사용하면 인벤토리 파일 없이 플레이북을 실행할 수 있습니다.

리소스 정리

  1. 다음 코드를 .로 delete_rg.yml저장합니다.

    ---
    - hosts: localhost
      tasks:
        - name: Deleting resource group - "{{ name }}"
          azure_rm_resourcegroup:
            name: "{{ name }}"
            state: absent
          register: rg
        - debug:
            var: rg
    
  2. ansible-playbook 명령을 사용하여 플레이북을 실행합니다. 자리 표시자를 삭제할 리소스 그룹의 이름으로 바꿉니다. 리소스 그룹 내의 모든 리소스가 삭제됩니다.

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

    주요 정보:

    • 플레이북의 register 변수 및 debug 섹션으로 인해 명령이 완료되면 결과가 표시됩니다.

다음 단계