如何设置 register 变量以在 ansible 的播放之间保持不变? [英] How do I set register a variable to persist between plays in ansible?
问题描述
我有一个 ansible playbook,我希望我在一台机器上注册的变量在另一台机器上可用.
I have an ansible playbook, where I'd like a variable I register on one machine to be available on another.
就我而言,我想在 localhost
上运行一个命令,在这种情况下是 git rev-parse --abbrev-ref HEAD
,这样我就可以记录当前 git 分支和 sha1,并注册此输出,以便我稍后在第二个游戏中在 main
组中的任何机器上工作时参考它.
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.
但是,我不清楚如何在 localhost 上注册变量,因此我可以从 main 访问它.当我尝试在第二场比赛中访问该变量时,我收到以下消息:
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"
推荐答案
您遇到的问题是您试图从另一台主机的事实/变量中引用一个主机的事实/变量.您需要记住,在 Ansible 中,分配给主机 localhost
的变量 app_git_sha1
不同于分配给主机 app_git_sha1
的变量 app_git_sha1
code>main 或任何其他主机.如果您想从另一台主机访问一个主机的事实/变量,那么您需要通过 hostvars
变量显式引用它.关于这个在这个问题.
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 host localhost
is distinct from the variable app_git_sha1
assigned to the host main
or any other host. If you want to access one hosts facts/variables from another host then you need to explicitly reference it via the hostvars
variable. There's a bit more of a discussion on this in this question.
假设你有一个这样的剧本:
Suppose you have a playbook like this:
- hosts: localhost
tasks:
- command: /bin/echo "this is a test"
register: foo
- hosts: localhost
tasks:
- debug: var=foo
这将起作用,因为您在两个播放中都引用了主机 localhost
和 localhosts
变量 foo
的实例.这个剧本的输出是这样的:
This will work because you're referencing the host localhost
and localhosts
's instance of the variable foo
in both plays. The output of this playbook is something like this:
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [command /bin/echo "this is a test"] ************************************
changed: [localhost]
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [debug var=foo] *********************************************************
ok: [localhost] => {
"var": {
"foo": {
"changed": true,
"cmd": [
"/bin/echo",
"this is a test"
],
"delta": "0:00:00.004585",
"end": "2015-11-24 20:49:27.462609",
"invocation": {
"module_args": "/bin/echo \"this is a test\"",
"module_complex_args": {},
"module_name": "command"
},
"rc": 0,
"start": "2015-11-24 20:49:27.458024",
"stderr": "",
"stdout": "this is a test",
"stdout_lines": [
"this is a test"
],
"warnings": []
}
}
}
如果您稍微修改此剧本以在一台主机上运行第一次播放,而在另一台主机上运行第二次播放,您将遇到遇到的错误.解决方案是使用 Ansible 的内置 hostvars
变量让第二个主机显式引用第一个 hosts 变量.所以像这样修改第一个例子:
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:
- hosts: localhost
tasks:
- command: /bin/echo "this is a test"
register: foo
- hosts: anotherhost
tasks:
- debug: var=foo
when: foo is defined
- debug: var=hostvars['localhost']['foo']
when: hostvars['localhost']['foo'] is defined
这个剧本的输出显示第一个任务被跳过,因为 foo
不是由主机 anotherhost
定义的.但是第二个任务成功了,因为它显式引用了 localhosts
变量的实例 foo
:
The output of this playbook shows that the first task is skipped because foo
is not defined by the host anotherhost
. But the second task succeeds because it's explicitly referencing localhosts
's instance of the variable foo
:
TASK: [debug var=foo] *********************************************************
skipping: [anotherhost]
TASK: [debug var=hostvars['localhost']['foo']] **************************
ok: ['anotherhost'] => {
"var": {
"hostvars['localhost']['foo']": {
"changed": true,
"cmd": [
"/bin/echo",
"this is a test"
],
"delta": "0:00:00.005950",
"end": "2015-11-24 20:54:04.319147",
"invocation": {
"module_args": "/bin/echo \"this is a test\"",
"module_complex_args": {},
"module_name": "command"
},
"rc": 0,
"start": "2015-11-24 20:54:04.313197",
"stderr": "",
"stdout": "this is a test",
"stdout_lines": [
"this is a test"
],
"warnings": []
}
}
}
所以,简而言之,您希望修改 main
剧本中的变量引用,以这种方式引用 localhost
变量:
So, in a nutshell, you want to modify the variable references in your main
playbook to reference the localhost
variables in this manner:
{{ hostvars['localhost']['app_git_sha1'] }}
这篇关于如何设置 register 变量以在 ansible 的播放之间保持不变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!