Ansible-如何使用循环设置变量
我想创建一个复杂的var(nginx_ssl_vhosts_列表),其中包含来自另一个简单var(reverse_proxy_ssl)的循环,但我无法实现这一点。是否有可能有如下代码,或者我应该使用自定义插件 以下是我认为它会起作用的方式:Ansible-如何使用循环设置变量,ansible,ansible-playbook,Ansible,Ansible Playbook,我想创建一个复杂的var(nginx_ssl_vhosts_列表),其中包含来自另一个简单var(reverse_proxy_ssl)的循环,但我无法实现这一点。是否有可能有如下代码,或者我应该使用自定义插件 以下是我认为它会起作用的方式: - hosts: localhost gather_facts: no connection: local vars: reverse_proxy_ssl: - name: foo.org frontport:
- hosts: localhost
gather_facts: no
connection: local
vars:
reverse_proxy_ssl:
- name: foo.org
frontport: 443
fronturl : /
backend: http://192.168.1.1:8080
- name: bar.org
frontport: 443
fronturl : /
backend: http://192.168.1.2:443
nginx_ssl_vhosts_list:
- listen: "{{ item.frontport }} ssl"
server_name: "{{ item.name }}"
access_log: "{{ item.name }}.access.log"
error_log: "{{ item.name }}.error.log"
extra_parameters: |
location {{ item.fronturl }} {
proxy_pass {{ item.backend }};
}
ssl_certificate {{ item.name }}.crt;
ssl_certificate_key {{ item.name }}.key;
with_items: "{{ reverse_proxy_ssl }}"
tasks:
- debug: msg="{{ nginx_ssl_vhosts_list }}"
据我所知,不能在变量定义中循环,但可以在模板或任务中循环 在这种情况下,您最好创建一个任务,通过
reverse\u proxy\u ssl
list变量生成虚拟主机,如下所示:
...
tasks:
- name: template virtual hosts
template:
src: apache2.conf.j2
dest: /etc/apache2/apache2.conf
...
apache2.conf.j2
这是可能的
我通过使用Jinja2模板和模板中的普通python来实现这一点。最后,只需返回带有{{-temp\u list-}}
下面是我的default/main.yml
# Arch List type
Mock_ArchType: ['epel-6-x86_64','epel-7-x86_64']
# Vars list Dictionary
Platform_Vars_list: [
{ var: "log_path", value: "'{{ Default_Home_String }}/logs/'" },
{ var: "python_site_packages_path", value: "'{{ Default_Python_String }}/lib/python{{ python_main_version }}/site-packages/'" }
]
Platform_Vars: "{%- set temp_list = [] -%}
{%- for item in Mock_ArchType if (client_code | search('Build')) -%}
{%- for vars in Platform_Vars_list -%}
{%- set temp_dic = {} -%}
{%- set _= temp_dic.update({'var': vars.var }) -%}
{%- set _= temp_dic.update({'value': vars.value }) -%}
{%- set _= temp_dic.update({'path': '/var/lib/mock/' + item + '/root/builddir/build/BUILDROOT' + Default_Home_String }) -%}
{%- set _= temp_list.append(temp_dic) -%}
{%- endfor -%}
{%- endfor -%}
{{- temp_list -}}"
这是值得赞扬的。
我知道这是一个老问题,但我也遇到了类似的问题。这是我的方法 首先,我认为@ydaetskcoR是正确的,解决这个问题的最佳方法不是创建复杂变量,而是将循环移动到模板 也就是说,在某些情况下,您需要循环使用dicts或list。在我的例子中,因为我想确保在dict列表中设置了每个必需的键,如果没有,则填写一个默认值,这取决于在模板中编写时需要复杂的逻辑 sonance207的方法似乎非常强大,但我注意到,Jinja2定义的“set”变量与Ansible设置的过滤器和变量之间存在一些不兼容。例如,在上面的示例中
{%- set _= temp_dic.update({'var': vars.var }) -%}
不能写成
{%- set temp_dic = temp_dic | combines({'var': vars.var }) -%}
如果你这样做,你会犯一些奇怪的错误,比如Ansible认为temp_dic是None而不是dictionary
最后,我使用了康斯坦丁·苏沃洛夫(Konstantin Suvorov)所写内容的简化版本。但是,我没有用register
关键字写入临时变量,以后再检索它,而是选择了一个简单的with_item
循环,该循环通过每个循环一个条目来增长所需的nginx_ssl_vhosts_list
变量
- hosts: localhost
gather_facts: no
connection: local
vars:
reverse_proxy_ssl:
- name: foo.org
frontport: 443
fronturl : /
backend: http://192.168.1.1:8080
- name: bar.org
frontport: 443
fronturl : /
backend: http://192.168.1.2:443
nginx_ssl_vhosts_list: []
tasks:
- set_fact:
nginx_ssl_vhosts_list: "{{ nginx_ssl_vhosts_list + [{
'listen': (item.frontport |string) + ' ssl',
'server_name': item.name,
'access_log': item.name + '.access.log',
'error_log': item.name + '.error.log'
}] }}"
with_items: "{{ reverse_proxy_ssl }}"
- debug: msg="{{ nginx_ssl_vhosts_list }}"
(请注意,此示例省去了
额外参数的多行格式设置。
。此类格式设置最好在jinja2模板文件中提供。我不认为这是可能的,但您可以修改或编写模板,使其从反向代理ssl获取值。如果您能描述您的全部要求,我可以帮助您n这个。谢谢@arbabanazar我会设置一个模板。谢谢你的帮助,我会用一个模板来完成。
{%- set temp_dic = temp_dic | combines({'var': vars.var }) -%}
- hosts: localhost
gather_facts: no
connection: local
vars:
reverse_proxy_ssl:
- name: foo.org
frontport: 443
fronturl : /
backend: http://192.168.1.1:8080
- name: bar.org
frontport: 443
fronturl : /
backend: http://192.168.1.2:443
nginx_ssl_vhosts_list: []
tasks:
- set_fact:
nginx_ssl_vhosts_list: "{{ nginx_ssl_vhosts_list + [{
'listen': (item.frontport |string) + ' ssl',
'server_name': item.name,
'access_log': item.name + '.access.log',
'error_log': item.name + '.error.log'
}] }}"
with_items: "{{ reverse_proxy_ssl }}"
- debug: msg="{{ nginx_ssl_vhosts_list }}"