Ansible Tower による VMware vSphere 環境の自動化 Part5 (仮想マシンの作成編)

皆様こんにちは、Red Hat ソリューションアーキテクトの岡野です。
Ansible Tower による VMware vSphere の自動化の第5弾です。
前回のPart 4では、info 系のモジュールを使った vSphere の構成情報の取得方法ついてご説明しました。

今回のシナリオ
今回は、Web Server の作成を Ansible Tower で自動化してみましょう。♪

具体的には以下を実施します。

1. Linux 仮想マシンをテンプレートからデプロイ
2. デプロイした仮想マシンに対しタグを付与
3. タグの付いた仮想マシンに対し httpd のインストール、80 / 443 のポート開放
4. httpd 動作確認
5. タグの削除

皆さんも同じ環境を準備して実行しながら進めてみてください。♪

一見すると簡単そうに見えますが、上記を一気に自動化しようとすると少し難しいところがあります。
例えば、手順 1 で vCenter Server に対し仮想マシンをデプロイを行い、手順 3、4 では新規作成した仮想マシンを指定してタスクを実行する必要があるのですが、1 を実行する時には 3 で対象となるインベントリ情報は存在しない・・・、じゃ、手順 3 のインベントリ情報ってどこから持ってくるの?しかも自動的に??という疑問ですね。

※今回一連のブログで利用する Playbook はこちらに公開しています。

1. Linux 仮想マシンをテンプレートからデプロイ
ではまず仮想マシンの作成から行ってみましょう。作成には Linux のテンプレートを使います。vCenter Server にあらかじめ登録されている Linux 仮想マシンテンプレートが存在することを前提としています。

Playbook はこちらの中から createVM.yml を使います。

---
- name: Create a VM from a template
  hosts: localhost
  gather_facts: no
  tasks:
  - name: Clone the Template
    vmware_guest:
      hostname: "{{lookup('env', 'VMWARE_HOST')}}"
      username: "{{lookup('env', 'VMWARE_USER')}}"
      password: "{{lookup('env', 'VMWARE_PASSWORD')}}"
      datacenter: DC
      cluster: CL
      name: "{{vmname}}{{item}}"
      folder: /DC/vm
      template: "{{template}}"
      networks:
      - name: VM Network
        type: dhcp
      state: poweredon
      datastore: NFS
      validate_certs: no
    with_sequence: count={{number|int - 1}}

  - name: Clone the Template with wait for customization
    vmware_guest:
      hostname: "{{lookup('env', 'VMWARE_HOST')}}"
      username: "{{lookup('env', 'VMWARE_USER')}}"
      password: "{{lookup('env', 'VMWARE_PASSWORD')}}"
      datacenter: DC
      cluster: CL
      name: "{{vmname}}{{number}}"
      folder: /DC/vm
      template: "{{template}}"
      networks:
      - name: VM Network
        type: dhcp
      state: poweredon
      datastore: NFS
      validate_certs: no
      wait_for_ip_address: yes

{{ }} で記載した部分は変数です。仮想マシンを作成する datastore については変数にしていませんので環境に合わせて変更してください。

Ansible Tower でジョブテンプレートを作成する際、インベントリーは、Local Host でお願いします。

with_sequence の中に指定されている変数 number は、作成する仮想マシンの数を示しています。
また、オプションとして仮想マシンの稼働を待つ処理を入れています。具体的には、wait_for_ip_address: yes というオプションです。vmware_guest モジュールは仮想マシンのデプロイが終了した時点で処理が終了します。このため、このオプションを記載しないと仮想マシンが起動する前に手順 3 の httpd のインストール操作が発生し、ジョブが失敗する可能性があります。このオプションは新規作成した仮想マシンが確実に httpd Install Ready になるまで待つために記載しているとお考え下さい。
※今回のこの Playbook では複数の仮想マシンをシーケンシャルに作成します。上記仮想マシンの稼働を1台1台待っていると時間がかかるので、最後の1台の作成のみこのオプションを記載しています。

2. デプロイした仮想マシンに対しタグ付け
次に、新規と既存の仮想マシンを区別するため、新規作成した仮想マシンにタグを付与します。
今回はあらかじめ vCenter Server に仮想マシン用として作成されているタグ New_VM を利用する想定です。
New_VM タグがあらかじめ作成されていないとジョブがエラーとなりますのでご注意ください。

Playbook はこちらの中から tag_vm_manage.yml を使います。

---
- name: Tag Control for VM
  hosts: all
  gather_facts: no
  tasks:
    - name: Manage VM Tag
      vmware_tag_manager:
        hostname: "{{lookup('env', 'VMWARE_HOST')}}"
        username: "{{lookup('env', 'VMWARE_USER')}}"
        password: "{{lookup('env', 'VMWARE_PASSWORD')}}"
        validate_certs: False
        tag_names: New_VM
        object_name: "{{vmname}}{{item}}"
        object_type: VirtualMachine
        state: "{{tag_state}}"
      with_sequence: count={{number}}

こちらも、インベントリーは、Local Host となります。

3. タグの付いた仮想マシンに対し httpd のインストール、80 / 443 のポート開放
仮想マシンへのタグ付けも完了しましたので、新規に作成した仮想マシンを Web Server として構成してみましょう。♪
これに関しては以下の 2 点に関し、少し考慮が必要です。

・新規仮想マシンのインベントリー情報の取得
・タグを使った新規仮想マシンの選別

順にみていきましょう。今回、ジョブ実行の前提として、手順1~5を一気通貫で自動的に実行することを目指しています。このため、新規作成された仮想マシンのインベントリー情報を Ansible Tower が利用可能なインベントリー情報として取得・利用しなければなりません。

これを実現するのが、ダイナミックインベントリーという便利な仕組みです。ダイナミックインベントリーを使うことにより、Ansible Tower は vCenter Server から仮想マシン情報取得し、その結果を、Ansible Tower が利用可能なインベントリー情報として自動的に登録することが可能となります。イメージは以下のような感じです。

f:id:hokn5:20200803165321j:plain

Ansible Tower に登録された vCenter Server の認証情報を使って vCenter Server に登録された仮想マシン情報を取得し、その結果をインベントリーのホストとして登録します。

ダイナミックインベントリーですが、Ansible Tower を使えば設定も極めて簡単です。通常通りインベントリー作成画面から、”ソース” を選択して、"+" をクリック、

f:id:hokn5:20200803180753j:plain

ソースに VMware vCenter を指定。さらに、定義されている vCenter Server の認証情報を選択します。
オプションの更新のところは、ヘルプをご確認の上必要なものにチェックを入れておくようにしましょう。
私は、上書き(既存インベントリーの上書き)起動時の更新(ジョブ実行時のインベントリー情報の自動更新) にチェックを入れることが多いです。

f:id:hokn5:20200803182422j:plain

登録が終わったら、以下の画面で、vCenter Server へ同期を行い、"ホスト" タブを確認してみてください。
起動中の仮想マシンが登録されていると思います。
※起動していない仮想マシンも登録する場合は、インスタンスフィルターに以下のように記述します。
{{ runtime.powerState == 'poweredOn' }} {{ runtime.powerState == 'poweredOff' }}

f:id:hokn5:20200803183816j:plain

これでインベントリー取得が出来ました。

さて、次に、もう 1 つの課題、タグ情報による仮想マシンの選別です。インストール対象である、新規仮想マシンを New_VM というタグで選別する方法ですね。

一番 Cool なのは、ダイナミックインベントリのフィルターで、タグの付いた仮想マシンのみを選別し登録!

なのですが、実は、vSphere 環境の場合、このタグ情報を使ったダイナミックインベントリー内での仮想マシンの選別・登録は現時点では出来ない様です。AWS だと簡単にできるんですが・・・。

ま、出来ないものは仕方がないので、Playbook の中で、タグ情報を拾って仮想マシンを選別します。
やりようはいくらでもあるということです。♬

Playbook はこちらの中から httpd-inst.yml を使います。

---
- name: Get VM Tag & httpd install & Firewall (80/443) config
  hosts: all
  gather_facts: yes
  tasks:
    - name: Confirm VM Tag & Register to variable
      vmware_guest_info:
        hostname: "{{lookup('env', 'VMWARE_HOST')}}"
        username: "{{lookup('env', 'VMWARE_USER')}}"
        password: "{{lookup('env', 'VMWARE_PASSWORD')}}"
        validate_certs: False
        datacenter: DC
        name: "{{ansible_nodename}}"
        tags: yes
      register: vm_facts
      delegate_to: localhost

    - name: httpd install
      yum:
        name: httpd
        state: latest
      when: vm_facts.instance.tags == ["New_VM"]

    - name: httpd running & Enabled
      service:
        name: httpd
        state: started
        enabled: yes
      when: vm_facts.instance.tags == ["New_VM"]

    - name: Firewall Setting 80/443
      firewalld:
        service: "{{item}}"
        zone: public
        state: enabled
        permanent: true
        immediate: true
      with_items:
        - http
        - https
      when: vm_facts.instance.tags == ["New_VM"]

このインベントリーは、先ほどダイナミックインベントリーを登録したものを利用します。

vmware_guest_info モジュールを使って自分自身のタグ情報を取得します。

このモジュール実行時に取得される情報(戻り値)については、Part4 をご確認ください。

このモジュールの戻り値を変数 vm_facts で受けると、仮想マシンに付与されたタグの値は、vm_facts.instance.tags から取得する事が出来ます。

その後の yum タスク、service タスク、firewalld タスクの実行に関しては、when による条件が付与されており、具体的には、New_VM タグが付与されている時のみ実行されます。これで、タグが付与された仮想マシンのみに必要な処理を実行することが可能となるわけです。♪

4. httpd 動作確認
ここまで来たら後は簡単です。せっかく Ansible Tower で自動化していますので、本当に httpd アクセスが可能かどうか確認してみましょう!
色んな方法がありますが、ここでは、curl を使った方法で簡単に確認しています。

Playbook はこちらの中から http-test.yml を使います。

---
- name: Test Connect to New Web Server
  hosts: all
  gather_facts: yes
  tasks:
    - name: Show VM Tag
      vmware_guest_info:
        hostname: "{{lookup('env', 'VMWARE_HOST')}}"
        username: "{{lookup('env', 'VMWARE_USER')}}"
        password: "{{lookup('env', 'VMWARE_PASSWORD')}}"
        validate_certs: False
        datacenter: DC
        name: "{{ansible_nodename}}"
        tags: yes
      register: vm_facts
      delegate_to: localhost

    - name: Test http Access
      command: curl http://localhost/
      when: vm_facts.instance.tags == ["New_VM"]

ダイナミックインベントリーを記載したインベントリー指定でお願いします。
こちらもタグが付与されている仮想マシンを選択して Task を実行しています。

5. タグの削除
最後はタグの削除です。使うジョブテンプレートは手順 2 と同じで、変数 tag_state の値を absent で実行すれば大丈夫です。

上記 1~5 の手順をこちらや、こちらを参考に、ジョブテンプレート、さらには、ワークフローテンプレートで定義し実行してみてください。

参考までに、私は以下の様なワークフローテンプレートを作成し、利用しています。

f:id:hokn5:20200804115555j:plain

ジョブテンプレートの実行が失敗したときのリカバリも Ansible Tower であれば簡単に定義することが可能です。

まとめ
さて、これで、5 回に及んだ Ansible Tower による VMware vSphere 環境の自動化のブログは終了となります。お楽しみいただけましたでしょうか?各回では、それぞれ以下の様な事を学んできました。

Part1:Ansible Tower で vSphere の何をどうやって自動化できるのか
Part2:vSphere モジュールを使った Playbook の書き方とAnsible Tower での実行方法について
Part3:Ansible Tower を使った ESXi ホストの自動構築とvMotion による確認
Part4:info モジュールを使った vSphere 環境の構成の確認
Part5:仮想マシンの作成とアプリケーションの構築・設定、ダイナミックインベントリの利用、仮想マシン情報(タグ情報)の取得について

vSphere そのものや、仮想マシン、アプリケーション、ストレージ、ネットワーク機器含めた vSphere の周辺環境を管理されている方は多いのではと思います。その方々の日々の運用が Ansible Tower を使うことで、少しでも楽になれば、しかも楽しく(ここが重要ですね)、となれば嬉しく思います。♬

是非ご検討ください!!

長々とご拝読、誠にありがとうございました!!

Ansible Tower のバイナリーと評価ライセンスは以下から取得可能です。是非使ってみてください!!

・Ansible Tower バイナリーダウンロードはこちらから
・Ansible Towerの評価ライセンスはこちらから
 ※Customer Portal のアカウント作成が必要です。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。