Python
Ansible

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にはよくあるので頑張っていきましょう。