1
votes

I am using a shell script and Ansible to stop services in a defined order. Ansible uses Jinja template and shell is used to get services and node in which it needs to be stopped

Let me explain my current setup. Shell line which calls the playbook $targetappname relates to services, $node relates to key/value in a playbook which contains the services in that node.

ansible-playbook -i inventories/<<systemname>>.ini --limit "$node"  playbooks/stop-services.yml -t  -u "$1" --ask-pass --ask-become-pass --extra-vars "mode=$mode target_app_name=$target_app_name"
      ;;

systemname.yml

[host1-n1]
host
[services in that:vars]
components=service1,service 2

[host2-n1]
host
[services in that:vars]
components=service1,service 2

[host1-n2]
host
[services in that:vars]
components=service1,service 2

[host2-n2]
host
[services in that:vars]
components=service1,service 2

[node1:children]
host1-n1
host2-n1
[node2:children]
host1-n2
host2-n2

services yml file

{"stopOrder":{"node1":['service1','service2'],"node2":['service1','service2']]}}

stop-services.yml

---
- name: somename
  hosts: {{node}}
  become: true
  gather_facts: false
  role: stop-services
  vars:
      - stop_apps: |
             {% for list in services.stopOrder.{{node}} if mode=='all' -%}
 ........
.........
..........
.........  

I want the last line of the above code to pick services.yml-> stoporder->node selected by user during shell execution.

I am not sure how a shell variable can be used to call a particular node which is inside services.yml.

1
edit the question and make it minimal reproducible example, i.e. remove what is not needed. Somebody already downvoted your question because of this, I think. Your question might be closed if you miss the rules. Welcome to SO!Vladimir Botka

1 Answers

0
votes

Q: "How a shell variable can be used to call a particular node that is inside services.yml?"

A: For example the inventory, playbook, and the script below

shell> cat hosts-130
node1
node2
shell> cat test-130.yml
---
- hosts: "{{ node }}"
  gather_facts: false
  tasks:
    - include_vars:
        file: services.json
        name: services
    - debug:
        msg: "{{ services.stopOrder[inventory_hostname] }}"
shell> cat test-130.sh
#!/bin/bash
ansible-playbook -i hosts-130 test-130.yml -e node=$1

gives

shell> ./test-130.sh node2

PLAY [node2] *******************************************************

TASK [include_vars] ************************************************
ok: [node2]

TASK [debug] *******************************************************
ok: [node2] => 
  msg:
  - service1
  - service2

Use jq if you want to iterate all nodes from the dictionary, e.g.

shell> cat ./test-130.sh
#!/bin/bash
for node in `cat services.json | jq '.stopOrder | keys[]'`; do
    ansible-playbook -i hosts-130 test-130.yml -e node=$node
done

The data in the file is JSON. I'll name it properly (to avoid lint's warnings)

shell> cat services.json
{"stopOrder": {"node1": ["service1", "service2"], "node2": ["service1", "service2"]}}