Ascender Pro videos

Using nested loops in Ansible

Greg Sowell explains why Ansible does not let you nest a loop directly inside another loop, and walks through the standard workaround: loop over a list while calling include_tasks, and put the second loop inside the included task file. The example playbook runs against localhost inside an execution environment, reads the passwd file, registers the usernames into a variable, and iterates over stdout_lines to call an inner task file once per user.

He highlights the loop_control and loop_var options, renaming the outer loop variable to current_user so it does not collide with the default item variable used by the inner loop. A commented-out conditional shows how to skip users that are not in a match list during testing. Inside the task file, a second loop collects the files owned by a given user, builds up a permissions variable with set_fact, and totals file counts across all users. He also notes that the pattern can be repeated to nest deeper.

The tutorial is for Ansible and Ascender users who have hit the nested loop wall and want a clean, reusable pattern, with the playbook and task file linked in the description.

Key takeaways

  • Ansible does not support nesting a loop directly inside another loop, so the workaround is a loop that calls include_tasks.
  • The outer play reads the passwd file, registers usernames, and loops over stdout_lines, which splits output into an iterable list.
  • Use loop_control with loop_var to rename the outer loop variable, avoiding a collision with the default item variable in the inner loop.
  • A when conditional can check whether the current value appears in a list, a handy way to narrow test runs.
  • The inner task file loops over files owned by the user, concatenating permissions with set_fact and accumulating a total file count.
  • The same include_tasks pattern can be repeated inside the task file to nest loops as deep as needed.

Questions this video answers

How do you do a nested loop in Ansible?

Ansible cannot nest one loop directly inside another, so you loop over your list and call include_tasks pointing at a separate task file. That task file contains its own loop, giving you an inner loop for each outer iteration. Repeat the same pattern inside the task file if you need to nest deeper.

Why use loop_var in an Ansible nested loop?

Both loops would otherwise write their current value into the default item variable and collide. Setting loop_control with loop_var on the outer loop, for example current_user, keeps the outer value separate so the inner loop can keep using item safely.

What does stdout_lines do in an Ansible register variable?

When you register a command's output, stdout holds the whole output as one string, while stdout_lines splits it at natural line breaks into a list. That list is easy to loop over, which is how the example iterates through usernames pulled from the passwd file.

About this video

Nested loops can be a little tricky when you first get started, but a quick example can make it seem pretty darn easy.

Greg Sowell is here to show how you can discover all users on the system, then loop through them to find all the files they own.

This video is part of the Ascender Pro playlist. Browse every CIQ video by product and topic.

Transcript

hey everybody I'm Greg Sowell and welcome to another ciq tutorial yeah not a demo but a tutorial so in this one I'm going to be talking about nested Loops inside of anible so this one can be a little bit tricky it was sort of weird for me uh the very first time around hopefully this one will be short I always say that or at least I always think it and they always tend to uh be me just rambling on and look what I'm doing right now anyway I digress let's jump in so Loops can't be nested very simply inside of anable it's not a

programming language that's what uh folks keep reminding me um so there are a couple of tricks that you can get around it and so I wanted to do just a little quick demonstration to show you how that works so I've got two little playbooks or actually I've got one Playbook and one task file so in here you can see it's not very complex so this one really what I'm doing is I'm just connecting to Local Host which is going to be the container itself right so when I launch this it's going to launch inside of a container because I'm using execution environment and it's just

going to look for all the users here so if you look at the very first task uh you can see that I am just uh cading the password file and I'm grabbing all of the usernames and I'm saving those into a variable named users right registering that to users so whenever you see the register parameter Tas level parameter it's taking all the output saving it into a variable well the very next one I'm doing a loop right so I'm uh you know just the standard Loop keyword you can see it here and I'm looping over users.

STD outline so you have just regular regular STD out and so that'll kind of be like one line it'll have all the the output there and then STD outline tries to find natural line breaks and will actually kind of give you a list that you can iterate over really easily and so that's what I'm doing here but you can see for the test itself what I'm doing is I'm doing include uncore tasks which will take a task file and it will run all the tasks inside of said task file so to do a nested loop I can't just do a loop inside of a block

View full transcriptHide full transcript

you know and then you know a block inside of that you can't do it that way what you do is you run a loop and you call a task file that has an additional Loop inside of it Bob's your uncle you're good to go so in here you can see I have uh Loop right I'm doing users. sdore lines um but I have some extra options here Loop control and so Loop uncore VAR I'm making that current uncore user so by default whenever you have a loop running the uh as it's iterating through the data that's being passed back right you know kind of the

contents of that variable it's coming back as a variable named item every single time it'll be item well the uh loop unor VAR allows me to change that so instead of being item it's current underscore user most of the time in my Loops I just leave it as item unless you're doing a nested Loop cuz think about it if I'm returning a variable as item and then I've got another loop that's trying to return a variable named item those are going to kind of uh Collide right you're going to have problems there so your outer loop at least um it's generally the way I do

it the outer loop at least should have a different variable name there I mean you theoretically could uh do the inner loop with a different variable name for me I like to have it as the outer that way I kind of know hey this is something different it's special in some way so anyway I digress We're looping through so for each user right that it returned here it's going to iterate through you can see I have something commented out here so I had a little match _ user variable that I created right here and I said hey if the current user I'm going through uh

or rather iterating through it's not one of these two then just skip it all right just to kind of narrow down the uh the data when I was doing some testing so it's kind of a nice little conditional if you haven't used one right there you can actually have a conditional that's looking for hey does this match anything else inside of a list it's pretty cool trick right it helps you not have to have multiple lists uh or rather multiple uh iterative Loops uh you can kind of do a little bit of Tricks here and there but I digress it will Loop through and say

for whatever the very first user is it will call this inter Loop task file right here to give the examp example of a loop within a loop uh right here I have an additional Loop for the TSS user right so it happens to be TSS user what I'm doing is essentially finding all the files that it actually owns and just looking for permissions on those right like show me all of them right so I have uh another loop inside right here so this one right here you can see that I am looping through in set fact and I'm kind of building a variable out that's going to have all

the extra uh files that are associated with it right here then you can see uh I'm not doing any variable name changing so it's always going to be returned back as item and so here I'm building the show file permissions and I am just kind of adding onto itself or or essentially concatenating additional entries onto it to make it longer and longer as it goes so uh that's for that specific user but for all users right it doesn't necessarily have to be a loop within a loop for this I'm actually getting the uh count of all of the uh files that happen to be owned

by said user that's right there and then I'm creating a total file where it adds all that up to a big total so you can kind of uh have one variable that's got all of those entries in it for whenever it comes back to this when it's complete with all the loops it will just display out the total number of files for all of said users and like any good baking show I've already baked one for us here so over here you can see that it's going to start out with the outer Loop so I'm looking at all the users or rather I'm creating a

list of all the users right it goes from Roots to user 1000 and then it's going to be hitting that um that Loop that we'll call the task file and so it's just going to be going through you could see a lot of skipping because there is a conditional Block in there right looking for the TSS user and so none of these are the TSS user so really all it's doing is it's passing that block and at the very end it's creating the overall account like how many files does this user own and then it's concatenating it to the end of that variable so you're

going to see that over and over but instead I'm going to skip to the very bottom where all the information is I'm scroll just a little bit and here's our TSS file right here so you can see the results of our nested Loop right we had a loop called the task file inside the task file we had an additional Loop and you can see all the file permissions for everything owned by the TSS user right there and available well let's skip to the very end just to have uh full completion there you can see all the users that that own files and here is the

count for them so as you can see doing nested Loops isn't that difficult it's just not exactly straightforward not maybe 100% the way you would expect it to be or at least it wasn't for me now that it's not that complex you can actually go even further down the rabbit hole so imagine I have a u a loop right for include task it calls a task file inside of that task file if I needed to go inside of yet another loop I could uh or rather Nest the loop even deeper I could do the exact same thing inside of that task file I could have

a loop that calls an additional task file and you can keep going down the rabbit hole that way to uh Nest deeper and deeper if you need to so if you have any questions or comments you tweak or tune this you can see this being used in your environment or you've used it in novel ways I would love to hear it if you're interested in some additional support for your uh automation environment we do have Ascender our Enterprise automation platform here we also have some supplementary tools uh like uh Ledger that pulls all this logging in together uh parses it gives you great information

all all the facts all the changes that are happen in your system all the packages right you could do AATA you could see packages added remove Services baselining all that good stuff and guess what you can also do reports and alerts so please reach out love to hear from from you uh Happy uh nested looping happy automating and uh if nothing else we'll see you next time bye

Built for scale. Chosen by the world’s best.

2.75M+

Rocky Linux instances

Being used world wide

90%

Of fortune 100 companies

Use CIQ supported technologies

250k

Avg. monthly downloads

Rocky Linux

9

Enterprise products

Spanning the kernel to the orchestrator

Have questions about your infrastructure?

Talk to a CIQ engineer about Rocky Linux, HPC, and AI infrastructure.

Talk to an Expert