I have an ansible playbook, where I'd like a variable I register on one machine to be available on another.
In my case, I'd like to run a command on localhost
, in this case git rev-parse --abbrev-ref HEAD
, so I can make a note of the current git branch, and sha1, and register this output, so I can refer to it later when working any machine in the main
group, in the second play.
However, it's not clear to me how I register a variable on localhost, so I can access it from main. When I try to access the variable in the second play I get this message:
TASK: [debug msg={{ app_git_sha1.stdout }}] ***********************************
fatal: [main] => One or more undefined variables: 'app_git_sha1' is undefined
Here's the play I'm using. Is there anything obvious I should be doing?
---
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: register current branch
command: git rev-parse --abbrev-ref HEAD
register: git_branch
sudo: no
when: vagrant
tags:
- debugsha
- debug: msg={{ git_branch.stdout }}
tags:
- debugsha
- name: register the SHA1 of the branch being deployed
command: git rev-parse origin/{{ git_branch.stdout }}
register: app_git_sha1
sudo: no
tags:
- slack
- debugsha
- debug: msg={{ app_git_sha1.stdout }}
tags:
- debugsha
- hosts: main
sudo: yes
roles:
- role: productscience.deploy_user
# TODO reprovision using these roles, for consistency
# - role: app.essentials
# - role: zenoamaro.postgresql
- role: productscience.papertrailapp
- role: jdauphant.nginx
tasks:
- include: setup.yml
# - include: db.yml
- name: checkout source control when deploying to remote servers
include: source.yml
when: not vagrant
tags:
- deploy
- include: django.yml
tags:
- deploy
- name: include vagrant specific dependencies for local development
include: vagrant.yml
when: vagrant
handlers:
- name: restart postgres
sudo: yes
service: name=postgresql state=restarted
- name: start restart uwsgi
sudo: yes
service: name={{ app }} state=restarted
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: register the SHA1 of the branch being deployed
when: not vagrant
command: git rev-parse origin/{{ git_branch }}
register: git_sha
tags:
- slack
- name: Send notification message via Slack all options
when: not vagrant
tags:
- slack
local_action:
module: slack
token: "{{ wof_slack_token }}"
msg: "Deployment of `{{ git_branch }}` to {{ app_url }} completed with sha `{{ git_sha.stdout }}`"
channel: "#wof"
username: "Ansible deploy-o-tron"
I have had similar issues with even the same host but across different plays. This thing to remember is facts not variables the things persistent across plays. Here is how I get round the problem.
results in
The problem you're running into is that you're trying to reference facts/variables of one host from those of another host. You need to keep in mind that in Ansible, the variable
app_git_sha1
assigned to the hostlocalhost
is distinct from the variableapp_git_sha1
assigned to the hostmain
or any other host. If you want to access one hosts facts/variables from another host then you need to explicitly reference it via thehostvars
variable. There's a bit more of a discussion on this in this question.Suppose you have a playbook like this:
This will work because you're referencing the host
localhost
andlocalhosts
's instance of the variablefoo
in both plays. The output of this playbook is something like this:If you modify this playbook slightly to run the first play on one host and the second play on a different host, you'll get the error that you encountered. The solution is to use Ansible's built-in
hostvars
variable to have the second host explicitly reference the first hosts variable. So modify the first example like this:The output of this playbook shows that the first task is skipped because
foo
is not defined by the hostanotherhost
. But the second task succeeds because it's explicitly referencinglocalhosts
's instance of the variablefoo
:So, in a nutshell, you want to modify the variable references in your
main
playbook to reference thelocalhost
variables in this manner:Use a dummy host and its variables
For example to pass K8S token and hash from the master to the workers.
On master
On worker