るつぼっと

NWエンジニアな人たちに向けて

[Ansible] vars lookupプラグインで階層構造の変数を参照する

はじめに

vars lookupプラグインを使うと参照したい変数名を変数で指定できる。
しかし下記のとおり階層のトップ以外は指定できないようだ。

---
- hosts: localhost
  gather_facts: false
  vars:
    Fruits:
      Name: apple
      Value: 100
    Target_var1: Fruits
    Target_var2: Fru
    Target_var3: Fruits.Name
  tasks:
    - name: print1
      debug:
        msg: "{{ lookup('vars', Target_var1) }}"
    - name: print2
      debug:
        msg: "{{ lookup('vars', Target_var2 + 'its') }}"
    - name: print3
      debug:
        msg: "{{ lookup('vars', Target_var3) }}"
TASK [print1] ********************************************************************************************************************
ok: [localhost] => 
  msg:
    Name: apple
    Value: 100

TASK [print2] ********************************************************************************************************************
ok: [localhost] => 
  msg:
    Name: apple
    Value: 100

TASK [print3] ********************************************************************************************************************
fatal: [localhost]: FAILED! => 
  msg: |-
    The task includes an option with an undefined variable. The error was: No variable found with this name: Fruits.Name
  
    The error appears to be in '/home/ansible/test/lookup_vars.yml': line 18, column 7, but may
    be elsewhere in the file depending on the exact syntax problem.
  
    The offending line appears to be:
  
            msg: "{{ lookup('vars', Target_var2 + 'its') }}"
        - name: print3
          ^ here

対処方法

下記のようにlookupの括弧外で指定できる。
トップレベルの名称は可変だが配下の名称は固定という場合に使える。

---
- hosts: localhost
  gather_facts: false
  vars:
    Fruits:
      Name: apple
      Value: 100
    Target_var: Fruits

  tasks:
    - name: print
      debug:
        msg: "{{ lookup('vars', Target_var)['Name'] }}"
TASK [print] *********************************************************************************************************************
ok: [localhost] => 
  msg: apple


下記のようにリストの番号や辞書のKeyを変数で指定することもできる。

---
- hosts: localhost
  gather_facts: false
  vars:
    Fruits:
      - Name: apple
      - Name: banana
    Target_var: Fruits
    Sub_num: 1
    Sub_key: Name
  tasks:
    - name: print
      debug:
        msg: "{{ lookup('vars', Target_var)[Sub_num][Sub_key] }}"
TASK [print] *********************************************************************************************************************
ok: [localhost] => 
  msg: banana

所感

あんまり役に立つ気はしないけど、折角なので書き留めた。