#目次
- 1. はじめに
- 2. 使用環境
- 3. Ansible構成
- 4. hostsを作成する
- 5. tasksを作成する
- 6. playbookを作成する
- 7. varsを作成する
- 8. Ansibleを実行する
- 9. おわりに
- 10. 技術情報
- 11. 参考URL
#1. はじめに
Ansibleを使いvSphereに仮想マシンを構築することを行っていた際に、vmware_guest_diskモジュールを使用しハードディスクの追加を行っていました。
1つのディスクの追加であれば簡単ですが2枚以上の追加を行う場合、unit_numberのループ方法を考えなくてはいけなかったので、Playbookにまとめました。
#2. 使用環境
・CentOS 8
・Ansible 2.9.10
・vSphere 7.0
#3. Ansible構成
.
|-- add_disk.yml
|-- host_vars
| `-- vcsa7
| `-- main.yml
|-- hosts
`-- include_add_disk.yml
#4. hostsを作成する
hostsの内容は以下の通り。ホスト名とIPを記載します。
[target]
vcsa7 ansible_host="vcenter ip"
#5. tasksを作成する
以下のようなタスク(include_add_disk.yml)を作成していきます。
---
- name: 仮想マシンのディスク情報を取得
vmware_guest_disk_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
name: "{{ vm_name }}"
datacenter: "{{ datacenter }}"
register: disk_info
delegate_to: localhost
ignore_errors: true
- name: set fact - controllerFacts
set_fact:
controllerFacts: "{{ disk_info.guest_disk_info.values()| map(attribute='controller_key') | list }}"
delegate_to: localhost
ignore_errors: true
- name: set facts - controllerKey
set_fact:
controllerKey: "{{ controllerFacts | sort | last }}"
delegate_to: localhost
ignore_errors: true
- name: debug
debug:
var: "{{ disk_info.guest_disk_info.values() | selectattr('controller_key','equalto',(controllerKey | int)) | map(attribute='unit_number') | list | sort | last |int +1 }}"
delegate_to: localhost
- name: set fact - unitNumber
set_fact:
unitNumber: "{{ disk_info.guest_disk_info.values() | selectattr('controller_key','equalto',(controllerKey | int)) | map(attribute='unit_number') | list | sort | last |int +1 }}"
delegate_to: localhost
ignore_errors: true
- name: Skip SCSI controller No 7
set_fact:
unitNumber: "{{ unitNumber | int+1 }}"
delegate_to: localhost
ignore_errors: true
when:
- "unitNumber is defined"
- "unitNumber == '7'"
- name: ディスクを追加
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
name: "{{ vm_name }}"
datacenter: "{{ datacenter }}"
disk:
- size_gb: "{{ loop_disks.disk_size }}"
type: "{{ disk_type }}"
state: present
datastore: "{{ datastore_name }}"
scsi_type: "{{ scsi_type }}"
scsi_controller: "{{ controllerKey[3:4] }}"
unit_number: "{{ unitNumber }}"
register: add_disk
delegate_to: localhost
まずは、実行対象の仮想マシンのディスク情報を取得します。
---
- name: 仮想マシンのディスク情報を取得
vmware_guest_disk_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
name: "{{ vm_name }}"
datacenter: "{{ datacenter }}"
register: disk_info
delegate_to: localhost
ignore_errors: true
debugの結果は以下のようになります。
TASK [debug] ****************************************************************************************
ok: [vcsa7] => {
"disk_info": {
"changed": false,
"failed": false,
"guest_disk_info": {
"0": {
"backing_datastore": "2_QNAP_datastore",
"backing_eagerlyscrub": false,
"backing_filename": "[2_QNAP_datastore] ansible_test/ansible_test.vmdk",
"backing_thinprovisioned": false,
"backing_type": "FlatVer2",
"backing_uuid": "6000C294-982e-e8d1-f5dc-f106b7fca5fc",
"backing_writethrough": false,
"capacity_in_bytes": 17179869184,
"capacity_in_kb": 16777216,
"controller_bus_number": 0,
"controller_key": 1000,
"controller_type": "paravirtual",
"key": 2000,
"label": "Hard disk 1",
"summary": "16,777,216 KB",
"unit_number": 0
}
}
}
}
次に現在使用しているコントローラキーを取得します。
コントローラのタイプにより、コントローラキーが決まってます。
(例 SCSIコントローラ0: 1000 , SCSIコントローラ1: 1001 など...)
- name: set fact - controllerFacts
set_fact:
controllerFacts: "{{ disk_info.guest_disk_info.values()| map(attribute='controller_key') | list }}"
delegate_to: localhost
ignore_errors: true
debugの結果は以下です。
TASK [debug] ****************************************************************************************
ok: [vcsa7] => {
"controllerFacts": [
1000
]
}
取得したcontrollerFacts をソートします。
- name: set facts - controllerKey
set_fact:
controllerKey: "{{ controllerFacts | sort | last }}"
delegate_to: localhost
ignore_errors: true
debugの結果は以下です。
TASK [debug] *****************************************************************************************************
ok: [vcsa7] => {
"controllerKey": "1000"
}
※ちなみにSCSIコントローラ0(1000)とSCSIコントローラ1(1001)を使用していた場合は以下のように、『1001』がコントローラキーとして格納されます。そのため、複数のコントローラを使用する場合は考慮が必要です。
TASK [set fact - controllerFacts] *****************************************************************************************************
ok: [vcsa7]
TASK [debug] *****************************************************************************************************
ok: [vcsa7] => {
"controllerFacts": [
1000,
1001
]
}
TASK [set facts - controllerKey] *****************************************************************************************************
ok: [vcsa7]
TASK [debug] *****************************************************************************************************
ok: [vcsa7] => {
"controllerKey": "1001"
}
ユニットナンバーを取得します。最後の『int +1』により取得したunit_numberに+1している値がセットされます。
- name: set fact - unitNumber
set_fact:
unitNumber: "{{ disk_info.guest_disk_info.values() | selectattr('controller_key','equalto',(controllerKey | int)) | map(attribute='unit_number') | list | sort | last |int +1 }}"
delegate_to: localhost
ignore_errors: true
debugの結果は以下になりました。
TASK [debug] *****************************************************************************************************
ok: [vcsa7] => {
"unitNumber": "1"
}
ユニットナンバーで7番は割り当てできないのでスキップを行うようにします。
- name: Skip SCSI controller No 7
set_fact:
unitNumber: "{{ unitNumber | int+1 }}"
delegate_to: localhost
ignore_errors: true
when:
- "unitNumber is defined"
- "unitNumber == '7'"
コントロールキーとユニットナンバーの変数化が完了したら『vmware_guest_disk』モジュールを使いディスクの追加を行います。
『controllerKey[3:4]』はコントローラキー(1000)の4桁目(0)を取得しています。
- name: ディスクを追加する
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
name: "{{ vm_name }}"
datacenter: "{{ datacenter }}"
disk:
- size_gb: "{{ loop_disks.disk_size }}"
type: "{{ disk_type }}"
state: present
datastore: "{{ datastore_name }}"
scsi_type: "{{ scsi_type }}"
scsi_controller: "{{ controllerKey[3:4] }}"
unit_number: "{{ unitNumber }}"
register: add_disk
delegate_to: localhost
#6. playbookを作成する
先ほど作成したタスクでplaybook(add_disk.yml)を作成します。
---
- hosts: all
gather_facts: false
tasks:
- name: タスクを読み込む
include_tasks: include_add_disk.yml
with_items:
"{{ disks }}"
loop_control:
loop_var: loop_disks
#7. varsを作成する
変数はhost_varsに格納しています。使用環境により値を変えてください。
vcenter_hostname: "vcenter hostname"
vcenter_username: "vcenter username"
vcenter_password: "vcenter password"
vm_name: test_vm
datacenter: /Datacenter/vm
disks:
- disk_size: 10
- disk_size: 14
disk_type: thin
datastore_name: datastore1
scsi_type: paravirtual
#8. Ansibleを実行する
仮想マシンの設定前の状態です。
Ansibleを実行します。
[root@localhost ansible]# ansible-playbook add_disk.yml -i hosts
・
・
・
PLAY RECAP **************************************************************************************************
vcsa7 : ok=22 changed=2 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
playbookが成功したら仮想マシンを確認します。ディスク2、ディスク3が指定されたサイズで追加されていることが確認できます。
#9. おわりに
今回はSCSIコントローラを使用したディスクの追加を行いました。
決め打ちの実行であればここまで考慮する必要はないですが、なるべく汎用的にタスクを作成するには工夫が必要になってきます。
#10. 技術情報
Ansible Moleculeを使ったテストの自動化の記事を執筆しています。roleをテストしてくれるツールになります。実行環境を自動で構築し、環境の削除も行うことができるので、冪等性を検証するには便利なツールになります。
また、Ansibleの入門者向け学習ガイド(CentOS編)やAnsibleの入門者向け学習ガイド(Windows編)など入門者向けの記事も執筆していますので、参考にしていただければと思います。
#11. 参考URL
https://vconfig.pl/2019/08/17/ansible-add-disk-to-vm-skipping-scsi-id-x7/
https://techacademy.jp/magazine/28100
https://docs.ansible.com/ansible/latest/modules/vmware_guest_disk_module.html