てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] フロースタイルでマッピング(ディクショナリ)を定義する場合の注意

これは、Ansible Advent Calendar 2020 (Adventar版) の 23日目の記事です。

はじめに

YAMLマッピング(ディクショナリ)の書き方は、大きく分けて、ブロックスタイルフロースタイルの 2つあります。

ブロックスタイルで書くケースで書くことが多いかと思いますが、フロースタイルで書くこともあるのではないでしょうか。

フロースタイルで書くと、微妙にハマる点があるのでご紹介します。

フロースタイルだと : のあとのスペースがなくてもシンタックスエラーにならない

以下の Playbook をご覧ください。

---
- hosts: all
  gather_facts: false

  vars:
    msg1: { key1: value1, key2:value2 }

  tasks:
    - name:
      debug:
        msg: "{{ msg1 }}"

key2:value2 のところは、キーが key2 でバリューがvalue2 としたつもりの箇所です。よく見ると、key2:value2 は、: のあとにスペースがありません。

これでも YAML シンタックスエラーにはならずに、実行できてしまいます。

実行結果は以下のとおりです。このように、キーが key2:value2 でバリューが null という扱いになります。

TASK [debug] ************************************
ok: [localhost] => {
    "msg": {
        "key1": "value1",
        "key2:value2": null
    }
}

このように、意図しない変数定義のまま、シンタックスエラーにならずに実行できるのは、なかなか都合が悪いのではないのでしょうか。

ブロックスタイルだどシンタックススエラーになる

ブロックスタイルで先程の定義をそれっぽく再現させると、以下のようになります。

---
- hosts: all
  gather_facts: false

  vars:
    msg1:
      key1: value1
      key2:value2   # シンタックスエラー

  tasks:
    - name:
      debug:
        msg: "{{ msg1 }}"

これはシンタックスエラーになります。

% ansible-playbook -i localhost, style.yml
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)

Syntax Error while loading YAML.
  could not find expected ':'

The error appears to be in '/Users/sakana/style.yml': line 10, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


  tasks:
  ^ here

もし、キーが key2 でバリューが value2 を意図したのであれば、このようにいっそのことシンタックスエラーになってくれたほうが嬉しいように思います。

おまけ

もし、ブロックスタイルで、キーが key2:value2 でバリューが null を定義する場合は以下のようにします。

---
- hosts: all
  gather_facts: false

  vars:
    msg1:
      key1: value1
      key2:value2:

  tasks:
    - name:
      debug:
        msg: "{{ msg1 }}"

おわりに

微妙な違いですが、ハマるとなかなか厳しい気がします。