使用 Ansible 在 Azure 中建立 Windows 虛擬機
本文說明如何使用 Ansible 在 Azure 中部署 Windows Server 2019 VM。
在本文中,您將學會如何:
- 建立資源群組
- 建立虛擬網路、公用IP、網路安全組和網路介面
- 部署 Windows Server 虛擬機
- 透過 WinRM 將 連線 至虛擬機
- 執行 Ansible 劇本以設定 Windows IIS
必要條件
- Azure 訂用帳戶:如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
- Azure 服務主體:建立服務主體,並記下下列值:appId、displayName、密碼和租使用者。
安裝 Ansible:執行下列其中一個選項:
- 在 Linux 虛擬機上安裝及 設定 Ansible
- 設定 Azure Cloud Shell
將 WinRM 支援新增至 Ansible
若要透過 WinRM 通訊,Ansible 控制伺服器需要 Python 套件 pywinrm
。
在 Ansible 伺服器上執行下列命令以安裝 pywinrm
:
pip install "pywinrm>=0.3.0"
如需詳細資訊,請參閱 適用於 Ansible 的 Windows 遠端管理。
建立資源群組
建立名為 azure_windows_vm.yml
的 Ansible 劇本,並將下列內容複製到劇本:
---
- name: Create Azure VM
hosts: localhost
connection: local
tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: myResourceGroup
location: eastus
重點︰
- 將 設定
hosts
為 localhost ,並在connection
_local_
Ansible 伺服器上本機執行劇本。
建立虛擬網路與子網路
將下列工作新增至 azure_windows_vm.yml
Ansible 劇本以建立虛擬網路:
- 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
模組可用來將 輸出azure_rm_publicipaddress
儲存在名為output_ip_address
的變數中。 - 模組
debug
可用來將 VM 的公用 IP 位址輸出至主控台。
建立網路安全組和 NIC
網路安全組會定義允許的流量,且不允許連線到 VM。
若要開啟 WinRM 和 HTTP 埠,請將下列工作新增至 azure_windows_vm.yml
Ansible 劇本:
- 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
建立 Azure 網路安全組,以允許埠5985
和5986
,允許從 Ansible 伺服器到遠端主機的 WinRM 流量。
建立虛擬機器
接下來,請建立虛擬機,以使用您在本文前幾節中建立的所有資源。
將下列工作新增至 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
的值admin_password
{{ 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 腳本。 執行ConfigureRemotingForAnsible.ps1
PowerShell 腳本會藉由建立自我簽署憑證並開啟 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 虛擬機
建立名為 connect_azure_windows_vm.yml
的新 Ansible 劇本,並將下列內容複製到劇本:
---
- 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的清查剖析器。 這項技術可讓您在沒有清查檔案的情況下執行劇本。
清除資源
將下列程式代碼儲存為
delete_rg.yml
。--- - hosts: localhost tasks: - name: Deleting resource group - "{{ name }}" azure_rm_resourcegroup: name: "{{ name }}" state: absent register: rg - debug: var: rg
使用 ansible-playbook 命令執行劇本 。 將佔位元取代為要刪除的資源群組名稱。 將會刪除資源群組中的所有資源。
ansible-playbook delete_rg.yml --extra-vars "name=<resource_group>"
重點︰
register
由於劇本的變數和debug
區段,因此命令完成時會顯示結果。