将 Ansible 变量从一个角色(一台主机上的运行)传递到同一剧本中另一台主机上的另一个角色运行
Pass Ansible variables from one role (running on one host) to another role running on another host within the same playbook
我有一个剧本 运行 在不同的主机上扮演不同的角色。
是否可以将变量从一台主机上的一个角色 运行ning 传递到同一剧本 运行 中另一台主机 运行ning 上的另一个角色?或者任何解决方法?
playbook
host1
role1
here I get some variables: var1 var2 ...etc
host2
role2
here I need to use var1 var2 ... etc from the above host/role
role1 中设置变量 db
的任务如下所示:
- shell: cd /ACE/conf && grep ^db.url local1.properties | awk -F/ '{print }' | awk -F? '{print }'
register: db
更新:在第一台主机上,值是动态的,它就像一个始终更新的配置文件。在我使用 role1 将值存储在 host1 上的变量中之后,我将移动到 host2,运行 role2 并使用 host1 存储的变量中的这些值进行处理。
我尝试使用 hostvars:
{{ hostvars.LBL.db.stdout }}
{{ hostvars['LBL']['db'] }}
{{ hostvars['LBL']['db']['stdout'] }}
我得到错误:
in get_variables raise Exception("host not found: %s" % hostname) Exception: host not found: LBL
LBL 存在于主机中,因为它是我运行第一个角色
我在一台主机上设置了一个变量,我希望该变量可用于另一台主机。所有这些都在一个剧本中。可以吗?
hostvars 无法像这样使用它:
---
- name: test hostvars host1
hosts: LBL
tasks:
- command: "ls /bin"
register: ls_out
- name: test hostvars host2
hosts: LM
tasks:
- debug:
var: "{{ hostvars['LBL']['ls_out']['stdout'] }}"
错误:
fatal: [10.104.148.138] => host not found: LBL
/etc/ansible/hosts
[root@NS1 ansible]# cat /etc/ansible/hosts
[LBL]
10.104.148.136
[LM]
10.104.148.138
这个题目比较复杂,根据你的需要,有两种不同的答案。
访问在同一主机的另一个角色中定义的变量
示例:
---
- hosts: host1
- roles:
- role1
- role2
目标:您想从角色 1 访问角色 2 中的一些变量。
使用set_fact
模块。
内部角色 1:
name: save precious value
set_fact:
pantsu: shiroi
内部角色 2:
name: Nozoki...
debug: msg="Color is {{ pantsu }}"
一个主机(或组)对其他主机(或组)的静态变量的访问
示例:
[group_foo]
host1
host2
[group_bar]
host3
host4
group_vars/group_foo
important_value=bla-bla-ba
目标:您想在 group2 的剧本中使用它。
这要复杂得多。
里面group_vars/group_bar
other_var: '{{hostvars[groups["group_foo"][0]].important_value}}'
您可以使用除“0”之外的其他索引。
问题出在您的库存中。
这条消息:
fatal: [10.104.148.138] => host not found: LBL
是因为LBL
是一个群组而不是主机。组 LBL
中有一个主机:10.104.148.136
执行以下操作之一:
1。将您的库存 (/etc/ansible/hosts
) 更改为:
LBL ansible_ssh_host=10.104.148.136
LM ansible_ssh_host=10.104.148.138
2。或者如果你真的知道你在做什么并且 LBL
是一个组并且你想保持这种状态然后访问变量:
{{ hostvars['10.104.148.136']['db']['stdout'] }}
再说一次,LBL 是一个团体,而不是主持人。 More info.
这是我的解决方案。我的任务是在两台服务器之间同步数据,我想像这样传递服务器名称:ansible-playbook sync.yaml -e "source=host1 destination=host2"
这是主要剧本:
---
- name: get_sync_facts
hosts: "{{ source }}"
roles:
- set_sync_facts
- name: sync
hosts: "{{ destination }}"
roles:
- get_sync_facts
- sync
这是 set_sync_facts 角色:
---
- set_fact: src_media_dir='/some/dir/'
- set_fact: src_user='myuser'
- set_fact: src_host='1.1.1.1'
- set_fact: src_port=12345
- set_fact: src_db_user='dbuser'
- set_fact: src_db_password='something'
- set_fact: src_db_name='some_db'
(我实际上从任务中派生了其中一些,从主机变量中派生了一些,但你明白了)
这里是 get_sync_facts 角色:
---
- set_fact: src_media_dir={{ hostvars[source]['src_media_dir'] }}
- set_fact: src_user={{ hostvars[source]['src_user'] }}
- set_fact: src_host={{ hostvars[source]['src_host'] }}
- set_fact: src_port={{ hostvars[source]['src_port'] }}
- set_fact: src_db_user={{ hostvars[source]['src_db_user'] }}
- set_fact: src_db_password={{ hostvars[source]['src_db_password'] }}
- set_fact: src_db_name={{ hostvars[source]['src_db_name'] }}
你可以不用这个,直接在你的剧本中引用 hostvars 但这似乎更容易维护,因为它直接对应于 set_sync_facts 角色。
这是一个很老的话题,但也许对某些人会有帮助。我使用 sed 根据额外参数中指定的 "target" 获取主机名。
要使用此 "target" 组必须仅包含 1 个主机名。
我的库存主机:
[ansible_local]
localhost
[machine1]
machine1.domain.tld
upgrade_packages.yml
---
- hosts: '{{ target }}'
sudo: yes
tasks:
- name: check for Debian system
shell: /bin/false
when: ansible_pkg_mgr != "apt"
- name: full-upgrade all packages
apt: update_cache=yes upgrade=full
register: upgrade_result
- hosts: ansible_local
tasks:
- name: find out host from target
shell: /bin/sed -n -e '/^\[{{ target }}\]$/,/^\[.*\]$/ { /^\[/d; /^$/d; p; }' {{ inventory_file }}
register: target_inventory
- name: Display all facts from target machine (change when to true if needed)
debug: var=hostvars[target_inventory.stdout]
when: false
- name: Display upgrade result on ansible_local node
debug: var=hostvars[target_inventory.stdout].upgrade_result.msg
调用方式:ansible-playbook ./upgrade-packages.yml -e "target=machine1" -v
我有一个类似的设置,其中有三个主机 h1、h2、h3,我想在每个主机上定义一个事实 { "important_fact": "foo" }
(分别是 bar 和 baz)
要获取包含所有主机上所有不同 important_facts 的列表,您可以这样做:
- set_fact:
important_facts_list: "{{ hostvars | json('*.important_fact') }}"
run_once: yes
delegate_to: h1
important_facts_list
将包含 [ 'foo', 'bar', 'baz' ]
,您现在可以使用 with_items
.
迭代它们
我有一个剧本 运行 在不同的主机上扮演不同的角色。 是否可以将变量从一台主机上的一个角色 运行ning 传递到同一剧本 运行 中另一台主机 运行ning 上的另一个角色?或者任何解决方法?
playbook
host1
role1
here I get some variables: var1 var2 ...etc
host2
role2
here I need to use var1 var2 ... etc from the above host/role
role1 中设置变量 db
的任务如下所示:
- shell: cd /ACE/conf && grep ^db.url local1.properties | awk -F/ '{print }' | awk -F? '{print }'
register: db
更新:在第一台主机上,值是动态的,它就像一个始终更新的配置文件。在我使用 role1 将值存储在 host1 上的变量中之后,我将移动到 host2,运行 role2 并使用 host1 存储的变量中的这些值进行处理。
我尝试使用 hostvars:
{{ hostvars.LBL.db.stdout }}
{{ hostvars['LBL']['db'] }}
{{ hostvars['LBL']['db']['stdout'] }}
我得到错误:
in get_variables raise Exception("host not found: %s" % hostname) Exception: host not found: LBL
LBL 存在于主机中,因为它是我运行第一个角色
我在一台主机上设置了一个变量,我希望该变量可用于另一台主机。所有这些都在一个剧本中。可以吗?
hostvars 无法像这样使用它:
---
- name: test hostvars host1
hosts: LBL
tasks:
- command: "ls /bin"
register: ls_out
- name: test hostvars host2
hosts: LM
tasks:
- debug:
var: "{{ hostvars['LBL']['ls_out']['stdout'] }}"
错误:
fatal: [10.104.148.138] => host not found: LBL
/etc/ansible/hosts
[root@NS1 ansible]# cat /etc/ansible/hosts
[LBL]
10.104.148.136
[LM]
10.104.148.138
这个题目比较复杂,根据你的需要,有两种不同的答案。
访问在同一主机的另一个角色中定义的变量
示例:
---
- hosts: host1
- roles:
- role1
- role2
目标:您想从角色 1 访问角色 2 中的一些变量。
使用set_fact
模块。
内部角色 1:
name: save precious value
set_fact:
pantsu: shiroi
内部角色 2:
name: Nozoki...
debug: msg="Color is {{ pantsu }}"
一个主机(或组)对其他主机(或组)的静态变量的访问
示例:
[group_foo]
host1
host2
[group_bar]
host3
host4
group_vars/group_foo
important_value=bla-bla-ba
目标:您想在 group2 的剧本中使用它。
这要复杂得多。
里面group_vars/group_bar
other_var: '{{hostvars[groups["group_foo"][0]].important_value}}'
您可以使用除“0”之外的其他索引。
问题出在您的库存中。
这条消息:
fatal: [10.104.148.138] => host not found: LBL
是因为LBL
是一个群组而不是主机。组 LBL
中有一个主机:10.104.148.136
执行以下操作之一:
1。将您的库存 (/etc/ansible/hosts
) 更改为:
LBL ansible_ssh_host=10.104.148.136
LM ansible_ssh_host=10.104.148.138
2。或者如果你真的知道你在做什么并且 LBL
是一个组并且你想保持这种状态然后访问变量:
{{ hostvars['10.104.148.136']['db']['stdout'] }}
再说一次,LBL 是一个团体,而不是主持人。 More info.
这是我的解决方案。我的任务是在两台服务器之间同步数据,我想像这样传递服务器名称:ansible-playbook sync.yaml -e "source=host1 destination=host2"
这是主要剧本:
---
- name: get_sync_facts
hosts: "{{ source }}"
roles:
- set_sync_facts
- name: sync
hosts: "{{ destination }}"
roles:
- get_sync_facts
- sync
这是 set_sync_facts 角色:
---
- set_fact: src_media_dir='/some/dir/'
- set_fact: src_user='myuser'
- set_fact: src_host='1.1.1.1'
- set_fact: src_port=12345
- set_fact: src_db_user='dbuser'
- set_fact: src_db_password='something'
- set_fact: src_db_name='some_db'
(我实际上从任务中派生了其中一些,从主机变量中派生了一些,但你明白了)
这里是 get_sync_facts 角色:
---
- set_fact: src_media_dir={{ hostvars[source]['src_media_dir'] }}
- set_fact: src_user={{ hostvars[source]['src_user'] }}
- set_fact: src_host={{ hostvars[source]['src_host'] }}
- set_fact: src_port={{ hostvars[source]['src_port'] }}
- set_fact: src_db_user={{ hostvars[source]['src_db_user'] }}
- set_fact: src_db_password={{ hostvars[source]['src_db_password'] }}
- set_fact: src_db_name={{ hostvars[source]['src_db_name'] }}
你可以不用这个,直接在你的剧本中引用 hostvars 但这似乎更容易维护,因为它直接对应于 set_sync_facts 角色。
这是一个很老的话题,但也许对某些人会有帮助。我使用 sed 根据额外参数中指定的 "target" 获取主机名。
要使用此 "target" 组必须仅包含 1 个主机名。
我的库存主机:
[ansible_local]
localhost
[machine1]
machine1.domain.tld
upgrade_packages.yml
---
- hosts: '{{ target }}'
sudo: yes
tasks:
- name: check for Debian system
shell: /bin/false
when: ansible_pkg_mgr != "apt"
- name: full-upgrade all packages
apt: update_cache=yes upgrade=full
register: upgrade_result
- hosts: ansible_local
tasks:
- name: find out host from target
shell: /bin/sed -n -e '/^\[{{ target }}\]$/,/^\[.*\]$/ { /^\[/d; /^$/d; p; }' {{ inventory_file }}
register: target_inventory
- name: Display all facts from target machine (change when to true if needed)
debug: var=hostvars[target_inventory.stdout]
when: false
- name: Display upgrade result on ansible_local node
debug: var=hostvars[target_inventory.stdout].upgrade_result.msg
调用方式:ansible-playbook ./upgrade-packages.yml -e "target=machine1" -v
我有一个类似的设置,其中有三个主机 h1、h2、h3,我想在每个主机上定义一个事实 { "important_fact": "foo" }
(分别是 bar 和 baz)
要获取包含所有主机上所有不同 important_facts 的列表,您可以这样做:
- set_fact:
important_facts_list: "{{ hostvars | json('*.important_fact') }}"
run_once: yes
delegate_to: h1
important_facts_list
将包含 [ 'foo', 'bar', 'baz' ]
,您现在可以使用 with_items
.