Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible custom nested looping

I have to process output from CloudFormation Outputs that is:

Ansible code that produces this output:

- debug: 
  var: stack.stack_outputs

Output:

ok: [localhost] => {
  "stack.stack_outputs": {
    "Roles": "webserver balancer dbserver",
    "dbserver": "54.0.1.1 54.0.1.2",
    "balancer": "54.0.2.3",
    "webserver": "54.0.2.5 54.0.2.7 54.0.3.1"
}}

With that, I want to create 3 (dynamic number!) groups named accordingly filled with appropriate IPs.

Ansible code that I want to HELP WITH:

- name: fill roles with proper hosts
  local_action: add_host hostname={{item}} groupname={{role}}
  with_whatever: ?...?

In pseudo ansible python it would look like this:

for role in stack.stack_outputs.Roles.split():                           # Python
  for ip in stack.stack_outputs[role].split():                           # Python
    local_action: add_host hostname={{ip}} groupname={{role}}            # Ansible

Note:

The way to do it for these three roles statically is obviously:

- name: fill role WEBSERVER
  local_action: add_host hostname={{item}} groupname=webserver
  with_items: stack.stack_outputs.webserver.split()
- name: fill role DBSERVER
  local_action: add_host hostname={{item}} groupname=dbserver
  with_items: stack.stack_outputs.dbserver.split()
- name: fill role BALANCER
  local_action: add_host hostname={{item}} groupname=balancer
  with_items: stack.stack_outputs.balancer.split()

I want to do it dynamically, is it even possible in Ansible?
Yes, I can use shell module to hack it putting everything in temporary file and then looping over that; but is there a better solution?

Thanks for any suggestions.

like image 720
DinGODzilla Avatar asked May 15 '26 06:05

DinGODzilla


1 Answers

I understand you want the answer to fit a very specific framework. Within that, a custom lookup_plugin is your best bet. Otherwise it'll be an ugly sequence of set_fact and add_host. Sophisticated control structures are the antithesis of Ansible.

You don't explicitly rule out the following, so even if it's too out of the box for you, consider it because I've been reconciling cfn and ansible for a good long while:

Don't use stack outputs to fill your inventory. Use a dynamic inventory script for that (e.g. one that goes over stack outputs or tags set in the templates).

I'm aware of the implications like, you can't have this in a single playbook, but if that's paramount, use group_by.

Hope this helps.

like image 51
nik.shornikov Avatar answered May 19 '26 02:05

nik.shornikov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!