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


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

疑問

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

- 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内でどう書けばいいか疑問に思った

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

書き方

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

tasksは以下の通り。

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変数をそのまま渡してあげること

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

varsは以下の通り

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" }
     ]
    }

ポイントは以下。

    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: {}でおk
これで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にて以下書き方でもできるよーと教えて頂いたので追記
確かにこっちのが見えやすい

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"