4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AnsibleAdvent Calendar 2021

Day 18

Ansible で vCenter 構築する日記

Last updated at Posted at 2021-12-17

まえおき

ある日、僕たちの使っていた vCenter が吹き飛びました。
頑張って復旧した結果、前と少し違うものが出来上がりました。

そのとき僕は思ったのです。ansible や terraform で構築できないのかなと :thinking:
これは ansible で vCenter、さらには vSphere cluster を構築できないか、検証した記録です :book:

サンプル実装はこちら

1日目 - vCenter VM をデプロイする準備

まずは何はともあれ、vCenter がない状況から、vCenter を生み出さなければなりません。ansible でやるか、terraform でやるか迷ったので、どちらも少し試してみました。terraform は vsphere_virtual_machineモジュールの、ovf_deployを使ってできないかなと思ったのですが、このモジュールは既に vCenter がある状態でないと実行できないことがわかり、諦めました。

気持ちを切り替えて、ansible でやっていきます :muscle:
ansibleでは、少し探すと下記の記事が見つかったので、参考にしました。

使用するモジュールは、community.vmware.vmware_deploy_ovf です。community.vmware コレクションを利用するためには、下記コレクションの install に加え、

ansible-galaxy collection install community.vmware

pyvmomi が必要なので、次のコマンドを実行します。

pip install pyvmomi

これで準備は OK です。

2日目 - vCenter vm のデプロイ

いよいよ、デプロイタスクを書いていきます。

いきなりですが、全体像です。ざっくりした説明をコメントに記載しています。

deploy_vcenter.yaml
- 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 タスクを繋げます。

deploy_vcenter.yaml
- 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ログイン画面が表示されます。
image.png

いつもの画面

image.png

3日目 - vCenter の設定

さて、ひとまず vCenter のデプロイができましたが、まだ設定が何もありません。ここでは最低限の設定をモリモリ盛り込んでいきました。
作ったタスクは、下記5つです。

  • vCenter のライセンス登録
  • SSO へのユーザ追加
  • Datacenter 作成
  • vSphere Cluster 作成
  • Folder 作成

最初に試したのが、ライセンス登録です。これは vcenter_license モジュールを使って何も考えずにサクッといけたので、詳細は割愛します。

次に試したのが、SSO へのユーザー追加です。これが2日目の山場でした。それっぽいモジュールを探したのですが、ESXi にユーザ追加するモジュールしか見つかりませんでした。色々調べた結果行き着いた結論は、SSO のドメインユーザーは vSphere API で作成することができず、VCSA の shell を変更してコマンドで実行するというものでした。全てを自動化することが目的だったので、シェルの変更が手作業になるのがちょっとだけ嫌でした。試行錯誤した結果、vmware_vm_shell モジュールで実行すると shell の変更が不要なことがわかりました。

ユーザを追加する場合のタスクはこんな感じです。

config_vcenter.yaml
- 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 の内容が削除コマンドになります。

config_vcenter.yaml
    vm_shell_args: >-
      user delete
      --account "{{ user.username }}"
      --login "{{ vcenter.admin_user }}"
      --password "{{ vcenter.admin_pass }}"

この後、vCenter 上に Datacenter と vSphere Cluster と Folder を追加しました。それぞれ vmware_datacentervmware_clustervcenter_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_drsvmware_cluster_ha モジュールを使用しました。どちらも結構柔軟な設定ができるようですが、vSphere の勉強不足でいまいち詳細を把握できていないので、詳細は割愛させていただきます :sweat:

まとめ

正直、最初の vCenter デプロイですら、ansible でできると思っていなかったので、無事に起動してきた時には感動すら覚えました :sparkles: community.vmware コレクションには、種々の細かな設定も一通りモジュールが揃っていそうなので、他に何ができるのかもっと調べてみようと思います。
ありがとう ansible :raised_hands:
すごいぞ ansible :raised_hands:

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?