てくなべ (tekunabe)

ansible / network / automation / 学習の記録

[Ansible] 「つまずき Ansible 【Part32】凡ミスTOP5」ふりかえり

はじめに

2021/02/27 に、YouTube Live で「つまずき Ansible 【Part32】凡ミスTOP5」という配信をしました。

実際に作業しながら(ときには)エラーと戦って進めるシリーズです。

tekunabe.connpass.com

今回は、私がよくやりがちな Playbook 上のミスを6個ほど紹介しました。

TOP5というタイトルですが、厳密につまずき回数をカウントしているわけではなく、なんとなくです。


動画

www.youtube.com

  • 0:00 オープニング
  • 1:30 気になり Ansible
  • 3:15 1.Python キーワードの利用
  • 9:38 2.モジュール名間違い
  • 13:32 3.パラメーター名間違い
  • 17:52 4.)閉じ忘れ
  • 22:46 5.インデント間違い
  • 26:40 6.変数のみ定義
  • 28:42 おわりに

(冒頭のおまけコーナー) 気になり Ansible 👀

ここ一週間くらいで気になった issue や PR、リリースを紹介するコーナーです。

今回は以下を取り上げました。

気になり リリース


以下、本編。

1. Python 的なキーワードを変数のキーとして使ってしまう

問題のある Playbook

- hosts: ios
  gather_facts: false

  vars:
    targets:
      items:
        - dest: 192.168.1.1
          count: 4
        - dest: 192.168.1.2
          count: 4

  tasks:
    - name: ping
      cisco.ios.ios_ping:
        dest: "{{ item.dest }}"
        count: "{{ item.count }}"
      loop: "{{ targets.items }}"

エラー

loop では リストの指定が期待されているが、リストでない。

TASK [ping] *************************************************************************************************************************************************************************************
fatal: [ios01]: FAILED! => {"msg": "Invalid data passed to 'loop', it requires a list, got this instead: <built-in method items of dict object at 0x7f1e6c33ba68>. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup."}

items

https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#referencing-key-value-dictionary-variables

に掲載されているように、ドットのキーの指定はできない。

--syntax-check では検出できない。

対処

自分で変数の構造を変えられる場合は、問題ないキーに変更する。

APIからの応答などにより、自分で構造を変えられない場合は、targets.itemstargets['items'] のように指定する。


2. モジュール名のスペルミス

問題のある Playbook

- hosts: ios
  gather_facts: false

  tasks:
    - name: configure lldp
      cisco.ios.ios_lldp_interface:
        config:
          - name: GigabitEthernet0/1
            receive: true
            transmit: true
            state: merge

エラー

ios_lldp_interface ではなく、ios_lldp_interfacesが正しい。

(a210) [admin@gitlab stumble]$ ansible-playbook -i inventory.ini bonmiss02.yml
ERROR! couldn't resolve module/action 'cisco.ios.ios_lldp_interface'. This often indicates a misspelling, missing collection, or incorrect module path.

The error appears to be in '/home/admin/general/vagrant/nwlab/stumble/bonmiss02.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
    - name: configure lldp
      ^ here

--syntax-check でも検出できる。

対処

正しいモジュール名、ios_lldp_interfacesに修正する。


3. オプション名のミス

問題のある Playbook

- hosts: ios
  gather_facts: false

  tasks:
    - name: configure interface
      cisco.ios.ios_interfaces:
        config:
          - name: GigabitEthernet0/1
            description: pukupuku
            state: merge

エラー

cisco.ios.ios_interfaces モジュールの config 内で、state が指定されたがサポートされていない。

TASK [configure interface] **********************************************************************************************************************************************************************
fatal: [ios01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "Unsupported parameters for (cisco.ios.ios_interfaces) module: state found in config. Supported parameters include: description, duplex, enabled, mtu, name, speed"}

--syntax-check では検出できない。

state オプションは、config と同じならびが正しいので一旦修正。

    - name: configure interface
      cisco.ios.ios_interfaces:
        config:
          - name: GigabitEthernet0/1
            description: pukupuku
        state: merge

ただし、これでもまだ以下のエラー。

TASK [configure interface] **********************************************************************************************************************************************************************
fatal: [ios01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "value of state must be one of: merged, replaced, overridden, deleted, rendered, parsed, gathered, got: merge"}

やはり、--syntax-check では検出できない。

state オプションが取りうる値は、

  • merged
  • replaced
  • overridden
  • deleted
  • rendered
  • parsed
  • gathered

であるのに対して、merge が指定された。

対処

正しいオプションの位置、正しい値に修正。

- hosts: ios
  gather_facts: false

  tasks:
    - name: configure interface
      cisco.ios.ios_interfaces:
        config:
          - name: GigabitEthernet0/1
            description: pukupuku
        state: merged


4. ) の閉じ忘れ

問題のある Playbook

- hosts: ios
  gather_facts: false

  vars:
    default:
      a:
        x: default_x
        y: default_x
      b: default_b
      c: default_c
    patch:
      a:
        y: patch_y
        z: patch_x
      b: patch_b

  tasks:
    - name: debug
      ansible.builtin.debug:
        msg: "{{ default | combine(patch, recursive=True }}"

エラー

) を期待している箇所に } がある。

TASK [debug] ************************************************************************************************************************************************************************************
fatal: [ios01]: FAILED! => {"msg": "template error while templating string: unexpected '}', expected ')'. String: {{ default | combine(patch, recursive=True }}"}

--syntax-check では検出できない。(おそらく文字列として扱われている中のため)

対処

以下のように修正。

        msg: "{{ default | combine(patch, recursive=True) }}"

ちなみに、以下の結果になる。

TASK [debug] ***************************************************
ok: [ios01] => {
    "msg": {
        "a": {
            "x": "default_x",
            "y": "patch_y",
            "z": "patch_x"
        },
        "b": "patch_b",
        "c": "default_c"
    }
}

5. インデント間違い

問題のある Playbook

- hosts: ios
  gather_facts: false

  tasks:
    - name: debug
      debug:
        msg: "hello {{ item }}"
     loop:
        - 1
        - 2
        - 3

エラー

loop のインデント位置がおかしい。

(a210) [admin@gitlab stumble]$ ansible-playbook -i inventory.ini bonmiss05.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.
  did not find expected '-' indicator

The error appears to be in '/home/admin/general/vagrant/nwlab/stumble/bonmiss05.yml': line 8, column 6, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

        msg: "hello {{ item }}"
     loop:
     ^ here

--syntax-check でも検出できる。

対処

インデントを正しく修正する。

- hosts: ios
  gather_facts: false

  tasks:
    - name: debug
      debug:
        msg: "hello {{ item }}"
      loop:
          - 1
          - 2
          - 3

6. 変数のみ定義

問題のある Playbook

- hosts: ios
  gather_facts: false

  vars:
    msg: pukupuku

  tasks:
    - name: debug
      debug:
        msg: "hello {{ mgs }}"

エラー

msg 変数を定義したのに対して、誤って mgs を参照しようとしている。

TASK [debug] ************************************************************************************************************************************************************************************
fatal: [ios01]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'mgs' is undefined\n\nThe error appears to be in '/home/admin/general/vagrant/nwlab/stumble/bonmiss06.yml': line 8, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: debug\n      ^ here\n"}

--syntax-check では検出できない。

対処

変数名を正しく修正。

    - name: debug
      debug:
        msg: "hello {{ msg }}"


Part33にむけて

以下のネタを検討中です。気が向いたものをやります。 connpass申込時のアンケートでいただいたものも含めています。

  • connection: local ななにか
  • Windows
  • cli_parse モジュール(Part15 の続き)
  • Ansible 2.10 関連
  • Ansible 3.0.0 関連
  • モジュールのテスト
  • Tower / AWX
  • role と Playbook のリポジトリ分割と読み込み
  • AWXとの共存を念頭に入れたDirectory構成