我有一个在不同主机上运行不同角色的剧本。 是否可以将变量从一个主机上运行的一个角色传递到同一个playbook运行中运行的另一个主机上的另一个角色?或者任何解决方法?
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
设置变量db
的role1中的任务如下所示:
- shell: cd /ACE/conf && grep ^db.url local1.properties | awk -F/ '{print $4}' | awk -F? '{print $1}'
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 /主机
[root@NS1 ansible]# cat /etc/ansible/hosts
[LBL]
10.104.148.136
[LM]
10.104.148.138
答案 0 :(得分:12)
这个主题很复杂,根据你的需要,有两种不同的答案。
示例:
---
- hosts: host1
- roles:
- role1
- role2
目标:您想要从role2中的role1访问一些变量。
使用set_fact
模块。
Inside role1:
name: save precious value
set_fact:
pantsu: shiroi
Inside role2:
name: Nozoki...
debug: msg="Color is {{ pantsu }}"
示例:
[group_foo]
host1
host2
[group_bar]
host3
host4
group_vars / group_foo
important_value=bla-bla-ba
目标:你想在playbook中将它用于group2。
这样做要复杂得多。
在group_vars / group_bar内
other_var: '{{hostvars[groups["group_foo"][0]].important_value}}'
除了' 0'。
之外,您还可以使用其他索引答案 1 :(得分:6)
问题在于您的广告资源。
此消息:
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
答案 2 :(得分:2)
这是我的解决方案。我的任务是在两台服务器之间同步数据,我想传递服务器名称,如下所示: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角色对应。
答案 3 :(得分:1)
这是一个非常古老的话题,但也许对某人有帮助。我使用sed根据额外参数中指定的“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
答案 4 :(得分:0)
我有一个类似的设置,其中有三个主机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
对其进行迭代。