まえおき
ある日、僕たちの使っていた vCenter が吹き飛びました。
頑張って復旧した結果、前と少し違うものが出来上がりました。
そのとき僕は思ったのです。ansible や terraform で構築できないのかなと
これは ansible で vCenter、さらには vSphere cluster を構築できないか、検証した記録です
サンプル実装はこちら。
1日目 - vCenter VM をデプロイする準備
まずは何はともあれ、vCenter がない状況から、vCenter を生み出さなければなりません。ansible でやるか、terraform でやるか迷ったので、どちらも少し試してみました。terraform は vsphere_virtual_machineモジュールの、ovf_deployを使ってできないかなと思ったのですが、このモジュールは既に vCenter がある状態でないと実行できないことがわかり、諦めました。
気持ちを切り替えて、ansible でやっていきます
ansibleでは、少し探すと下記の記事が見つかったので、参考にしました。
使用するモジュールは、community.vmware.vmware_deploy_ovf です。community.vmware コレクションを利用するためには、下記コレクションの install に加え、
ansible-galaxy collection install community.vmware
pyvmomi が必要なので、次のコマンドを実行します。
pip install pyvmomi
これで準備は OK です。
2日目 - vCenter vm のデプロイ
いよいよ、デプロイタスクを書いていきます。
いきなりですが、全体像です。ざっくりした説明をコメントに記載しています。
- name: Deploy vCenter VM from delegete host
vmware_deploy_ovf:
hostname: "{{ esxi.address }}" # この辺りは、vCenter VM をデプロイする先のESXiの情報です
username: "{{ esxi.username }}"
password: "{{ esxi.password }}"
name: "{{ vcenter.hostname.split('.')[0] }}" # VM名です FQDN じゃないよ
datastore: "{{ datastore.name }}" # VMをデプロイする Datastore です
deployment_option: "{{ deploy.size }}" # tiny や small など、vcsa のサイズを選択します ※
disk_provisioning: "thin"
networks:
"Network 1": "{{ vcenter.network_label }}" # VM のネットワークインターフェース(key は固定っぽい)
ovf: "{{ deploy.ovf_abs_path }}" # delegate_to でデプロイを代行するサーバ上の、OVF ファイルの絶対パスです
wait_for_ip_address: true # デプロイ後、IPが振られるまで待つかどうか
validate_certs: "{{ validate_certs }}"
inject_ovf_env: true # ここを yes(true) に設定することで、VM 起動時に、下記 properties セクションの値を設定してくれます
properties:
guestinfo.cis.appliance.net.addr.family: "ipv4" # ipv4 or ipv6
guestinfo.cis.appliance.net.mode: "static" # static or dhcp
guestinfo.cis.appliance.net.addr: "{{ vcenter.address }}"
guestinfo.cis.appliance.net.pnid: "{{ vcenter.hostname }}" # FQDN
guestinfo.cis.appliance.net.prefix: "{{ net.prefix }}" # netmask length, CIDR notation, たとえば "24"
guestinfo.cis.appliance.net.gateway: "{{ net.gateway }}"
guestinfo.cis.appliance.net.dns.servers: "{{ net.dns.servers }}" # Comma separated list
guestinfo.cis.appliance.root.passwd: "{{ vcenter.admin_pass }}" # ssh とかで使う root のパスワード
guestinfo.cis.appliance.ssh.enabled: "true"
guestinfo.cis.appliance.ntp.servers: "{{ net.ntp.servers }}" # Comma separated list
guestinfo.cis.ceip_enabled: "False"
guestinfo.cis.deployment.autoconfig: "True" # デプロイ後に、Auto-configure するかどうかですが、ここも true にしておく必要があります
guestinfo.cis.vmdir.username: "{{ vcenter.admin_user }}" # vcenter local SSO のユーザ名
guestinfo.cis.vmdir.domain-name: "{{ vcenter.admin_user.split('@')[1] }}" # SSO のドメイン名
guestinfo.cis.vmdir.password: "{{ vcenter.admin_pass }}" # SSO の管理者パスワード
domain: "{{ vcenter.hostname.split('.')[1:] | join('.') }}" # vCenter のドメイン名
searchpath: "{{ vcenter.hostname.split('.')[1:] | join('.') }}"
ignore_errors: "{{ ansible_check_mode }}"
delegate_to: "{{ deploy.delegate_server }}" # OVFデプロイを代行させるマシンで、localhostでもOKです
tags:
- deploy_vcenter
※ vcsaのサイズに関してはこちらを参照
また、デプロイ後の Auto-configure は非同期で進むので、デプロイが正常に終了したかどうかを確かめるために、下記の wait タスクを繋げます。
- name: Wait for vCenter VM
vmware_about_info:
hostname: "{{ vcenter.hostname }}"
username: "{{ vcenter.admin_user }}"
password: "{{ vcenter.admin_pass }}"
validate_certs: "{{ validate_certs }}"
delegate_to: "{{ deploy.delegate_server }}"
retries: "{{ 0 if ansible_check_mode else 20 }}"
delay: 60
register: result
until: result is succeeded
ignore_errors: "{{ ansible_check_mode }}"
tags:
- deploy_vcenter
1点、気をつけないといけない点としては、デプロイしたい vCenter の IP アドレスを DNS 登録する必要がありました。デプロイ自体は成功しますが、properties の設定でハングしてしまい、wait タスクが完了しませんでした。かなりハマりました。
今回の場合、一度 guestinfo.cis.deployment.autoconfig
の値を False
にしてみて、手動でセットアップを進めてみることで、エラーの原因がわかりました。GUIだとエラーメッセージが表示されました。autoconfig
をFalseにすると、下記の画面で設定が止まります。Trueで最後まで行けると、いつものVMware vSphereログイン画面が表示されます。
いつもの画面
3日目 - vCenter の設定
さて、ひとまず vCenter のデプロイができましたが、まだ設定が何もありません。ここでは最低限の設定をモリモリ盛り込んでいきました。
作ったタスクは、下記5つです。
- vCenter のライセンス登録
- SSO へのユーザ追加
- Datacenter 作成
- vSphere Cluster 作成
- Folder 作成
最初に試したのが、ライセンス登録です。これは vcenter_license モジュールを使って何も考えずにサクッといけたので、詳細は割愛します。
次に試したのが、SSO へのユーザー追加です。これが2日目の山場でした。それっぽいモジュールを探したのですが、ESXi にユーザ追加するモジュールしか見つかりませんでした。色々調べた結果行き着いた結論は、SSO のドメインユーザーは vSphere API で作成することができず、VCSA の shell を変更してコマンドで実行するというものでした。全てを自動化することが目的だったので、シェルの変更が手作業になるのがちょっとだけ嫌でした。試行錯誤した結果、vmware_vm_shell モジュールで実行すると shell の変更が不要なことがわかりました。
ユーザを追加する場合のタスクはこんな感じです。
- name: Add the domain user of the vsphere.local domain if it doesn't exist and present state
community.vmware.vmware_vm_shell:
hostname: "{{ esxi.address }}"
username: "{{ esxi.username }}"
password: "{{ esxi.password }}"
vm_id: "{{ vcenter.hostname.split('.')[0] }}"
vm_username: root
vm_password: "{{ vcenter.admin_pass }}"
vm_shell: "/usr/lib/vmware-vmafd/bin/dir-cli"
vm_shell_args: >-
user create
--account "{{ user.username }}"
--user-password "{{ user.password }}"
--login "{{ vcenter.admin_user }}"
--password "{{ vcenter.admin_pass }}"
--first-name "{{ user.first_name if user.first_name is defined else user.username }}"
--last-name "{{ user.last_name if user.last_name is defined else user.username }}"
validate_certs: "{{ validate_certs }}"
wait_for_process: true
delegate_to: localhost
changed_when: true
when:
- user.state == "present"
- gather_domain_user_info_result.domain_user_groups | length == 0
no_log: true
tags:
- local_user
削除時には vm_shell_args
の内容が削除コマンドになります。
vm_shell_args: >-
user delete
--account "{{ user.username }}"
--login "{{ vcenter.admin_user }}"
--password "{{ vcenter.admin_pass }}"
この後、vCenter 上に Datacenter と vSphere Cluster と Folder を追加しました。それぞれ vmware_datacenter と vmware_cluster と vcenter_folder モジュールでサクっと作成できました。こちらも割愛させてもらいます。
ちなみに、この後ESXiの紐付けなどがありますが、その際に Datacenter と、vSphere Cluster の指定が必要なため、先に作っておく必要があります。Cluster 指定をしない場合は Folder を指定するようですが、そちらは試していません。
4日目 - ESXi と Cluster の可用性の設定
ここまできてしまえば、あともう少しです。ESXi関連のモジュールはたくさん揃っています。Community.Vmware コレクションの中で、 vmware_host
で始まるモジュールが大体全て ESXi に対する設定モジュールのようです。
今回は既存の ESXi を紐づけたので、大した設定はしていません。最低限の設定ということで下記を実施しています。
- Cluster への ESXi ホスト追加
- ESXi のライセンス登録
- Cluster の DRS 設定と、HA 設定
まず、Cluster への ESXi ホスト追加は vmware_host モジュールを使用します。present
/absent
state しか試していませんが、結構柔軟に接続をコントロールできるようです。特に難しいところやハマりどころもなかったので、Example を見ていただければと思います。
次に、ESXi ライセンス登録です。これには、vCenter のライセンス登録と同様に、vcenter_license モジュールを使用します。このモジュールで、esxi_hostname セクションを追加すると、ESXiに対するライセンス割り当てになります。
最後に、vSphere Cluster に対して DRS(Distributed Resource Scheduler)、HA(High Availability)の設定を行いました。それぞれ、vmware_cluster_drs、vmware_cluster_ha モジュールを使用しました。どちらも結構柔軟な設定ができるようですが、vSphere の勉強不足でいまいち詳細を把握できていないので、詳細は割愛させていただきます
まとめ
正直、最初の vCenter デプロイですら、ansible でできると思っていなかったので、無事に起動してきた時には感動すら覚えました community.vmware コレクションには、種々の細かな設定も一通りモジュールが揃っていそうなので、他に何ができるのかもっと調べてみようと思います。
ありがとう ansible
すごいぞ ansible