在我的
hostvars
结构中,我的网络服务器有一个这样的数据结构:
{
"wordpress": {
"config": {
"port": 80,
"ssl": {
"port": 443
}
}
}
}
我希望能够对其进行动态访问,无论我是否使用 SSL。
直接访问很简单——主机是
inventory_hostname
;例如在 Jinja for
循环中:
- debug:
msg: "{{ hostvars[host].wordpress.config.port }}"
问题是:我可以有一个变量名称的动态后缀吗,例如:
- hosts: lb1
vars:
host: web1
suffix: '.wordpress.config.port'
tasks:
- debug:
msg: "{{ hostvars[host] + suffix }}"
- debug:
msg: "{{ lookup('vars',hostvars[host] + suffix ) }}"
对我来说,数据结构和方法看起来不必要的复杂和笨拙。由于您似乎正在寻找布尔状态,因此是否配置了 TLS、是或否、真或假,一个简单的最小示例剧本可能如下所示
---
- hosts: localhost
become: false
gather_facts: false
vars:
wordpress:
config:
ssl: true
tasks:
- name: Construct URL
debug:
msg: "http{% if wordpress.config.ssl %}s{% endif %}://wordpress.example.com"
- name: With port if necessary
debug:
msg: "https://wordpress.example.com:443"
when: wordpress.config.ssl
产生
的输出TASK [Construct URL] *******************
ok: [localhost] =>
msg: https://wordpress.example.com
TASK [With port if necessary] **********
ok: [localhost] =>
msg: https://wordpress.example.com:443
或仅用于
false
TASK [Construct URL] **************
ok: [localhost] =>
msg: http://wordpress.example.com
如果你有能力改变你的数据结构,你可能会更好地应用某种数据库,比如规范化到你的 JSON 对象,并实现类似的目标
{
"wordpress": {
"config": {
"http": { "port": 80 },
"https": { "port": 443 }
}
}
这样您就可以轻松地解决您的配置问题:
protocol: https
port: "{{ wordpress.config[protocol].port }}" # 443, in this case
但是如果你真的想在当前的数据结构上实现它,Ansible 为你提供了
json_query
过滤器,它带有完整的 JSON 查询语言,称为 JMESPath。
在 JMESPath 中,给定您的
wordpress
变量,您可以使用查询 config.port
访问 HTTP 端口,并使用查询 config.ssl.port
访问 HTTPS 端口,因此您可以有效地执行以下操作:
protocol: https
query:
http: config.port
https: config.ssl.port
port: "{{ wordpress | json_query(query[protocol]) }}"
ternary
过滤器,根据条件选择一个值或另一个值:
- debug:
msg: "{{ ssl_enabled | ternary(hostvars[host].wordpress.config.ssl.port, hostvars[host].wordpress.config.port) }}"