これまでAnsibleで、LinuxやWindows Serverの初期構築と単体テストを実施してきた。今回は、Ansibleを使ってESXi上に仮想マシンを構築するPlaybookを作ってみたので紹介する。なお、私の環境の問題でESXiを用いているが、少し修正すればvCenter Server経由でも実行することができるだろう。
今までのAnsible関連記事
- AnsibleコントロールノードをAlmaLinux上に構築する
- AnsibleからLinuxサーバに接続するための事前作業
- AnsibleでLinuxサーバの初期設定と単体テストを行う
- Ansibleのベストプラクティスのディレクトリ構成でPlaybookを実行する
- AnsibleからWindows Serverに接続するための事前作業
- AnsibleでWindows Serverの初期設定と単体テストを行う
- AnsibleでESXi上に仮想マシンを構築する ←★本記事
環境
コントロールノードのLinuxのOSは、AlmaLinuxにて構築している。実行対象のESXiは、ESXi 6.7となる。なお、ESXiの無償ライセンスではPlaybookを実行できないため注意する。
- コントロールノード
- OS : AlmaLinux 8.5
- Ansible : ansible [core 2.13.1]
- Ansible実行対象サーバ
- OS : ESXi 6.7
Ansibleコントロールノードでの設定
1. pyVmomiをインストール
PythonでESXiやvCenter Serverの管理をできるようpyVmomiをインストールする。これはpip
を使ってインストールすればよい。
# pip install pyvmomi
2. vSphere Automation Python SDKをインストール
pyVmomiとは別に、vSphere Automation Python SDKもインストールを行う。こちらは、git
を使う必要があるので、git
をインストールしたのち、pip
にてインストールを行う。
# dnf install git -y
# pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git
Collecting git+https://github.com/vmware/vsphere-automation-sdk-python.git
Cloning https://github.com/vmware/vsphere-automation-sdk-python.git to /tmp/pip-req-build-qjay0ffh
Running command git clone --filter=blob:none --quiet https://github.com/vmware/vsphere-automation-sdk-python.git /tmp/pip-req-build-qjay0ffh
Resolved https://github.com/vmware/vsphere-automation-sdk-python.git to commit 4bad74ad6be25a41fef7f0bfaa13a17b25039d25
Preparing metadata (setup.py) ... done
~(中略)~
Installing collected packages: lxml, pyOpenSSL, vapi-runtime, vapi-common-client, vapi-client-bindings, vmc-draas-client-bindings, vmc-client-bindings, nsx-vmc-policy-python-sdk, nsx-vmc-aws-integration-python-sdk, nsx-python-sdk, nsx-policy-python-sdk, vSphere-Automation-SDK
Running setup.py install for vSphere-Automation-SDK ... done
Successfully installed lxml-4.9.1 nsx-policy-python-sdk-3.1.5.0.0 nsx-python-sdk-3.1.5.0.0 nsx-vmc-aws-integration-python-sdk-3.1.5.0.0 nsx-vmc-policy-python-sdk-3.1.5.0.0 pyOpenSSL-22.0.0 vSphere-Automation-SDK-1.78.0 vapi-client-bindings-3.8.0 vapi-common-client-2.34.0 vapi-runtime-2.34.0 vmc-client-bindings-1.60.0 vmc-draas-client-bindings-1.19.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
3. 動作確認
これだけでESXiやvCenter Serverに対してAnsible実行ができるようになる。テスト用として、ESXiの情報を取得するPlaybookを作成したので、実際にPlaybookを実行して、問題なく実行できることを確認してみよう。
インベントリーファイル
hosts
というファイル名で以下の通り1台のESXiを記載したインベントリーファイルを作成した。
[vmware_servers]
esxi01 ansible_host=192.168.1.1
Playbook
test_esxi_connection.yml
というファイル名で以下の通りPlaybookを作成した。ユーザ名、パスワードなどの変数は、環境に合わせて修正すること。
---
- name: Test esxi connection
gather_facts: false
hosts: vmware_servers
vars:
ansible_connection: local
ansible_python_interpreter: /usr/bin/python3.8
esxi_username: root
esxi_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
37316332366436396537613265366334323663646463306163353665323836636362323334313763
~(中略)~
3730
tasks:
- name: Get vmware host facts
community.vmware.vmware_host_facts:
hostname: "{{ inventory_hostname }}"
username: "{{ esxi_username }}"
password: "{{ esxi_password }}"
validate_certs: false
register: result
- name: Show vmware host facts
ansible.builtin.debug:
msg: "{{ result }}"
実行結果
ok=2
となることが確認できればOKとなる。
# ansible-playbook -i hosts test_esxi_connection.yml
PLAY [Create vmware vm] ********************************************************************************************
TASK [Get vmware host facts] ***************************************************************************************
ok: [esxi01]
TASK [Show vmware host facts] **************************************************************************************
ok: [esxi01] => {
"msg": {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.1.1",
"192.168.2.1"
],
"ansible_bios_date": "2018-07-12T00:00:00+00:00",
"ansible_bios_version": "P3.00",
"ansible_datastore": [
{
"free": "326.41 GB",
"name": "Datastore_01",
"total": "458.25 GB"
},
{
"free": "641.69 GB",
"name": "Datastore_02",
"total": "931.25 GB"
},
{
"free": "584.54 GB",
"name": "nfs_01",
"total": "1.94 TB"
}
],
"ansible_distribution": "VMware ESXi",
"ansible_distribution_build": "18828794",
"ansible_distribution_version": "6.7.0",
"ansible_hostname": "esxi01",
"ansible_in_maintenance_mode": false,
"ansible_interfaces": [
"vmk0",
"vmk1"
],
"ansible_memfree_mb": 6108,
"ansible_memtotal_mb": 32420,
"ansible_os_type": "vmnix-x86",
"ansible_processor": "Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz",
"ansible_processor_cores": 6,
"ansible_processor_count": 1,
"ansible_processor_vcpus": 6,
"ansible_product_name": "To Be Filled By O.E.M.",
"ansible_product_serial": "To Be Filled By O.E.M.",
"ansible_system_vendor": "To Be Filled By O.E.M.",
"ansible_uptime": 13418913,
"ansible_uuid": "8cc28570-1edb-0000-0000-000000000000",
"ansible_vmk0": {
"device": "vmk0",
"ipv4": {
"address": "192.168.1.1",
"netmask": "255.255.255.0"
},
"macaddress": "70:85:c2:8c:xx:xx",
"mtu": 1500
},
"ansible_vmk1": {
"device": "vmk1",
"ipv4": {
"address": "192.168.2.1",
"netmask": "255.255.255.0"
},
"macaddress": "00:50:56:64:xx:xx",
"mtu": 1500
},
"cluster": null,
"host_date_time": {
"date": "2022-08-21",
"day": "21",
"epoch": "1661038759",
"hour": "08",
"iso8601": "2022-08-21T08:39:19Z",
"iso8601_basic": "20220821T083919210083",
"iso8601_basic_short": "20220821T083919",
"iso8601_micro": "2022-08-21T08:39:19.210083Z",
"minute": "39",
"month": "08",
"second": "19",
"time": "08:39:19",
"tz": "UTC",
"tz_offset": "+0000",
"weekday": "日曜日",
"weekday_number": "0",
"weeknumber": "33",
"year": "2022"
},
"vsan_cluster_uuid": null,
"vsan_health": "unknown",
"vsan_node_uuid": null
},
"changed": false,
"failed": false
}
}
PLAY RECAP *********************************************************************************************************
esxi01 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ESXi上に仮想マシンを作成するPlaybook
Playbookのファイルの記載内容は大きく以下のように構成される。
設定項目 | 説明 |
---|---|
hosts | 実行対象のサーバを記載する。サーバのリストは別ファイルで作成し、そのファイルの中で実行する対象のサーバやグループを指定する。 |
vars | 変数を記載する。ここで記載した変数は{{ 変数名 }} という形で参照できる。また、変数は配列して複数の要素を持たせることもできる。 |
tasks | Ansibleで実行するメインの処理を記載する。 |
handlers | Ansibleでメイン処理実行状況に応じて実行する事後処理を記載する。例えば、設定ファイル更新がされた場合 (実行結果がchanged の場合) は設定反映のためにサービス再起動を行うといった使い方をする。今回のPlaybookでは未使用となる。 |
今回はcreate_vmware_vm.yml
というファイル1つにすべての内容を記載して作成した。以下にそれぞれの記載内容を説明する。
hosts : 実行対象のESXiを指定
hosts
というファイル名で以下の通り1台のESXiを記載したインベントリーファイルを作成した。
[vmware_servers]
esxi01 ansible_host=192.168.1.1
vars : 変数①(ESXiに接続するための変数)
変数名 | 内容 |
---|---|
ansible_connection |
ESXiへの接続の場合はlocalhostを使用する。 |
ansible_python_interpreter |
Pythonの実行パスを指定する。これを指定しない場合、「The error was: ModuleNotFoundError: No module named 'pyVim' 」といったモジュールが見つからないというメッセージが表示され、タスクの実行に失敗する。 |
esxi_username |
ESXiへ接続するためのユーザ名を指定する。 |
esxi_password |
ESXiへ接続するためのパスワードを指定する。平文で記載するとセキュリティ上よろしくないので、Ansible Vaultを使って暗号化して記載しよう。 |
vars:
ansible_connection: local
ansible_python_interpreter: /usr/bin/python3.8
esxi_username: root
esxi_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
37316332366436396537613265366334323663646463306163353665323836636362323334313763
~(中略)~
3730
vars : 変数②(仮想マシンのパラメータ)
変数名 | 内容 |
---|---|
vm_name |
仮想マシン名を指定する。 |
vm_annotation |
仮想マシンの注釈を指定する。 |
vm_folder |
仮想マシンのフォルダを指定する。ESXiにはフォルダの概念がないが、指定が必須となる。この場合は/ を指定する。 |
vm_guest_id |
仮想マシンのOS種別を指定する。OS種別とIDの紐づけはVMwareのドキュメントを参照。今回はother4xLinux64Guest を指定する。 |
vm_hardware |
仮想マシンのハードウェアとして、CPU数とメモリ容量を指定する。 |
vm_disk |
仮想マシンのハードデイスクを指定する。 |
vm_networks |
仮想マシンのNICを指定する。 |
vm_cdrom |
仮想マシンの光学ドライブを指定する。今回はOSのインストールメディアであるISOファイルをマウントさせるため、ISOファイルのパスを指定する。 |
vm_boot |
起動時にEFIを使用し、セキュアブートを有効化するよう指定する。 |
vm_usb_type |
USBコントローラとして、USB 2.0のコントローラを指定する。 |
vars:
~(中略)~
vm_name: ansible-test
vm_annotation: "Create Ansible"
vm_folder: /
vm_guest_id: other4xLinux64Guest
vm_hardware:
num_cpus: 2
num_cpu_cores_per_socket: 2
memory_mb: 2048
vm_disk:
size_gb: 16
type: thin
datastore: Datastore-01
vm_networks:
name: Network_01
device_type: vmxnet3
vm_cdrom:
iso_path: '[nfs_01] ISO/AlmaLinux/AlmaLinux-8.5-x86_64-minimal.iso'
vm_boot:
boot_firmware: efi
secure_boot_enabled: true
vm_usb_type: usb2
tasks : 処理内容
VMwareのAnsibleモジュールでは、毎回実行対象ESXiのホスト名、ユーザ名、パスワード、証明書検証の無効化を指定する必要があるため、以下4行を各タスクに設定するようにしよう。
hostname: "{{ inventory_hostname }}"
username: "{{ esxi_username }}"
password: "{{ esxi_password }}"
validate_certs: false
各タスクの処理概要を以下に記載する。
※モジュール名はFQCNで記載すると長くなるため名前だけの記載にしているが、PlaybookにはFQCNで記載することを推奨する。
タスク名 | モジュール | 設定 |
---|---|---|
Create vm | vmware_guest |
仮想マシンを作成する。作成する仮想マシン名name を指定し、CPU、メモリ、光学ドライブ、ディスク、ネットワークなどを設定する。ただし、一部起動時の設定やUSBコントローラの追加はできないため、それについては他タスクにて対応する。 |
Set boot settings | vmware_guest_boot_manager |
起動時BIOS/EFIの設定を行う。 |
Set usb controller | vmware_guest_controller |
USBコントローラを追加する。 |
tasks:
# 仮想マシン作成
- name: Create vm
community.vmware.vmware_guest:
hostname: "{{ inventory_hostname }}"
username: "{{ esxi_username }}"
password: "{{ esxi_password }}"
validate_certs: false
name: "{{ vm_name }}"
annotation: "{{ vm_annotation }}"
folder: "{{ vm_folder }}"
guest_id: "{{ vm_guest_id }}"
hardware:
num_cpus: "{{ vm_hardware.num_cpus }}"
num_cpu_cores_per_socket: "{{ vm_hardware.num_cpu_cores_per_socket }}"
memory_mb: "{{ vm_hardware.memory_mb }}"
cdrom:
- controller_number: 0
controller_type: sata
unit_number: 0
iso_path: "{{ vm_cdrom.iso_path }}"
type: iso
disk:
- size_gb: "{{ vm_disk.size_gb }}"
type: "{{ vm_disk.type }}"
datastore: "{{ vm_disk.datastore }}"
networks:
- name: "{{ vm_networks.name }}"
device_type: "{{ vm_networks.device_type }}"
start_connected: true
state: present
# BIOS/EFI設定
- name: Set boot settings
community.vmware.vmware_guest_boot_manager:
hostname: "{{ inventory_hostname }}"
username: "{{ esxi_username }}"
password: "{{ esxi_password }}"
validate_certs: false
name: "{{ vm_name }}"
boot_firmware: "{{ vm_boot.boot_firmware }}"
secure_boot_enabled: "{{ vm_boot.secure_boot_enabled }}"
# USBコントローラ設定
- name: Set usb controller
community.vmware.vmware_guest_controller:
hostname: "{{ inventory_hostname }}"
username: "{{ esxi_username }}"
password: "{{ esxi_password }}"
validate_certs: false
name: "{{ vm_name }}"
controllers:
- state: present
type: "{{ vm_usb_type }}"
実行結果
実際にPlaybookを実行した結果を以下に記載する。
# ansible-playbook -i hosts create_vmware_vm.yml
PLAY [Create vmware vm] *********************************************************************************************
TASK [Gathering Facts] **********************************************************************************************
ok: [esxi01]
TASK [Create vm] ****************************************************************************************************
changed: [esxi01]
TASK [Set boot settings] ********************************************************************************************
changed: [esxi01]
TASK [Set usb controller] *******************************************************************************************
changed: [esxi01]
PLAY RECAP **********************************************************************************************************
esxi01 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
実際にESXi上で作成した仮想マシンを確認すると、設定したパラメータ通りに作成が成功していた。
Ansibleを使ってESXi上に仮想マシンを構築するPlaybookの説明は以上となる。