Score:0

How to set a task to run for a specific inventory group?

uz flag

The following task:

- name: Download Jfrog Artifcats
  ansible.windows.win_shell: |
    $ENV:JFROG_CLI_OFFER_CONFIG="false"
    jfrog rt download ...
  when: ???

should run only for machines that are located under center in the appservers group

---
all:
  children:
    root:
      children:
        center:
          children:
            appservers:
              hosts:
                vm1.domain.com:
            qservers:
              hosts:
                vm2.domain.com:
            dbservers:
              hosts:
                vm3.domain.com:
        mobilefarms:
          hosts:
          children:
            gateways:
              hosts:
        south:
          children:
            brooklyn:
              hosts:
                vm4.domain.com:
              children:
                clients:
                  hosts:
                    vm5.domain.com:
                    vm6.domain.com:
        north:
          children:
            new_york:
              hosts:
                vm8.domain.com:
              children:
                clients:
                  hosts:
                    vm9.domain.com:

What should I type as a condition under when in order to accomplish this? Also, What is the principle behind this configuration option?

Semicolon avatar
jo flag
when: inventory_hostname in appservers Not sure what you mean by "what is the principle behind this"
uz flag
@Semicolon, I want to know how am I reach to a wanted group. For example: ```appservers``` under ```center```, or ```gateways``` under ```mobilefarms```, or all machines under ```north``` and so on...
Score:2
jo flag

In order to use group membership in a conditional for a task, play or block, you would use the format:

when: inventory_hostname in groups["<group name>"]

Specifically to your initial question:

when: inventory_hostname in groups["appservers"]

To reach all machines under north, you would simply change it to: when: inventory_hostname in groups["north"]

In regards to your follow up clarification (specifying a group in a particular "location"), as group names must be unique in ansible, there's no need to distinguish which appservers group you're referring to, as appservers can only ever be in one location.

If you attempt to create two appservers groups, only the first one would actually be parsed by the ansible engine; any subsequent group of the same name will be ignored. So, if you were planning to (in the future) have an appservers group under north and an appservers group under south, you'll find that only members in the first group will be included.

In ansible, how we achieve this (my assumption of what you may want in the future), the ansible way to proceed is to add the hosts to multiple groups like so, and adjust your limit or conditional appropriately:

all:
  children:
    north:
      hosts:
        a.domain.com:
        b.domain.com:
    south:
      hosts:
        y.domain.com:
        z.domain.com:
    appservers:
      hosts:
        a.domain.com:
        y.domain.com:
    dbservers:
      hosts:
        b.domain.com:
        z.domain.com:

In this example, if you wanted all app servers, you would just target appservers. If you wanted only appservers in the north region, then you would set your limit on the play to north:&appservers, or alternatively use the conditional

when:
  - inventory_hostname in groups["appservers"]
  - inventory_hostname in groups["north"]

In any event, I think you might need a refresher in how inventory is structured in ansible, for that I would recommend the user guide; there are also some great resources on various training sites that can go into much greater detail.

For further information about more complex targeting using multiple groups (combinations, unions, and exclusions, etc), I suggest you review this other user guide.


On a personal note, initially I thought the setup was tedious and limited, but as I have become more familiar with using it, I actually find it more dynamic than the alternative.

uz flag
Thank. ```when: "'appservers' in group_names"``` - This is the only format I succeed with. But, still cannot manage to focus the condition only on ```appservers``` inside ```center``` main group. I need this focus, because some labs include ```appservers``` under ```mobilefarms``` main gourp - and those machine shouldn't include the artifact...
Zeitounator avatar
fr flag
@Hiddai A group `Sub1` wherever you define it is **one** group. If you give several definitions of `Sub1` as a children of several parent groups. the result will be a concatenation of all host/children defined anywhere. As a result, the group `Sub1` as a children of group `A` will contain exactly the same hosts as when it is a children of group `B`. See [this question/answers](https://stackoverflow.com/questions/68746910/).
Zeitounator avatar
fr flag
@Semicolon: did you mean `when: inventory_hostname in groups[<group_name>]` which translates to `when: inventory_hostname in groups['appservers']` in OP's case ? Your solution cannot work as is anyway unless the user has himself defined the var `appservers` (else you get a `appservers` is undefined error). –
uz flag
@Semicolon, @Zeitounator - I succeed now. After reading carefully @Semicolon's answer: "group names must be unique in ansible". when I change particullary center's ```appservers``` group to something like ```center_appservers``` name - It started to work like a magic. thanks.
Semicolon avatar
jo flag
@Zeitounator, indeed you are correct. I had just finished writing a series of tasks looking for a string in a hostname and just kept typing along. I've updated with the correct syntax -- using your note, but essentially just copying from an open screen I had.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.