2015-10-14 159 views
26

我有一个很大的Ansible playbook,在运行Docker时会创建Docker镜像。我正在使用越来越多的数字作为标签来对它们进行版本化。目前,我必须在每个hosts:部分中指定。是否可以在Ansible中定义剧本全局变量?

我知道存在全局变量,但是通过搜索“可靠的”“全局变量”,我发现它们必须在剧本之外进行定义。是否有可能为剧本定义全局变量?

回答

11

如果您使用的标签/版本适用于所有主机,则使用group_vars/all是一个可行的选项。

如果修订版本号特定于host_vars/host_name文件中的每个主机条目可能会更好。

如果您想读取并初始化var,然后在每次播放后增加该值,在剧本中跨越播放(或您所说的每个主机)变得更难以持续保存该信息。例如,如果您正在寻找部署ň泊坞窗情况下,你可能会做一些动态库存魔术这样的:

- hosts: localhost 
    tasks: 
    - add_host: name=docker_{{item}} groups="dockers,other" tag={{item}} 
    with_sequence: start={{ext_def_start}} count={{ext_def_num}} 


- hosts: dockers 
    tasks: 
    - debug: var=tag 
+0

我希望在剧本中有变量,因为我在Git中拥有它。然后我采取与变量共享库存文件,并且必须适应它。我希望剧本中的变量,因为一旦所有东西都设置好了,它们不会改变,但是库存中的主机可能会改变。 – rabejens

+0

ansible处理变量的方法有点笨拙,但由于它严重依赖隐式包含(基于库存)以及无法在整个剧本中轻松共享变量,所以这是可以理解的。正如我的例子所示,我已经使用库存模块将数据推送到库存变量。事实上(参见set_fact模块)在整个游戏中保持不变,但它们是基于主机的。请记住,您始终可以编写一个快速脚本(例如python)来生成动态库存,包括变量和分组,这些库存看起来完全符合您的需要。 – Petro026

+0

我一直在想这样的事情(编写一个脚本来生成库存),我想我会这样做。该剧本用于设置具有Spark/YARN支持,Cassandra数据库和Zeppelin的基本Hadoop集群,我可能会编写一个脚本,首先要求用户枚举所有主机,然后设置哪些主机应该安装哪个服务。 – rabejens

10

Ansible有一个默认all组,它足够有趣地包含库存文件中的所有主机。

因此,您可以使用任何主机组并为主机组提供group_vars

如上一个链接所示,这些可以直接在库存文件中定义,也可以包含在与库存文件相同目录级别的group_vars目录中的组之后命名的单独文件中。然后

一个例子的目录结构可能看起来像:

-ansible 
|--inventory 
| |--group_vars 
| | |--all 
| | |--dev 
| | |--test 
| | |--prod 
| | |--webservers 
| | |--databases 
| |--dev 
| |--test 
| |--prod 
|--roles 
    ... 

dev的库存文件,那么可能看起来像:

​​

所有这些主机现在拿起任何主机特定的配置(可以在行中定义,或者像group_vars一样可以放入host_vars文件夹中),还可以配置它们所在的特定组,例如,然后还可以继承它们继承的组,如dev b另外,默认情况下,all

然后,这可以用来以比每台主机更粗糙的方式来配置事物。

诸如NTP服务器之类的事情可能需要全部定义,而DNS服务器可能希望在环境级别定义(如果您的网络被分割为dev,测试和生产他们可能需要不同的DNS服务器设置/etc/resolv.conf ),而不同类型的服务器可能具有不同的配置,如要安装的软件包列表等。最后,有些事情可能需要特定于主机,例如在复制组中设置MySQL服务器标识。

相反,如果你只是想确定剧本全局设置,而不是在广告资源(并因此可能被其他剧本进行访问),那么你只需要一个vars块在play定义,就像这样:

- hosts: webservers 
    vars: 
    http_port: 80 
    tasks: 
    - name: Task1 to be ran against all the webservers 
     ... 

正如前面提到的,你可以随时在这里使用的all组太:

- hosts: all 
    vars: 
    ntp_pool: 
     - ntp1.domain 
     - ntp2.domain 
    tasks: 
    - name: Task1 to be ran against all the servers 
     ... 

虽然在一般,我会强烈建议使用角色构建什么东西对某些^ h跑然后使用清单解释哪些服务器是什么类型,然后在清单级别使用group_vars目录来包含这些主机组的所有变量。以这种方式做事可以帮助您将事情保持在合理的位置,并让您轻松地重用您的代码库。

+0

嗯,把一个'[{主机: '所有',乏:{测试: 'hello'}},{hosts:'web':roles:[...]}'当我在'all'的设置阶段后进入角色时,我仍然得到一个'未定义的变量'错误: ( – ThorSummoner

+0

@ThorSummoner我也收到了。我认为这些变量只对在该主机组内部调用的任务有效。 –

+0

如果您有兴趣,我会写出我的解决方案。 –

0

是,全局变量有可能这样,

样品的Splunk安装剧本

splunk/ 
    setup_splunk_playbook.yaml 
    roles/base 
      /tasks/main.yaml 
      /tasks/install.yaml 
     search_head 
      /tasks/configure.yaml 
     indexer 
      /tasks/configure.yaml 
     some_other_role 
      /tasks/some_task.yaml 
    hosts 
    config.yaml 

将您瓦尔成config.yaml

猫的Splunk/config.yaml

--- 
# global Splunk variables 
splunk_version: 7.0.0 
在你的剧本

,包括角色

猫setup_splunk_playbook.yaml

- hosts: "search_heads" 
    become_user: root 
    become: true 
    gather_facts: true 

    roles: 
    - base 
    - search_head 
在你的角色

,包括任务

猫的角色里面的全局变量/ base/tasks/main.yaml

--- 
# install Splunk Base 

- name: include vars 
    include_vars: "{{ playbook_dir }}/config.yaml" 

- include: install.yaml 

瓦尔在现在的任务访问,

猫的角色/基/任务/ install.yaml

- name: echo version 
    debug: splunk version is {{ splunk_version }} 
+0

在“hosts:”属性中使用变量不起作用。 – hakre