Ansible:如何从inventory或group_vars文件中获取变量的值?

时间:2016-08-25 10:46:23

标签: ansible

如果变量可以在清单文件或group_vars目录中,如何从清单中获取变量的值?

例如,region=place-a可能位于清单文件中,也可能位于group_vars某处的文件中。我想要一个命令能够使用ansible或检索该值的东西来检索该值。像:

$ ansible -i /somewhere/production/web --get-value region
place-a

这将有助于我部署并了解正在部署哪个区域。

为了澄清更长的解释,我的库存结构如下所示:

/somewhere/production/web
/somewhere/production/group_vars/web

包含库存文件/somewhere/production/web变量的内容如下所示:

[web:children]
web1 ansible_ssh_host=10.0.0.1
web2 ansible_ssh_host=10.0.0.2

[web:vars]
region=place-a

我只需解析文件即可从库存文件中获取值。像这样:

$ awk -F "=" '/^region/ {print $2}' /somewhere/production/web
place-a

但该变量也可以在group_vars文件中。例如:

$ cat /somewhere/production/group_vars/web
region: place-a

或者它看起来像一个数组:

$ cat /somewhere/production/group_vars/web
region:
    - place-a

我不想查找和解析所有可能的文件。

Ansible有办法获得价值吗?有点像--list-hosts

$ ansible web -i /somewhere/production/web --list-hosts
    web1
    web2

3 个答案:

答案 0 :(得分:1)

首先,您必须了解变量优先级在Ansible中的工作原理。

确切的顺序在documentation中定义。以下是摘要摘录:

  

基本上,任何进入“角色默认值”的东西(默认值)   角色里面的文件夹)是最具延展性和容易被覆盖的。   角色的vars目录中的任何内容都将覆盖以前的版本   名称空间中的该变量这里的想法是   你得到的范围越明确,它所用的优先级就越高   命令行-e额外的vars总是赢。主机和/或库存   变量可以胜过角色默认值,但不明确包含类似   vars目录或include_vars任务。

清除后,查看变量值的唯一方法是使用debug任务,如下所示:

- name: debug a variable
  debug:
    var: region

这将打印出变量region的值。

我的建议是维护单个值类型,stringlist,以防止tasks中不同playbooks内的混淆。

您可以使用以下内容:

- name: deploy to regions
  <task_type>:
    <task_options>: <task_option_value>
    // use the region variable as you wish
    region: {{ item }}
    ...
  with_items: "{{ regions.split(',') }}"

在这种情况下,您可以使用逗号分隔变量regions=us-west,us-eastwith_items语句会将其拆分为,并重复所有区域的任务。

最后, NO 没有用于获取变量值的CLI选项。

答案 1 :(得分:1)

此版本的CLI对于尝试将ansible连接到其他系统的人员非常重要。在其他地方使用copy模块的基础上,如果你在本地有一个POSIX mktemp和一份jq,那么这里有一个bash one-liner,可以从CLI获得技巧:

export TMP=`mktemp` && ansible localhost -c local -i inventory.yml -m copy -a "content={{hostvars['SOME_HOSTNAME']}} dest=${TMP}" >/dev/null && cat ${TMP}|jq -r .SOME_VAR_NAME && rm ${TMP}

分解

# create a tempfile
export TMP=`mktemp` 

# quietly use Ansible in local only mode, loading inventory.yml
# digging up the already-merged global/host/group vars 
# for SOME_HOSTNAME, copying them to our tempfile from before
ansible localhost --connection local \
  --inventory inventory.yml --module-name copy \
  --args "content={{hostvars['SOME_HOSTNAME']}} dest=${TMP}" \
  > /dev/null 

# CLI-embedded ansible is a bit cumbersome.  After all the data 
# is exported to JSON, we can use `jq` to get a lot more flexibility 
# out of queries/filters on this data.  Here we just want a single 
# value though, so we parse out SOME_VAR_NAME from all the host variables 
# we saved before
cat ${TMP}|jq -r .SOME_VAR_NAME
rm ${TMP}

答案 2 :(得分:0)

另一个更简单的解决方案是从ansible通过cli得到一个变量:

export tmp_file=/tmp/ansible.$RANDOM ansible -i <inventory> localhost -m copy -a "content={{ $VARIABLE_NAME }} dest=$tmp_file" export VARIBALE_VALUE=$(cat $tmp_file) rm -f $tmp_file

看起来很难看,但真的很有帮助。