1

I have a ansible task which runs a python script to get the cron schedule time as follows

- name: check the expiry of node certificates using python script
  shell: python /opt/cron_exp.py
  register: cron_schedule
  when: inventory_hostname in groups['kubemaster']

The output of the script is a dictionary (print in python) which is captured by the register cron_schedule as follows:

- debug:
    msg: "{{cron_schedule}}"
  when: inventory_hostname in groups['kubemaster']


MSG:

{'stderr_lines': [], u'cmd': u'python /opt/cron_exp.py', u'end': u'2021-01-06 03:59:45.980785', u'stdout': u"{u'node1': {'month': 12, 'hour': 11, 'minute': 2, 'day': 8}, u'node3': {'month': 12, 'hour': 11, 'minute': 2, 'day': 8}, u'node2': {'month': 12, 'hour': 11, 'minute': 7, 'day': 8}, u'master': {'month': 12, 'hour': 11, 'minute': 2, 'day': 8}}", u'changed': True, u'rc': 0, 'failed': False, u'stderr': u'', u'delta': u'0:00:00.632724', 'stdout_lines': [u"{u'node1': {'month': 12, 'hour': 11, 'minute': 2, 'day': 8}, u'node3': {'month': 12, 'hour': 11, 'minute': 2, 'day': 8}, u'node2': {'month': 12, 'hour': 11, 'minute': 7, 'day': 8}, u'master': {'month': 12, 'hour': 11, 'minute': 2, 'day': 8}}"], u'start': u'2021-01-06 03:59:45.348061'}


Here the ansible hosts are master, node1, node2... I want to set the cronjob in all the hosts by referring to the python dictionary output key with hostnames and respective values having month, hour , minute and day. To achieve this, I have tried to use loop for the dict as follows:

- name: Set a cronjob 
  cron:
    name: "origin node restart cron"
    minute: "{{ item.value.minute }}"
    hour: "{{ item.value.hour }}"
    day: "{{ item.value.day }}"
    month: "{{ item.value.month }}"
    job: 'service origin-node restart'
  when: inventory_hostname in groups[item.key]
  loop: "{{ lookup('dict', cron_schedule.stdout) }}"

But its throwing the error as follows:

fatal: [master]: FAILED! => {}

MSG:

An unhandled exception occurred while running the lookup plugin 'dict'. Error was a <class 'ansible.errors.AnsibleError'>, original message: with_dict expects a dict

I tried with_dict instead of loop as suggested here Ansible with_dict expects a dict but no luck

Please help me to debug this or is there any alternative that I can try.

Note: Ansible version: 2.9.5

Rakesh Kotian
  • 175
  • 3
  • 20
  • 3
    As explicitely reported by your error message, remove jinja2 markers. A `when` stanza should be a raw jinja2 expression as explained in the [documentation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#basic-conditionals-with-when) => `when: inventory_hostname in groups[item.key]` – Zeitounator Jan 06 '21 at 08:14
  • Thanks, i tried your suggestion but now i get a different error: ```The conditional check 'inventory_hostname in groups[item.key]' failed. The error was: error while evaluating conditional (inventory_hostname in groups[item.key]): Unable to look up a name or access an attribute in template string ({% if inventory_hostname in groups[item.key] %} True {% else %} False {% endif %}). Make sure your variable name does not contain invalid characters like '-': argument of type 'AnsibleUndefined' is not iterable ``` – Rakesh Kotian Jan 06 '21 at 08:58
  • 2
    The dictionary you want to iterate is in `stdout`. Try `loop: "{{ lookup('dict', cron_schedule.stdout) }}"` – Vladimir Botka Jan 06 '21 at 10:18
  • Thanks, I have updated the question with observations, recent tries done based on yours and @Zeitounator suggestions – Rakesh Kotian Jan 06 '21 at 11:07
  • 2
    Put up a debug task and use `msg: "{{ cron_schedule.stdout | type_debug }}"` to find out that your var is a `str` and not a `dict`. Since that string is still a valid json representation of a dict, convert it so json using the [`from_json` filter](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#formatting-data-yaml-and-json) – Zeitounator Jan 06 '21 at 12:04
  • Great, this solved my issue. thanks , please post as answer – Rakesh Kotian Jan 07 '21 at 00:45

0 Answers0