Ansible:如何从库存或组变量文件中获取变量值?

Ansible:如何从库存或组变量文件中获取变量值?,ansible,Ansible,如果变量可能位于库存文件或group_vars目录中,如何从库存中获取变量的值 例如,region=place-a可以在库存文件中,也可以在组的某个位置的文件中。我希望命令能够使用ansible或其他东西检索该值。比如: $ ansible -i /somewhere/production/web --get-value region place-a 这将有助于我进行部署,并了解将部署到哪个区域 更详细的解释是,我的库存结构如下所示: /somewhere/production/web /s

如果变量可能位于库存文件或group_vars目录中,如何从库存中获取变量的值

例如,region=place-a可以在库存文件中,也可以在组的某个位置的文件中。我希望命令能够使用ansible或其他东西检索该值。比如:

$ ansible -i /somewhere/production/web --get-value region
place-a
这将有助于我进行部署,并了解将部署到哪个区域

更详细的解释是,我的库存结构如下所示:

/somewhere/production/web
/somewhere/production/group_vars/web
[web:children]
web1 ansible_ssh_host=10.0.0.1
web2 ansible_ssh_host=10.0.0.2

[web:vars]
region=place-a
- name: deploy to regions
  <task_type>:
    <task_options>: <task_option_value>
    // use the region variable as you wish
    region: {{ item }}
    ...
  with_items: "{{ regions.split(',') }}"
包含库存文件/where/production/web变量的内容如下所示:

/somewhere/production/web
/somewhere/production/group_vars/web
[web:children]
web1 ansible_ssh_host=10.0.0.1
web2 ansible_ssh_host=10.0.0.2

[web:vars]
region=place-a
- name: deploy to regions
  <task_type>:
    <task_options>: <task_option_value>
    // use the region variable as you wish
    region: {{ item }}
    ...
  with_items: "{{ regions.split(',') }}"
我可以通过简单地解析该文件从清单文件中获取值。像这样:

$ 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有办法获得值吗?有点像列表主机

简短回答
否没有CLI选项来获取变量的值

长话短说 首先,您必须了解变量优先级在Ansible中是如何工作的

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

基本上,任何进入“角色默认值”的内容都是默认值 角色内的文件夹是最具可塑性且易于重写的。 角色的vars目录中的任何内容都会覆盖以前的版本 名称空间中该变量的名称。下面的想法是 范围越明确,它的优先级就越高 命令行-e额外的变量总是赢。主机和/或资源清册 变量可以胜过角色默认值,但不能像 vars目录或include\u vars任务

清除该选项后,查看变量取值的唯一方法是使用调试任务,如下所示:

- name: debug a variable
  debug:
    var: region
这将打印出变量区域的值

我的建议是保持一个单一的值类型,或者是字符串,或者是列表,以防止不同剧本中任务之间的混淆

您可以使用以下内容:

/somewhere/production/web
/somewhere/production/group_vars/web
[web:children]
web1 ansible_ssh_host=10.0.0.1
web2 ansible_ssh_host=10.0.0.2

[web:vars]
region=place-a
- 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 east逗号分隔。with_items语句会将其拆分为,并对所有区域重复该任务。

另一个更简单的解决方案是通过cli从ansible获取变量,可能是:

导出tmp_文件=/tmp/ansible.$RANDOM ansible-i localhost-m copy-a content={{{$VARIABLE\u NAME}}}dest=$tmp\u file 导出变量值=$cat$tmp\U文件 rm-f$tmp_文件


看起来很难看,但确实很有帮助。

对于尝试将ansible连接到其他系统的用户来说,此命令行的CLI版本非常重要。基于复制模块在其他地方的使用情况,如果您有一个POSIX mktemp和一个本地的副本,那么下面是一个bash one命令行程序,它可以从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}

>否没有CLI选项来获取变量的值。太糟糕了,但是谢谢。这就是我想要确定的。IMHO,不,没有CLI选项来获取变量的值。应该是第一件被提到的事情,因为问题就是关于它的。