Ansibleのエラーと闘って得た気づき(解決済み)。
-
groups
に限らず、マジック変数で定義されている言葉は変数名として使うことができない。
経緯
Ansibleを使ってのサーバ構築をしていた。
OS上のグループの定義を一通り作成
省略しているがだいたい下記のようなものを作成
#ap_group.yml
---
groups:
- {name: 'group1', gid: 2001}
- {name: 'group2', gid: 2002}
- {name: 'group3', gid: 2003}
#create_group.yml
---
- hosts: all
tasks:
- name: create group
group:
name: "{{ item.name }}"
gid: "{{ item.gid }}"
with_items:
- "{{ groups }}"
ansible-playbook -l ap -i inventory_file -e @v_ap_group.yml create_group.yml
- 実行するymlは汎用性を考えて
hosts: all
とし、インベントリファイルの中からapグループだけを対象として選んで実行 - apグループ以外は別のグループを作成するが、実際には数が多く煩雑なのでvarsファイルごと分けて作成し、実行時に
-e
(--extra-vars
)で対象を選択
…で、簡単にできるはずだったが、かなりはまってしまった。
トラブルシューティング
出たエラーは、前後省略しているが、これ
The error was: 'dict object' has no attribute 'name'
と、お決まりのこれ
but may be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- hosts: all
tasks:
- name:
^here
syntax errorかも、というエラーログは
もはや何を信じていいかわからないので、
念のため手元に構文エラーになりそうなものがないかを調べた。
実際にはgroupだけでなく同時にユーザの定義も書いてあり、
varsファイルもplaybookもそこそこ行数があり、じっくり確認したが、とくに見当たらない。
次に、実はこの「dict形式の定義をwith_itemsで回す」の実績がなかったため、
呼び出し方が間違っているのか?と思い、別の定義の仕方をいくつか調べたが、
いまひとつピンとくる情報はなかったので、とりあえずいろいろ試してみることにした。
まず確認してわかったことは、
別ファイルに出してあるvarsを、実行するplaybook内に書いても、何も変わらないということだった。
書き方もいくつか試したが変化なし。
これでもはや定義の仕方の問題である可能性は低い…?
仕方ないので、エラーログでも意味のありそうな方
'dict object' has no attribute
を検索し、次のstackoverflowに辿り着いた。
症例も似ていたが、
Friendly advice: always check registered variables with debug if you bump on such errors.
このアドバイスを見て、なるほどと思い、やってみた
#create_group.yml debug
---
- hosts: all
tasks:
- name: create group
debug: msg="{{ item }}"
# group:
# name: "{{ item.name }}"
# gid: "{{ item.gid }}"
with_items:
- "{{ groups }}"
すると、参照しているインベントリファイルの内容がずらーっと表示され、気づいた。
これは優先度の高い予約語みたいなものがあるな、と。
というわけで、以下のように変更してやってみることにしたことで、エラー解消。長い闘いであった。
#v_ap_group.yml
---
v_groups:
- {name: 'group1', gid: 2001}
- {name: 'group2', gid: 2002}
- {name: 'group3', gid: 2003}
#create_group.yml
---
- hosts: all
tasks:
- name: create group
group:
name: "{{ item.name }}"
gid: "{{ item.gid }}"
with_items:
- "{{ v_groups }}"
後から確認したが、マジック変数については以下にまとまっていたので参考にされたい。
https://qiita.com/h2suzuki/items/15609e0de4a2402803e9
追記:
マジック変数について、公式ドキュメントの記載はこちら
マジック変数以外では、python的に意味のあるものは使えないとのコメントをTwitterでいただいた(ありがとうございます!)
そもそも公式ドキュメントに、Creating valid variable names
という部分があってきちんと書かれていたのですね。。
大変勉強になりました。
以上