Here is my script , i am trying to send a message to multiple slack channels, using loops. I have defined variable inside variable.
- name: send msg to slack
community.general.slack:
token: XXXXXXXXXXXX
blocks:
- type: section
text:
type: mrkdwn
text: |-
****text message********
channel: '{{ item.slack_channel }}'
username: 'slackbot'
parse: 'full'
loop: "{{ slack | default([]) | selectattr('slack_channel') | list }}"
when: inventory_hostname == 'abc.xyz'
vars
slack:
- slack_channel: '#mychannel'
- slack_channel: '{{ slackchannel1|default(None) }}'
- slack_channel: '{{ slackchannel2|default(None) }}'
slackchanne1 and slackchannel2 variable are optional, sometimes i will define value but sometimes i won't define value
What i want is -
When a script is triggered, message has to send to all slack channels, but if the variable is not defined then i don't want loop to run and get fail, incase if it run and no variable found then it should't say play failed, it has to skip that loop cause no value is defined for variable slackchannel1 and slackchannel2 , at the end play should be successful with single defined variable vlaue - slack_channel: #mychannel
error i am getting
fatal: [abc.xyz]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'msg'\n\nThe error appears to be in 'tasks/slack.yml': line 303, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: send msg to slack\n ^ here\n"}
Use default(None) to avoid error "'slackchannel1' is undefined"
slack:
- slack_channel: '#mychannel'
- slack_channel: '{{ slackchannel1|default(None) }}'
- slack_channel: '{{ slackchannel2|default(None) }}'
Then, select defined items
loop: "{{ slack | default([]) | selectattr('slack_channel') | list }}"
Quoting from selectattr
If no test is specified, the attribute’s value will be evaluated as a boolean.
For example, the playbook
shell> cat playbook.yml
- hosts: localhost
vars:
slack:
- slack_channel: '#mychannel'
- slack_channel: '{{ slackchannel1|default(None) }}'
- slack_channel: '{{ slackchannel2|default(None) }}'
tasks:
- debug:
msg: "{{ item.slack_channel }}"
loop: "{{ slack | default([]) | selectattr('slack_channel') | list }}"
shell> ansible-playbook playbook.yml
gives
ok: [localhost] => (item={'slack_channel': '#mychannel'}) =>
msg: '#mychannel'
When the variable is defined
shell> ansible-playbook playbook.yml -e slackchannel2=test
the playbook gives
ok: [localhost] => (item={'slack_channel': '#mychannel'}) =>
msg: '#mychannel'
ok: [localhost] => (item={'slack_channel': 'test'}) =>
msg: test