Posted at

Ansible module書くときにパラメータで渡された文字列JSONを辞書に落とし込む方法

More than 1 year has passed since last update.


tl;dr

import ast

desired_dict = ast.literal_eval(module.params['json_str'])

しましょう。


なにがまずいの

Ansibleのプレイブックを書くとき、以下のように

JSONファイルを読み込ませて文字列で渡すことが多くあります。

  tasks:

- name: Update
spam_module:
state: present
json_str: "{{ lookup('file', 'ham.json') }}"

これを、モジュール内で読むには、

argument_spec.update(

dict(
json_str=dict(type='str', required=True),
state=dict(default='present', type='str', choices=['present', 'absent']),
)
)

module = AnsibleModule(argument_spec=argument_spec)

print(module.params['json_str'])

などとすることで読み取ることができるのですが

module.params内には、ダブルクォートがシングルクォートに変換されて入っています。

このとき安直にJSON変換しようとするの失敗します。

desire_dict = json.loads(module.params['json_str'])

# Fail!!!


どうするの

シングルクォートで囲まれた文字列をPythonでは抽象構文木として扱えるので、

desired_dict = ast.literal_eval(module.params['json_str'])

ast.literal_evalを使って辞書に変換すると良いでしょう。


どこで使うの

冪等性チェックのために、2つのJSONを比較したく

辞書に落とし込んで比較しました。

ただし、JSONはリストの順序保証がないですが、辞書には順序保証があるので厳密な比較にはなりません。

なんかそういうことはAnsibleにはよくあるので頑張っていきましょう。