Learning looping

So i am try to learn how to do loops in the playbook :

So suppose for example i wanted to look through all hosts get their public key and add on all other nodes, So they can have password less access. This is the best example i could think of , doing loops in playbook. This should work in template but how do i do in playbook. (yml)

{% for host in groups[$hosts] %}

  • authorized_key: key={{hostvars[host][‘ansible_ssh_host_key_rsa_public’]}}
    {% endfor %}

I would run 2 playbooks, both loop over all hosts. The first adds their keys to a file, the 2nd copies the filw

Brian Coca

Don't believe you can do this in the playbooks themselves. (Think there was
some talk of maybe allowing playbooks to be templated... don't think that
ever happened.)

I have templatesd playbooks, we generate them locally and then call ansible on them.

Brian Coca

{% for host in groups[$hosts] %}
      - authorized_key:
key={{hostvars[host]['ansible_ssh_host_key_rsa_public']}}
  {% endfor %}

Don't believe you can do this in the playbooks themselves. (Think there was
some talk of maybe allowing playbooks to be templated... don't think that
ever happened.)

Yeah, this is a terrible idea because if you do that, your playbooks
stop being valid data, and you can't just parse them by arbitrary
software.

We loop by using things like with_items.

I'd keep it simple and define an array of keys and put that in a file
like group_vars/all.

tasks:

   - authorized_key: key=$item
     with_items: $all_my_keys

It's also convient to just template out the authorized file directly,
and put your conditional logic in the .j2 file.

Thanks, This is helpful… Is there an example i can see (to populate $all_my_keys from all nodes) , Yes using templates was my last option, i just wanted to explore other possibilities.

Regards,–
Kavin Kankeshwar

Sure thing. Here is what I would try.

Either in a file specified by vars_files or in a file named
group_vars/all alongside your playbook or group_vars/groupname, I
would define something like so:

Thanks , So i should write another playbook to populate the group_vars or i can do that on the fly ?

Regards,–
Kavin Kankeshwar

You would write a YAML file, just data, rather than a playbook for this.

If your inventory is /path/hosts

group_vars/all is just a YAML text file:

/path/group_vars/all

Thanks, Related to looping:

Is it possible to do the following

my.yml

hosts=$hosts

tasks:

  • action : something $item
    with_items: $hosts

where $hosts is my group of servers im working on. So instead of putting in a list how do i create a list of all hosts this playbook is running on.

Thanks, Related to looping:

Is it possible to do the following

my.yml

hosts=$hosts

tasks:
   - action : something $item
     with_items: $hosts

where $hosts is my group of servers im working on. So instead of putting in
a list how do i create a list of all hosts this playbook is running on.

Not so much.

However, you don't typically need that kind of loop as you are already
looping over those hosts for connectivity.

delegate_to and local_action are more natural in this case.

But in case you do want it, the following is available.

${groups.all} or ${groups.webservers} etc

Just be aware that if using that inside a play, it will still get
executed once for every host in that play, so don't use it where you
really meant local_action or delegate_to

Sorry, this is probably a bit incoherrent -- I would understand much
better if we were talking about a specific use case.

So basically how do people do loop in a loop, Like playbook is looping through all the hosts in group , 1 by 1 , but for each node i want to again loop through the entire group and get something from all nodes and do it on 1 node.

Regards,–
Kavin Kankeshwar

Like 1 good example is :

So i have a group of servers,

I want to use the “with_random_choice” and make it use all the hosts in the group the playbook in running on. Then this will select randomly 1 node, Then in template i just want to use this random nodes internal IP.

How best can i achieve this, As this will give a fairly good understanding how to do things like this.

Regards,–
Kavin Kankeshwar

Ok, got it.

With random choice will select a random string element, but that
variable you select is namespaced, not a global or anything like that.

Thus you can't currently randomly select a host.

You can however assign a random probability that you select the host
(may have to write a better filter plugin to do this), which is
probably not what you want.

I'll think about syntax about how we could possibly make that cleaner.

Other folks may have some ideas too.