How can I set an Ansible variable whose value won't be known until after running the playlist?

rmunn asked:

I’m working on an Ansible script to set up a new TeamCity build agent, and there’s one part of the process that I don’t know how to automate. After installing a TeamCity build agent, it must be authorized by an admin, who logs into the build server and clicks the “Authorize” button next to the build agent. This creates an authorization token, which is then saved in the agent’s file. What I’d like to do is extract that token and save it in the host variables for that build agent, so that if I re-run the Ansible script, the right authorization token will be copied over and the agent will not need to be re-authorized.

I could easily do this manually: after the admin logs in and authorizes the agent, I could copy the authorization key out of the agent’s file, put it in host_vars/(agent name)/buildagent.yml, and be done. But is there a way to do this automatically? Any manual step is a step that has to be documented, and that someone might forget to do — that’s why we use Ansible in the first place.

I found the set_fact module that looked promising at first, but it says “These variables will survive between plays during an Ansible run, but will not be saved across executions even if you use a fact cache.” (Emphasis mine). Fact caching and registered variables also don’t seem to be quite what I’m looking for.

Maybe I could have an Ansible task that rewrites host_vars/(agent name)/buildagent.yml on the Ansible host machine — I suppose that could work. But that seems rather kludgy. Is there an “official” way to set host variables for future playbook runs, which I just haven’t found? Or am I just going to have to accept a single manual step in my process here?

My answer:

You could always just read the authorization token from the file live, and fail if it isn’t set.

- name: Read authorization token
  command: "grep authorizationToken .../ | cut -f 2 -d ="
  register: result
  failed_when: result.stdout == ""

- name: Set authorization token fact
  set_fact: authorization_token="{{result.stdout}}"

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.