将Ansible变量从一个角色(在一个主机上运行)传递到在同一个playbook中的另一个主机上运行的另一个角色

时间:2015-03-31 12:28:31

标签: variables ansible roles ansible-playbook

我有一个在不同主机上运行不同角色的剧本。 是否可以将变量从一个主机上运行的一个角色传递到同一个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

5 个答案:

答案 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对其进行迭代。