Passing Ansible variables in workflows using set_stats
set_fact is scoped to a single playbook, so variables created in one job template of an Ascender workflow do not reach the next. The set_stats module is the trick that carries them across, but its documentation says nothing about workflows and little about when to flip its per_host and aggregate parameters. Greg Sowell builds a two-node workflow, one job template that gathers facts and sets stats in several combinations and a second that simply displays what arrived, then walks the output alongside the playbook.
The findings are concrete. Stats are handed to the next job as extra vars. Anything set with per_host true is not passed at all. With aggregate true, values from different hosts are smashed together into one value, so two hosts reporting 8.8 and 8.6 produce a merged result; with aggregate false the last host to run overwrites the variable. None of that gives true per-host data.
The workaround uses Jinja: default to an empty dictionary, then the combine filter to merge in a new key for inventory_hostname holding facts such as the distribution version, with aggregate true so every host contributes. The next playbook can then index the dictionary by hostname. The video assumes familiarity with playbooks, inventories and projects, and suits anyone building multi-step workflows in Ascender, AWX or AAP.
Key takeaways
- set_fact is scoped to one playbook, so set_stats is needed to pass variables between job templates in a workflow.
- Values from set_stats arrive in the next workflow job as extra vars, not as facts.
- Setting per_host true causes nothing to be passed to the following job template.
- With aggregate true, values from multiple hosts are merged together; with aggregate false the last host to run wins.
- Per-host data can be faked by combining a dictionary keyed on inventory_hostname using default({}) and the combine filter.
Questions this video answers
How do you pass variables between job templates in an Ascender or AWX workflow?
Use the set_stats module with the data parameter listing the variables to pass. The workflow hands those values to the next job template as extra vars. Standard set_fact variables stay inside their own playbook and never cross the workflow boundary.
What do the per_host and aggregate options of set_stats do in a workflow?
per_host true keeps stats per host, but those values are not passed to the next job at all. aggregate, which defaults to true, merges values from all hosts into one combined value; aggregate false means each host resets the variable, so whichever host ran last is what gets passed on.
How can you pass per-host information through set_stats?
Build a dictionary instead of a scalar. Use default with empty braces so the variable exists on the first pass, then the combine filter to add a key for inventory_hostname holding the facts you need, with aggregate true. The next playbook reads the value by indexing that dictionary with the hostname.
This video is part of the Ascender Pro playlist. Browse every CIQ video by product and topic.
Transcript
foreign I'm Greg Zoll and welcome to another ciq demo so today's demonstration is going to be passing information in Ascender workflows right so whenever you create a workflow you have multiple job templates and say there's variableized information you want to pass in between those job templates how do you do that right if you do it with just kind of a standard set fact if you're trying to do that rightly so normally when we're going to create variables and we're going to save information we'll use the setback module and that's great but that scope to an individual Playbook it won't actually move between so there's
a little trick that we utilize called set stat it's a special module so in here I've created a workflow a very simple one I should say let me rearrange this I've got two playbooks one that uh is tied to a job template here right that's really just pulling a bunch of variabilized information in different formats because I want to show you exactly kind of what it does whenever you're like tweaking and tuning these settings because unfortunately documentation doesn't really clearly or even remotely State what's going on in that fashion and the second one just displays it right so here are my set stats and the
the workflow itself so step stats one that's going to grab all the information set stats two is going to display it and here's the workflow tying the two together here I'll show you in the visualizer really quick it is just run the first one run the second one nothing really cool or complex about that so I'm going to go ahead and just launch it really fast I'm assuming several things if you are curious about how information moves between workflows I'm going to operate in the Assumption you know how to write a Playbook you know how inventories Works projects all that stuff so I'm not going
to cover any of that I've done a lot of that in the getting started or quick start guides as well as the lesson plans that are coming through so if you take a look here again this one is just running and collecting all the information I'm going to take a look at the output here I'm gathering facts because really I'm just doing some fat Gathering everything runs clean and then we're going to go to the output section so I'm going to pop back into my jobs here and I will get to the one where it actually outputs everything and what I'm going to try to
View full transcriptHide full transcript
do is go back and forth between the Playbook and show you the results just to maybe make a little bit more clear if you want to gather facts you don't do anything so by default it's going to do all that stuff you can see I have gather underscore facts false I usually put that at all in my playbooks but here I commented it out because I want to use some of that information in this little demo here I have kind of the first four using the set stats module and when I say there's very little documentation let me move over to it right here here
is the set stats docs and you can see it doesn't say anything about workflows or how information moves between job templates and workflows you see there are a couple of parameters that I'm interested in one is aggregate and one is per host but really it doesn't tell you a whole lot about when to turn these knobs it kind of gives you an idea of what they do per host means keep stats on a per host basis by default it doesn't do that right so kind of the stat is just this one incrementing value and then aggregate what exactly is that going to do says it's
going to aggregate values but what does it actually look like in playbooks when you run it first you can see I am doing right here I am doing set stats using set stats module you have to use the data parameter and then all the variables you want to create go underneath that so here I am doing Pro host true and aggregate true so by default Aggregates on right that's why it's not actually specified because that is the default value but we're doing per hosts true and aggregate true here we're doing per host true again so the first two are going to be kind of on
the stats module it's going to be collecting per host stats and then aggregate false and if you take a look over here at my output whenever it gets called over or rather whenever that information gets passed over the per host values don't actually get sent over it doesn't send any of that information over period so let me show you exactly what does get sent over so this is the second job and what happens is the set stats collects information and passes that over but not on a per host basis if you specify per host it sends nothing all that information is actually right here it's
passed as extra vars right in the extra VAR section it places that information that's what gets passed over that's why you don't see those per host True Value sent because they just don't make it over right here we've got our other two that are perhurst host false and uh again that is default Behavior I went ahead and overtly put it just so you could see it in this case right here so we've got a per host false with a aggregate true and then down here we've got an aggregate false and so what does that look like aggregate true one of those hosts is returning 8.8
and one is returning 8.6 as you can see when you aggregate stats it is just smashing those values together so it'll just keep smashing them into one big giant thing so not always the ideal Behavior sometimes that might actually be the case and be useful but not always what you're looking for if you have aggregate false that means it's not going to do that aggregation and this just keeps getting reset so every host that runs will reset this value to something new and whatever happened to run absolutely lasts in this case 8.6 that's what actually gets passed over as extra VAR now that's not always
the ideal Behavior Sam setting some specific setting that makes sense to be used across all hosts or it's just some informational value or maybe some kind of counter that I'm creating it could work well right to have one kind of one value one variable to represent everything right but what if I actually did want to pass over per host information well you can kind of fake it and this is my work around right here again trying to show you a couple of different options and what happens when you tweak those knobs so now that I've made the screen a little bit bigger it might be
easier to see the first one you can see I have aggregate false okay so it's also going to Remember by default have per host off because if we do per host nothing gets passed over but one has aggregate information false one has aggregated information true so the one that's false I am building everything and you can see it only passes over one host worth of information so whatever ran last that's what overrides the variable and gets passed in the second one I have aggregate true so that means it's going to allow all those hosts to kind of pump in information so you could see I
had two hosts one is Greg rockrocky 86 LTS one's Greg Rocky 86 non LTS and so you can see I'm keeping per host information so if I wanted to in my second Playbook where this information gets passed I can look at this dictionary and I can put in inventory host name right like variable name and then in Brackets inventory host name and then I can reference the version variable after that to have this very specific hosts information let's break down just a tiny bit what I'm doing right here in the variables you can see they're both created the same way what I do is I
have the variable name and then I will inside of the double quotes double mustaches I have the variable name again I'm piping that and so whenever I'm piping it I'm moving it to an additional plug-in to do some other operation to it here I have default and then one bracket one bracket or one curly brace one curly brace close and what that does is that sets up an empty dictionary so if I am trying to run this and it's the very first iterational Loop and that variable doesn't exist rather than airing out it will just say oh default value for this is just make it
just make it a blank thing then it's going to pipe it and it's using the combine plug-in and what the combined does is it will take two dictionary multiple dictionaries however many you want and it will kind of combine them together and you can see I have one curly brace there I'm doing inventory hostname right that's the variable of or rather a magic variable which is one that's known to ansible and inventory hostname is what's the host that I'm actually running on right now what's its inventory name so it'll put that foreign and then it'll go down a level right so it'll break underneath it
in the dictionary it'll have version is the new key and the new value is going to been be a variable and these are some of the facts that we collected right the ansible facts distribution underscore version and I can keep going down the level I could actually uh use this in kind of a loop fashion to develop this right to kind of Flesh this out if I want to I can Loop it down below and then build what that Loop information looks like pass that in so they're all multiple ways of kind of adding extra information in here but hopefully this gives you an idea
of how you can not only pass just regular information regular you know standard collection maybe statistic information over but also how you can fake it and do per host information well thank you for your time today I hope you learned a couple of things I know this can be kind of tricky if you have any questions or comments I would love to hear from you if you would tweak or tune this to fit in your environment I'd love to hear that too if you are tired of counting nodes and you wish there was a better way guess what I can help you with that as
well we have awesome support on this product so thank you keep automating keep workflowing happy set starting and 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.
