Ansible を使用して Windows 仮想マシンを Azure 上に作成する
この記事では、Ansible を使用して Azure に Windows Server 2019 VM をデプロイする方法について説明します。
この記事では、次のことについて説明します。
- リソース グループを作成する
- 仮想ネットワーク、パブリック IP、ネットワーク セキュリティ グループ、およびネットワーク インターフェイスを作成する
- Windows Server 仮想マシンをデプロイする
- WinRM 経由で仮想マシンに接続する
- Ansible プレイブックを実行して Windows IIS を構成する
前提条件
- Azure サブスクリプション:Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。
- Azure サービス プリンシパル: サービス プリンシパルを作成して、appId、displayName、password、および tenant の値をメモします。
Ansible のインストール: 次のいずれかのオプションを実行します。
- Linux 仮想マシンに Ansible をインストールして構成する
- Azure Cloud Shell を構成する
Ansible に WinRM サポートを追加する
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 アドレスの作成
パブリック IP アドレスを作成するには、azure_windows_vm.yml
プレイブックに次のタスクを追加します。
- 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
は、ポート5985
と5986
を許可することで Ansible サーバーからリモート ホストへの WinRM トラフィックを許可する Azure ネットワーク セキュリティ グループを作成します。
仮想マシンの作成
次に、この記事の前のセクションで作成したリソースをすべて使用する仮想マシンを作成します。
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
{{ 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 を構成するには、次の拡張機能 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
セクションにより、コマンドの完了時に結果が表示されます。
- プレイブックの