Ansibleを使ってVMwareのVMクローンとゲストOSにパッケージをインストールした時のメモ

Ansibleを使ってVMwareのVMをAPI経由でクローンした後にSSH接続してゲストOSにパッケージをインストールした時のメモです。

# 環境

|   項目  |  バージョン   |
|---------|---------------|
| OS      | CentOS7.6     |
| Ansible | 2.7.7         |
| vCenter | 6.7.0 8833179 |

# 実行するタスク

* localhostタスク
    * VMをクローンする
        * Linux Prepを実行してホスト名やIPを設定する(ゲストOS側にPerlがインストールされている必要がある)
    * vmware toolsの起動を待つ
    * クローンしたVMのSSHポートに接続できるまで待つ
* ゲストOSタスク(SSH接続)
    * yumでhttpdをインストール
    * httpdを起動
    * firewalldを停止

# Ansible情報

## ディレクトリ構造

```shell-session
vm_clone_example/
├── ansible.cfg
├── inventory
└── main.yml
```

## main.yml(Playbook)ファイル

Playbookにはlocalhost用とclone_host用のタスクを2つ書いて実行します。

```yaml
---
- name: VMware Clone VM
  hosts: localhost
  gather_facts: no
  tasks:
    - name: vm clone
      vmware_guest:
        hostname: "{{ vcenter_host }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: no
        datacenter: "{{ datacenter }}"
        folder: "{{ folder }}"
        name: "{{ vm_name }}"
        datastore: "{{ datastore }}"
        template: "{{ vm_template }}"
        state: poweredon
        networks:
          - name: "{{ network_name }}"
            ip: "{{ network_ip }}"
            netmask: "{{ network_netmask }}"
            gateway: "{{ network_gateway }}"
        customization:
          hostname: "{{ vm_name }}"
          dns_servers: "{{ dns_servers }}"
          domain: "{{ domain }}"

    - name: wait vmware tools started
      vmware_guest_tools_wait:
        hostname: "{{ vcenter_host }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: no
        name: "{{ vm_name }}"

    - name: wait ssh port
      wait_for:
        host: "{{ network_ip }}"
        port: 22
        delay: 10
        timeout: 300

- name: Apache Setup of Guest OS
  hosts: clone_host
  gather_facts: no
  tasks:
    - name: install package
      yum:
        name: httpd
        state: present

    - name: start httpd
      systemd:
        name: httpd
        state: started
        enabled: yes

    - name: stop firewalld
      systemd:
        name: firewalld
        state: stopped
        enabled: no
```

## inventoryファイル

```
[localhost]
127.0.0.1 ansible_connection=local

[clone_host]
192.168.0.154 ansible_user=root ansible_password=secret

[localhost:vars]
vcenter_host = 192.168.0.111
vcenter_username = administrator@vsphere.local
vcenter_password = secret
datacenter = DC
folder = /vm
datastore = datastore1
vm_template = CentOS7_TMP
vm_name = centos01
network_name = VM Network
network_ip = 192.168.0.154
network_netmask = 255.255.255.0
network_gateway = 192.168.0.1
dns_servers = ["192.168.0.1"]
domain = example.com
```

## ansible.cfgファイル

SSH接続次にknown_hostsエラーが出ないようにしています。

```
[defaults]
host_key_checking = False
```

# 実行

```shell-session
[root@localhost vm_clone_example]# ansible-playbook main.yml -i inventory

PLAY [Clone VM] ************************************************************************************************************************

TASK [vm clone] ************************************************************************************************************************
changed: [127.0.0.1]

TASK [wait vmware tools started] *******************************************************************************************************
changed: [127.0.0.1]

TASK [wait ssh port] *******************************************************************************************************************
ok: [127.0.0.1]

PLAY [Apache setup] ********************************************************************************************************************

TASK [install package] *****************************************************************************************************************
changed: [192.168.0.154]

TASK [start httpd] ********************************************************************************************************************
changed: [192.168.0.154]

TASK [stop firewalld] ******************************************************************************************************************
changed: [192.168.0.154]

PLAY RECAP *****************************************************************************************************************************
127.0.0.1                  : ok=3    changed=2    unreachable=0    failed=0
192.168.0.154              : ok=3    changed=3    unreachable=0    failed=0
```

Playbookに2つのタスクを書くことでローカル処理(API接続)と遠隔接続処理(SSH接続)を分けて実行することができました。