I have a playbook that depends on knowing where a certain git repository is on the local machine. All of our developers have this repo somewhere, but no assumptions can be made about the name of the dir or its location on each dev’s computer.
What I want is this: some default variable that stores where this repo is (DIR) after a user specifies it once. I’ve managed to define what I want in a finite state machine:
Is there an efficient way to implement this in Ansible?
Without a better method, implementing this would require a lot of tasks just dedicated to checking states, which seems tedious. I’m also not sure how I would loop over the “is DIR valid” <—> “prompt” sequence.
Where will you store DIR’s value? A local file on each machine? The playbook can have a default value. Comparing the local machine’s value to the default is easy. If you plan to run the playbook remotely across numerous machines who will answer the question? Ansible really excels at executing the same tasks and configuring numerous systems the same way - configuration management. You define a particular state. Ansible ensures that is the state. If the machine doesn’t match that state, it makes a change. If the machine matches the state, no change is made. It is “declarative”. You describe a desired state. Ansible does what is necessary to make that the state.
DIR will be stored on a local file on each machine, since the setting is custom to each user running the playbook. I’ve also realized the default value is actually useless; instead I should just check for the presence of the local file – since the structure of the Ansible dirs are known, this is simple enough to maintain. This will never be run remotely (it is part of a local setup for a remote process).
I suppose I was just wondering if there was an efficient way to do this rather than a series of tasks checking files, variables and states. I figured the use case may have been common enough for a special solution. For instance, let’s say we needed the user to enter a password, but this password doesn’t change so we want the user to only have to enter it once and the playbook “remembers” it for future runs. Is there a quick way to do this in Ansible, maybe in a single task?
If it were me, I’d install the updatedb/locate mechanism on all the machines (developers, like me, usually have it around anywway). I’d put a uniquely-named file in your repo, or choose an existing file in the repo which has a name unlikely to exist on any machine outside the checked-out repo. (like “ZXXXGY340JJQQW”. “GiveMeALittleSmooch,Foobar”, or something like that). Use a script to locate where on a disk that file exists, decide what to do if they have the repo checked out multiple times, and if it can’t be found,. then take the location up to the filename as the DIR, and away you go… Using locate is maybe 100000X times faster than using find -name ZXX* /, I can assure you of that! But, if it’s only going to be in certain place, and the number of files&dirs is small enough, the “find” util would be a good choice also.
For instance, let’s say we needed the user to enter a password, but this password doesn’t change so we want the user to only have to enter it once and the playbook “remembers” it for future runs.
You never want “secrets” stored (remembered) in the clear.
Thank you for the suggestion – it is a good idea, but it would still require a fallback if for whatever reason there were multiple copies of the repo on the system, or perhaps the locate db isn’t up-to-date, in which case it would require user input anyways. So, it actually just adds another step to the process I’ve outlined above.
After some more research and implementation attempts, I came to the conclusion that ansible is actively averse to prompting in tasks. As such, there is not really any great tooling for an input validation loop, which makes this very hard to implement unless I force the playbook to fail if DIR is invalid after a single prompt.
I ended up doing this check in a python script and passing the result via command-line variable to an ansible-playbook. This is an acceptable solution for my project since ansible is mainly interfaced through a python cli anyways.