Ascender Pro videos

Building an Ansible playbook to verify the XZ CVE version

Rather than presenting a finished playbook, Greg Sowell records himself writing one from scratch, lookups and false starts included. The example is timely: a quick report that runs xz --version across hosts and flags any machine whose xz-utils build matches the versions tied to the XZ backdoor CVE. He notes that Rocky Linux is not affected, but the same approach applies to whatever the next critical vulnerability turns out to be.

Working in VS Code with two-space indentation, he starts the play with a name, hosts, gather_facts: false and an empty vars section for documentation, then adds a shell task that registers its output to xz_version and a debug task that prints it. In Ascender he creates a project pointed at his public Git repository with update revision on launch, builds a job template, and iterates against a single Rocky Linux 9 host. Inspecting the JSON output reveals stdout_lines, so he adds a when condition that compares the first line to the vulnerable 5.6.0 and 5.6.1 strings and rewrites the debug as a message naming the inventory_hostname and its version.

The final run targets a new inventory group of two hosts, demonstrating how to keep hosts: all in a playbook and rely on the limit field instead. Greg closes with ideas for turning the check into remediation or an emailed HTML report built from a Jinja template.

Key takeaways

  • Always name your plays and tasks; the name field doubles as documentation and appears in the job output.
  • Greg defaults to gather_facts: false and an explicit vars section at the top of every playbook to save time and document variables.
  • Register the output of ansible.builtin.shell running xz --version, then inspect stdout_lines in the Ascender JSON output to build a match.
  • Put when conditionals at the top of a task, right under name, so they are not lost beneath long module parameter lists.
  • Using hosts: all with the job template limit field avoids editing a version-controlled playbook every time the target set changes.
  • Enabling update revision on launch on the project resyncs the repository before each run, which speeds up iterative development.

Questions this video answers

How can I check which servers have a vulnerable xz version with Ansible?

Run xz --version through the shell module, register the result, and add a when condition on the first line of stdout_lines that matches the vulnerable version strings, 5.6.0 and 5.6.1 for the XZ CVE. A debug task then prints the inventory_hostname and version for each matching host, giving a quick report across your infrastructure.

What is the difference between the hosts field in a playbook and the limit field in Ascender?

The hosts field in the play sets the broadest target, often all. The limit field on the Ascender job template narrows that to specific hosts or groups at launch time. Leaving hosts as all and using limit means a playbook under version control does not need editing when targets change.

Should Ansible conditionals go at the top or bottom of a task?

Greg recommends placing when directly after the task name. Some modules, such as VMware VM cloning, take twenty to thirty lines of parameters, and a conditional buried at the bottom is easy to miss. Putting it at the top makes the run condition visible immediately.

About this video

I thought it was high time to walk you through how I develop playbooks, so I chose a simple example to show: verifying the version of the installed XZ package.

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

Transcript

hey everybody I'm Greg Sowell welcome to another ciq tutorial you thought I was going to say demo you are incorrect I'm doing a tutorial this time or at least I'm going to call it a tutorial it's really going to be hey let's figure this thing out together so I'm going to do something I've wanted to do for a little bit which is to write a Playbook and record it and kind of uh hopefully edit down the process so it's not as painful but uh I'm going to be doing some Googling and I'm going to be looking some stuff up because I just I can't

keep everything in my brain and I wanted you to see kind of the process I follow when I'm actually developing this stuff your mileage may vary I'm going to go ahead and say that right out of the box so what I'm going to be writing a playbook for today is a really quick fast dirty simple Playbook that will check for the XY vulnerability which is absolutely top of everybody's mind right now uh Rocky Linux isn't affected otherwise I would have really quickly put out uh A playbook that kind of demonstrated that but I thought hey you know if it is you know the next big

cve that hits you know and I need to check all of my infrastructure to see if the XC version is you know compatible with whatever the exploit was right then uh I need to create a list of all those or you know maybe create a list and um do remediation or just do remediation or whatever your case happens to be in this instance I'm just going to be uh developing A playbook that's going to check all of my hosts in here and it's going to evaluate and uh I'm going to say it's going to develop a list of all of the compromise versions but maybe

I'll just do a list of everything right it's kind of inlux and process so let's get started I've got my Ascender here I actually do my development through Ascender when I say through I mean I'm going to be running all my Automation in Ascender I'm actually going to be creating all of my playbooks in VSS code Studio so let me pop over to my vs code uh virtual Studio code uh so I have uh this connected to my public G repository so anything I create in here is going to be available to you and you can look through the history and see how dirty these configurations were but uh in here I'm just going to right click do new file and we'll call it uh check XZ version.

View full transcriptHide full transcript

yml now whenever you specify something as yml inside of uh vs code it actually will do syntax highlighting for uh yaml files and so something I always say is whenever you're creating your yaml files do spaces do two spaces don't hit the Tab Key now if you create a file that's yml inside of vs code and you hit the Tab Key guess what it's going to do it's going to do two spaces so I kind of eat my own words when I say that but it's kind of a good practice to go ahead and get accustomed to just putting in spaces so I tend to hit spaces you'll probably hear that as I'm bangging on the keyboard but we're going to start out with our three dashes they indicate it's a yo file I'll do.

name technically the name fields are usually um optional in my case in my estimation they are always mandatory you should always be putting this here um because it's it's just documentation and as you see the output when we run the thing pop out it's actually going to display well what's the overall purpose of this that's what the name portion up at the top is I'm naming the play right A playbook could technically have multiple plays I generally only have one play per and so I will say uh generate a report on uh XC versions we'll call it that next we're going to have the host

portion for now I'll just say all it's going to be my little placeholder gather uncore facts I'm going to do false on that which is kind of a my default go to I may end up using gathered facts and I may turn this back off uh or I might disable that uh right there or comment it out uh but for now my default is always turn off gather facts because that's going to slow down my operation a little bit if I don't need it and I really don't think I am so I always create a VAR section so if I'm going to have any variables

that are going to apply to all of the tasks in here I put them up in the VAR also use that for documentation so then I will add my task portion and now I'll start doing some kind of pseudo coding so I'll do name and then what's the very first thing I want to do I want to um shell command to gather XY version seems pretty straightforward so I'm going to do that after that I will do a uh let's just do a debug let's just spit out uh the contents of the variable to screen that way it makes a little bit easier to kind

of see what's going on so I will uh display uh XC we'll call it XC version that's what we're going to name the variable XC version to screen we'll just do that so in here I'm just going to is to a shell command that's going to be an. builtin do shell now notice that I indented in the uh module name right there uh to be in line with the name portion so uh as you see like at the beginning of my task I have kind of that Dash or minus whatever you want to call that uh because this is a list of tasks we're going to be operating under so everything's going to uh for an individual task will live under said task so it needs to be indented in so an.

shell and we will do uh xc-- version and we're going to register this so the register option basically says take all the outputs you get right here and stick it into this variable so I'm going to say register uh the output to uh xcore version that's going to be my variable name we go ahead and put a space after that I will do anible do buil in.

debug and I had two options here I can do message and I can formulate a message but for now I'm just going to spit it out to screen and I'll do VAR and whenever you're using the VAR option you don't use any double quotes or double curly braces so in here I'm just going to purely put xcore version that should be a good first run now I don't want it to necessarily run against all my objects so I have an inventory in here that I've named generic inventory because I have just some generic hosts in here so you know what I'm going to run it

against uh Greg Rocky 9 now I could leave that option to all but I'm not going to do that I'm just going to go ahead and set it for this one individual host really quick I could update um the limit section to uh Greg Rocky 9 in the job templet itself so even though the Playbook is saying all the limit section will then narrow narrow down to other individual hosts or groups that I want to operate inside of there but just for my quick and dirty example I'll just do this so I'm going to save that come over here to the source control menu I'll

just put in some junk you should probably put in real messages but when I'm developing I'm too lazy to do that so I just hit DD and I sync that now I need to add uh these playbooks in so I'm going to create a project so I'm going to click add for the project the name I will make it uh XZ version demo we'll call it that I'm going to tell it to use a get repository maybe it's this one yeah so I've got my get repository right here so I'm just going to copy the URL switch back over under Source control I'm going to

put in that URL now if this was a priz repository which is most likely the case for you you would have to choose your credentials here mine however is just in a public G repo also while I'm developing I like to have update revision on launch and what that does is before I launch any piece of automation it's going to resynchronize this project so it's always going to make sure it's got the newest version of my playbooks in here so while I'm iterating really quick if I want to uh update the Playbook I'll uh you know I'll run into vs code I'll update the Playbook

and then I'll just fire the job off again and it'll go ahead and refresh that inventory or rather that uh project so it'll go pull those new files and STI in here so we successfully synced I already have credentials to connect to this host again I already have that inventory that I had created right because I've got all my stuff already so I'm going to go to the template section this is where I'm going to tie it all together I'll add a new job template and we'll name it XZ version check demo inventory that was going to be the generic inventory let me switch screens

actually I'll just type gen for generic here's my generic inventory I'll select that the project is going to be the one we just created I'll say XZ to find it really quick there's my version demo select select uh technically I would normally have to hit this drop down and pick a Playbook since there was only a single playbook in that uh repository it went ahead and chose it for me so keeps live simple in here I'm going to choose my credentials to connect to the server with and technically I'm done remember earlier I talked about how in my playbook itself so in this playbook in

the host portion I changed it from all to greg- rocky9 I could leave that as all in there if I wanted to and then just in this limit section put Greg rocky9 I do that I'm just going to leave it the way it is and I will go ahead and click save and I will launch this and so it should connect out to that host pull all that information do the magic of editing like now and through the remainder of this demo uh you won't have to wait on anything I'll just cut out the little pauses now that it has completed the run I can see it ran the show Command right there let's

have us a look see at the output so I'll click on it click on Json it'll show me all the output so it's showing me here's the XE version and so you have some extra information like change true STD out and then we should have STD out lines as well right so STD Out Lines I can see that I have got two entries in here one's going to be the XC utils itself and then here's the live lzma output and so really I only need to check one of these and I need to check the version number in there it's going to be two versions

that it's going to equal to if it is a problem so let's just match to that let's do that let's pick this statement in St outlines and match that right there so I'm just going to kind of copy that little bit of text let me pop back into VSS code and I will just put a hashtag or pound sign there as a comment comment that out as well just so I can visualize it so let's do a little test let's do a little testy test on running this so let's put a conditional on here we'll say when and conditionals can be put at the very

bottom or put at the top a friend of mine Jimmy Connor an awesome automator he said uh you know what some of these uh modules actually get really long so if you ever look at like cloning a VMware VM like it is insanely long it's like 20 to3 lines for one module call well if you put a conditional at the very bottom of that or say you have a block with several of those and you put a conditional you're going to lose that thing so the best practice and and or maybe good practice I try to say best practice a good practice is to put

the conditional up the top that way immediately after the name you see the conditional associated with it like it's only going to run if these conditions are met so in here let's say uh XZ underscore version is equal to or actually we'll say xcore version dot St TD Out uncore Lines uh whenever that and we're going to say the very first iteration in that Loop is equal to uh we'll just copy this right here when it equals this go ahead and run uh this task right so since what we're doing is we're running the chck up above it put a little space there to make

it a little bit easier to look at uh so what we're going to do is we're going to run the initial shell command that's going to generate the output and then next we're going to say hey only spit it out the screen if this thing actually meets this criteria right so if an STD outlines the very first line is equal to this we're going to have to spit out this is actually a safe version but for this example we're just going to use that as our like like bad version so that we we it'll immediately show me output whether it's matching or not synchronize those

changes I'm going to come back in I'm just going to fire that same job off again that seem to work okay let's try it by changing the version number and seeing if it doesn't match see if we get a skipped condition come in here I'll change it to a four I'll save that and then I'll go ahead and commit that to my repository as well so technically it should show skipping on this now because it didn't meet like the requirements here didn't meet my conditional criteria let me fire that job off again now remember it's automatically refreshing because on the project I said update Source

on launch so that means anytime I fire this piece of automation it's actually going to go and check their repository for the newest version of the playbooks otherwise I have to go into the project and sync every single time before I ran otherwise it's not going to have that newest version of The Playbook so we had details output and now we see skipping right we saw skipping because I had changed the version numbers on there so therefore it didn't actually meet the criteria so we should be good in that respect so now I can modify my playbook a little bit say uh let's actually make

it match the versions that are actually vulnerable so I go little earlier and it's 560 and 561 so I'm going to come in here and we'll say if it is five 6 0 I'm do I'm just going to copy this whole line right here I'm going to say if it's 5 60 or if it's 561 right so if uh the utility on the output either matches 560 or 561 go ahead and perform this operation so it'll spit it out to screen all right but you know what I'm going to do I'm going to actually change this message so I'm going to highlight that I'm going

to hit control forward slash that's going to comment it out and instead of doing a VAR I'm going to do a message and I will say what are we going to say here I will say double curly braces uh anible underscore or no inventory unor host name which is a magic variable which essentially is whichever host I'm operating against right now kind of uh like for this individual task it's get it gets replaced with inventory host name so we're going to say um it'll be like greg- rocky9 is vulnerable Rubble to the exploit and I will spit out its version number so that you can

see right on screen which version it is running and we'll do double curly braces so inside the message I actually have to form it like almost any other parameter like any other um module parameter so I've got to do uh double quotes and double curly braces for stuff and so the double quotes really just live outside the entirety of the message if I have any variables inside all I have to do is putting in uh double CR braces so it should also spit out the version that it's got in there so it's going to say inventory host name blah blah blah I'll go ahead and

save that and I'll just do DD commit sync and then I will run that piece of automation again remember just going to go ahead and refresh it really quick and now on this again I expect it to say skipping on that output now right here you see how it doesn't have any output if I just click details and output again everything pops up as it should so I should see skipping I really just wanted to see did I put any syntax errors inside my playbook if I did it's going to pop up and it's going to give me an indication of what those were so now let's change it to where it uh actually is one of the uh version cuz I I know in my environment I don't actually have any exploited versions so I will change this to 5 do 2.

five and I will save that so now I know I'm actually going to get some interesting output here I'm going to pop back over here I'm going to give it a launch so as you can see it spit out greg- rocky9 is vulnerable to the exploit so let's change uh the host so that it will actually uh gather a little bit more information or rather let's change it so that it runs against multiple hosts just so we can see kind of what it would look like in the output let me check in my inventory to see if I've got let me see generic inventory here

we are what groups do I have in here actually let me look at the host tab I could see if they're both a member of an individual or a s similar group words are tough sometimes let me uh create a group really quick just for a fun I will create one named Greg rocky9 group how fun we'll click save and then I will add hosts I'm going to say add existing hosts and I'm going to add these two Bellas in there now they're part of that group so I will copy and paste the name of that group and I'll put it right up here at

the top so it is the Greg rocky9 grp group that we're going to be operating against I'll save that commit now if I were to use the all group uh that means if I want to actually change what host it's operating against I never have to touch the Playbook right if I do have Version Control and things like that and I have to go through change procedures I probably don't want to be changing this Playbook very often so if you leave it as all then you can just do the limit section and since this is really just spitting out um informational stuff it's not actually

making any changes it's pretty safe to do that now I could and I've done before I have a couple of tasks I can add at the beginning that checks to make sure that you're not running it literally against the all group just in case you could be potentially doing some uh breaking changes so it really looks to check and make sure that you're actually using the limit option in here I'm not going to necessarily do that I will just go with what I've got right now uh so it should be running against two host let's go ahead and fire off that piece of automation again

so I'm going to come back to my Ascender I will click on templates and this has XZ in the title I'll find it I'll click the Little Rock ship right there launch it off and let's see what happens it should be showing up on Two Hosts now all right so it ran against all of my hosts here and you can see it's showing 5.2.5 so theoretically if this was one of the vulnerable versions it's going to pop up in the list right right I I obviously artificially set it so that it's it's not one of the vulnerable versions just so you'd have some output here

uh the rest would say skipping if it actually was checking for those vulnerable versions but you can see this was a super quick and dirty way to get a report I could literally run against my entire infrastructure looking for this information and then uh I could use that for remediation as well so I could also bake in the remediation steps often times it makes sense to just run a report first just to see what you're working with if it is like a really important production machine and you're afraid you might brick something maybe you don't necessar want to do the remediation immediately against this thing

um right your mileage may vary it entirely is dependent on your situation your scenario some people are in like air gap networks and so it's less a big problem so maybe just identifying those would be good to start with uh and then doing the remediation after that or just finding ones in specific environments that need remediation now I said uh this is just doing a really quick uh onscreen like spit out a report right here I actually wrote a um with the help of a buddy of mine Nick he actually created the ginger template for me a uh Reporting System whereby I can have it

Go and collect any information from any kind of thing and it will build a uh HTML report and email that to you so it's a nice pretty formatted table and it automatically builds all the cool pieces so I could do that as well so I could have it just develop a report and put all that stuff in there with a roll I actually have a blog post showing you how to do all that stuff if you are so inclined if you have any questions or comments I would love to hear them um I don't think I've ever done a live demonstration of me kind of

on the Fly figuring things out in the playbooks I didn't actually have to look too much up um I kept it so simple that it didn't really require me to uh go digging around in there but I digress even people like me who work with automation all the time have to look stuff up up constantly because I can't keep this stuff in my head so here's just a quick example of doing that now if you want some assistance with this stuff us over at ciq our team we are happy to assist with Professional Services or Ascender this cool automation platform you see here running all

this interesting stuff uh it is um something that we are very proud of and we would love to help you set up a cluster or configure it or teach you to use it or any way we can assist please feel free to reach out and if nothing else have automating happy uh I guess verification of your systems reporting 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