Ansible 変数名が「vars」の場合の変数参照の仕方について


↓のように定義された変数を参照するとき

varfile1.yml
vars:
  var1: hogehoge

vars.var1 → 不正解

$ ansible -m debug -a "var=vars.var1" -e "@varfile1.yml" localhost
localhost | SUCCESS => {
    "vars.var1": "VARIABLE IS NOT DEFINED!"
}

vars.vars.var1 → 正解

$ ansible -m debug -a "var=vars.vars.var1" -e "@varfile1.yml" localhost
localhost | SUCCESS => {
    "vars.vars.var1": "hogehoge"
}

なんで?

調べてみた

環境

environment version
Python 3.8.0
Ansible 2.9.3

varsを見てみる

$ ansible -m debug -a "var=vars" -e "@varfile1.yml" localhost
localhost | SUCCESS => {
    "vars": {
        "ansible_check_mode": false,
        "ansible_connection": "local",
        "ansible_dependent_role_names": [],
        "ansible_diff_mode": false,
        "ansible_facts": {},
        ...
        "playbook_dir": "/Users/answer_d/work/20200208_vars_test",
        "role_names": [],
        "vars": {
            "var1": "hogehoge"
        }
    }
}
  • varsにはそもそもAnsibleが内部的に使う色々な値が入ってる
  • 定義した変数も一緒に入ってる

変数名がvarsでない場合はどうなるか

varfile2.yml
var1: fugafuga
$ ansible -m debug -a "var=vars" -e "@varfile2.yml" localhost
localhost | SUCCESS => {
    "vars": {
        "ansible_check_mode": false,
        ...
        "var1": "fugafuga"
    }
}

この場合はvar1でもvars.var1でも参照可能

$ ansible -m debug -a "var=var1" -e "@varfile2.yml" localhost
localhost | SUCCESS => {
    "var1": "fugafuga"
}
$ ansible -m debug -a "var=vars.var1" -e "@varfile2.yml" localhost
localhost | SUCCESS => {
    "vars.var1": "fugafuga"
}

結論(予想)

  1. まず定義した変数はvars.<定義名>で参照できる
  2. ↑に加えて、単に<定義名>だけでも参照できるようになってる
  3. でも定義名にvarsを含んでる場合、Ansibleが内部で使っている変数名と被るので2の方法が使えない

だからvars.vars.var1と参照しなければいけなかった!