【メモ】【Ansible】リスト変数内にリスト辞書(dic)

vmをterraformかAnsible、どっちで作るか検討中で色々試しているのだがAnsibleで疑問に思ったことがでたのでメモ

## 疑問
公式のAnsible DocではVMの作成は以下の通りになっている。

https://docs.ansible.com/ansible/latest/modules/vmware_guest_module.html#vmware-guest-module

```yml
- name: Create a virtual machine on given ESXi hostname
  vmware_guest:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: no
    folder: /DC1/vm/
    name: test_vm_0001
    state: poweredon
    guest_id: centos64Guest
    # This is hostname of particular ESXi server on which user wants VM to be deployed
    esxi_hostname: "{{ esxi_hostname }}"
    disk:
    - size_gb: 10
      type: thin
      datastore: datastore1
    hardware:
      memory_mb: 512
      num_cpus: 4
      scsi: paravirtual
    networks:
    - name: VM Network
      mac: aa:bb:dd:aa:00:14
      ip: 10.10.10.100
      netmask: 255.255.255.0
      device_type: vmxnet3
    wait_for_ip_address: yes
  delegate_to: localhost
  register: deploy_vm
```

上記タスクにリスト変数を渡してloopさせてvmいっぱい作るぞーと思ったのだが以下部分をvars内でどう書けばいいか疑問に思った

```yml
    disk:
    - size_gb: 10
      type: thin
      datastore: datastore1
```

## 書き方
色々調べて検証した結果以下で出来ることが分かった。

tasksは以下の通り。

```yml:tasks/main.yml
---
- name: Create a virtual machine on given ESXi hostname
  vmware_guest:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: no
    folder: /
    name: "{{ item.name }}"
    state: poweredon
    guest_id: centos64Guest
    esxi_hostname: renge.shiro-rabbit.me
    datacenter: "{{ item.datacenter }}"
    disk: "{{ item.disk }}"
    hardware: "{{ item.hardware }}"
    networks: "{{ item.networks }}"
  delegate_to: localhost
  register: deploy_vm
  loop: "{{ vmware_guest_var }}"
```

ポイントとしては辞書が格納されたlist変数をそのまま渡してあげること


```yml
    disk: "{{ item.disk }}"
    hardware: "{{ item.hardware }}"
    networks: "{{ item.networks }}"
```

varsは以下の通り

```yml:vars/main.yml
vmware_guest_var:
 - {
    name: test01,
    datacenter: kirara,
    hardware: {
        memory_mb: 512,
        num_cpus: 1,
        },
    disk: [
     { size_gb: 16 , type: thin, datastore: Jack },
     { size_gb: 16 , type: thin, datastore: Jack }
     ],
    networks: [
     { name: VM Network, mac: "aa:bb:dd:aa:00:14", ip: 10.10.10.100, netmask: "255.255.255.0", device_type: "vmxnet3" }
     ]
    }
```
ポイントは以下。

```yml
    hardware: { memory_mb: 512, num_cpus: 1 },
    disk: [
     { size_gb: 16 , type: thin, datastore: Jack },
     { size_gb: 16 , type: thin, datastore: Jack }
     ],
    networks: [
     { name: VM Network, mac: "aa:bb:dd:aa:00:15", ip: 10.10.10.100, netmask: "255.255.255.0", device_type: "vmxnet3" }
  ]
```

リスト内に辞書を定義する場合は ``var: [ {} , {} ]`` ただ辞書を定義をする場合は``vars: {}``でおｋ
これでtasksのフォーマットに依存することがなく、diskやnic数をvars内で定義が出来るようになって便利。

一行で書くとこんな感じ

```
 - { name: test01, datacenter: kirara, hardware: { memory_mb: 512, num_cpus: 1, }, disk: [ { size_gb: 16 , type: thin, datastore: Jack },{ size_gb: 16 , type: thin, datastore: Jack }], networks: [ { name: VM Network, mac: "aa:bb:dd:aa:00:14", ip: 10.10.10.101, netmask: "255.255.255.0", device_type: "vmxnet3" }] }
 - { name: test02, datacenter: kirara, hardware: { memory_mb: 512, num_cpus: 1, }, disk: [ { size_gb: 16 , type: thin, datastore: Jack },{ size_gb: 16 , type: thin, datastore: Jack }], networks: [ { name: VM Network, mac: "aa:bb:dd:aa:00:15", ip: 10.10.10.102, netmask: "255.255.255.0", device_type: "vmxnet3" }] }
 - { name: test03, datacenter: kirara, hardware: { memory_mb: 512, num_cpus: 1, }, disk: [ { size_gb: 16 , type: thin, datastore: Jack },{ size_gb: 16 , type: thin, datastore: Jack }], networks: [ { name: VM Network, mac: "aa:bb:dd:aa:00:16", ip: 10.10.10.103, netmask: "255.255.255.0", device_type: "vmxnet3" }] }
 - { name: test04, datacenter: kirara, hardware: { memory_mb: 512, num_cpus: 1, }, disk: [ { size_gb: 16 , type: thin, datastore: Jack },{ size_gb: 16 , type: thin, datastore: Jack }], networks: [ { name: VM Network, mac: "aa:bb:dd:aa:00:17", ip: 10.10.10.104, netmask: "255.255.255.0", device_type: "vmxnet3" }] }
 - { name: test05, datacenter: kirara, hardware: { memory_mb: 512, num_cpus: 1, }, disk: [ { size_gb: 16 , type: thin, datastore: Jack },{ size_gb: 16 , type: thin, datastore: Jack }], networks: [ { name: VM Network, mac: "aa:bb:dd:aa:00:18", ip: 10.10.10.105, netmask: "255.255.255.0", device_type: "vmxnet3" }] }
```
# 追記

varsの書き方についてtwitterにて以下書き方でもできるよーと教えて頂いたので追記
確かにこっちのが見えやすい

```yaml
vmware_guest_var:
  - name: test01
    datacenter: kirara
    hardware:
     memory_mb: 512
     num_cpus: 1
    disk:
     - size_gb: 16
       type: thin
       datastore: Jack
     - size_gb: 16
       type: thin
       datastore: Jack
    networks:
    - name: VM Network
      mac: "aa:bb:dd:aa:00:14"
      ip: 10.10.10.100
      netmask: "255.255.255.0"
      device_type: "vmxnet3"
```