如何使用具有不同变量集的模板模块?
How to use template module with different set of variables?
我的用例如下:
我有一个模板文件,我想从该模板创建 2 个不同的文件,每个文件的变量由一组不同的变量填充。
例如,假设我想为包含以下行的文件创建模板:
mkdir -p {{myTemplateVariable}}
我想找到一个合适的方法来让 "File1" 和 "File2" 填充这个变量。像 :
- name: template test 1
template:
src=myTemplateFile
dest=result1
- name: template test 2
template:
src=myTemplateFile
dest=result2
我可以为第一个模板指定要使用的变量是 a = "File1",对于第二个模板,b = "File2".
对于 Ansible 2.x:
- name: template test
template:
src: myTemplateFile
dest: result1
vars:
myTemplateVariable: File1
- name: template test
template:
src: myTemplateFile
dest: result2
vars:
myTemplateVariable: File2
对于 Ansible 1.x:
遗憾的是template
模块不支持传递变量给它,可以在模板内部使用。有一个feature request但是被拒绝了
我可以想到两个解决方法:
1.包括
include
语句支持传递变量。因此,您可以将 template
任务放在一个额外的文件中,并使用适当的参数将其包含两次:
my_include.yml:
- name: template test
template:
src=myTemplateFile
dest=destination
main.yml:
- include: my_include.yml destination=result1 myTemplateVariable=File1
- include: my_include.yml destination=result2 myTemplateVariable=File2
2。重新定义 myTemplateVariable
另一种方法是在每个 template
任务之前简单地重新定义 myTemplateVariable。
- set_fact:
myTemplateVariable: File1
- name: template test 1
template:
src=myTemplateFile
dest=result1
- set_fact:
myTemplateVariable: File2
- name: template test 2
template:
src=myTemplateFile
dest=result2
这是 solution/hack 我正在使用:
tasks/main.yml:
- name: parametrized template - a
template:
src: test.j2
dest: /tmp/templateA
with_items: var_a
- name: parametrized template - b
template:
src: test.j2
dest: /tmp/templateB
with_items: var_b
vars/main.yml
var_a:
- 'this is var_a'
var_b:
- 'this is var_b'
templates/test.j2:
{{ item }}
在 运行 之后,您在 /tmp/templateA 中得到 this is var_a
,在 /tmp/templateB 中得到 this is var_b
。
基本上,您滥用 with_items
来呈现包含单项列表中每一项的模板。之所以可行,是因为您可以在使用 with_items
.
时控制列表内容
这样做的缺点是您必须在模板中使用 item
作为变量名。
如果你想通过这种方式传递多个变量,你可以像这样将指令作为你的列表项:
var_a:
-
var_1: 'this is var_a1'
var_2: 'this is var_a2'
var_b:
-
var_1: 'this is var_b1'
var_2: 'this is var_b2'
然后像这样在您的模板中引用它们:
{{ item.var_1 }}
{{ item.var_2 }}
我是这样做的
在tasks/main.yml
- name: template test
template:
src=myTemplateFile.j2
dest={{item}}
with_dict: some_dict
并在 vars/main.yml
some_dict:
/path/to/dest1:
var1: 1
var2: 2
/path/to/dest2:
var1: 3
var2: 4
并在 templates/myTemplateFile.j2
some_var = {{ item.value.var1 }}
some_other_var = {{ item.value.var2 }}
希望这能解决您的问题。
- name: copy vhosts
template: src=site-vhost.conf dest=/etc/apache2/sites-enabled/{{ item }}.conf
with_items:
- somehost.local
- otherhost.local
notify: restart apache
重要提示:请注意,一个项目不必只是一个字符串,它可以是一个具有任意数量属性的对象,这样您就可以传递任意数量的变量。
在我的模板中:
<VirtualHost *:80>
ServerAdmin me@example.org
ServerName {{ item }}
DocumentRoot /vagrant/public
ErrorLog ${APACHE_LOG_DIR}/error-{{ item }}.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
借助 Ansible 2.x,您可以将 vars:
用于任务。
模板test.j2
:
mkdir -p {{myTemplateVariable}}
剧本:
- template: src=test.j2 dest=/tmp/File1
vars:
myTemplateVariable: myDirName
- template: src=test.j2 dest=/tmp/File2
vars:
myTemplateVariable: myOtherDir
这会将不同的 myTemplateVariable
值传递给 test.j2。
你可以很容易地做到这一点,看看我的主管食谱:
- name: Setup Supervisor jobs files
template:
src: job.conf.j2
dest: "/etc/supervisor/conf.d/{{ item.job }}.conf"
owner: root
group: root
force: yes
mode: 0644
with_items:
- { job: bender, arguments: "-m 64", instances: 3 }
- { job: mailer, arguments: "-m 1024", instances: 2 }
notify: Ensure Supervisor is restarted
job.conf.j2:
[program:{{ item.job }}]
user=vagrant
command=/usr/share/nginx/vhosts/parclick.com/app/console rabbitmq:consumer {{ item.arguments }} {{ item.job }} -e prod
process_name=%(program_name)s_%(process_num)02d
numprocs={{ item.instances }}
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/{{ item.job }}.stderr.log
stdout_logfile=/var/log/supervisor/{{ item.job }}.stdout.log
输出:
TASK [Supervisor : Setup Supervisor jobs files] ********************************
changed: [loc.parclick.com] => (item={u'instances': 3, u'job': u'bender', u'arguments': u'-m 64'})
changed: [loc.parclick.com] => (item={u'instances': 2, u'job': u'mailer', u'arguments': u'-m 1024'})
尽情享受吧!
我有一个类似的问题要解决,这里有一个简单的解决方案,如何将变量传递给模板文件,诀窍是利用变量编写模板文件。您需要创建一个字典(列表也是可能的),其中包含与每个文件对应的变量集。然后在模板文件中访问它们。
见下文:
the template file: test_file.j2
# {{ ansible_managed }} created by xbalaji@gmail.com
{% set dkey = (item | splitext)[0] %}
{% set fname = test_vars[dkey].name %}
{% set fip = test_vars[dkey].ip %}
{% set fport = test_vars[dkey].port %}
filename: {{ fname }}
ip address: {{ fip }}
port: {{ fport }}
剧本
---
#
# file: template_test.yml
# author: xbalaji@gmail.com
#
# description: playbook to demonstrate passing variables to template files
#
# this playbook will create 3 files from a single template, with different
# variables passed for each of the invocation
#
# usage:
# ansible-playbook -i "localhost," template_test.yml
- name: template variables testing
hosts: all
gather_facts: false
vars:
ansible_connection: local
dest_dir: "/tmp/ansible_template_test/"
test_files:
- file_01.txt
- file_02.txt
- file_03.txt
test_vars:
file_01:
name: file_01.txt
ip: 10.0.0.1
port: 8001
file_02:
name: file_02.txt
ip: 10.0.0.2
port: 8002
file_03:
name: file_03.txt
ip: 10.0.0.3
port: 8003
tasks:
- name: copy the files
template:
src: test_file.j2
dest: "{{ dest_dir }}/{{ item }}"
with_items:
- "{{ test_files }}"
另一个使用列表的真实示例
php.ini
模板的摘录
{% if 'cli/php.ini' in item.d %}
max_execution_time = 0
memory_limit = 1024M
{% else %}
max_execution_time = 300
memory_limit = 512M
{% endif %}
这是变量
php_templates:
- { s: 'php.ini.j2', d: "/etc/php/{{php_version}}/apache2/php.ini" }
- { s: 'php.ini.j2', d: "/etc/php/{{php_version}}/cli/php.ini" }
然后我用这个部署
- name: push templated files
template:
src: "{{item.s}}"
dest: "{{item.d}}"
mode: "{{item.m | default(0644) }}"
owner: "{{item.o | default('root') }}"
group: "{{item.g | default('root') }}"
backup: yes
with_items: "{{php_templates}}"
我的用例如下:
我有一个模板文件,我想从该模板创建 2 个不同的文件,每个文件的变量由一组不同的变量填充。
例如,假设我想为包含以下行的文件创建模板:
mkdir -p {{myTemplateVariable}}
我想找到一个合适的方法来让 "File1" 和 "File2" 填充这个变量。像 :
- name: template test 1
template:
src=myTemplateFile
dest=result1
- name: template test 2
template:
src=myTemplateFile
dest=result2
我可以为第一个模板指定要使用的变量是 a = "File1",对于第二个模板,b = "File2".
对于 Ansible 2.x:
- name: template test
template:
src: myTemplateFile
dest: result1
vars:
myTemplateVariable: File1
- name: template test
template:
src: myTemplateFile
dest: result2
vars:
myTemplateVariable: File2
对于 Ansible 1.x:
遗憾的是template
模块不支持传递变量给它,可以在模板内部使用。有一个feature request但是被拒绝了
我可以想到两个解决方法:
1.包括
include
语句支持传递变量。因此,您可以将 template
任务放在一个额外的文件中,并使用适当的参数将其包含两次:
my_include.yml:
- name: template test
template:
src=myTemplateFile
dest=destination
main.yml:
- include: my_include.yml destination=result1 myTemplateVariable=File1
- include: my_include.yml destination=result2 myTemplateVariable=File2
2。重新定义 myTemplateVariable
另一种方法是在每个 template
任务之前简单地重新定义 myTemplateVariable。
- set_fact:
myTemplateVariable: File1
- name: template test 1
template:
src=myTemplateFile
dest=result1
- set_fact:
myTemplateVariable: File2
- name: template test 2
template:
src=myTemplateFile
dest=result2
这是 solution/hack 我正在使用:
tasks/main.yml:
- name: parametrized template - a
template:
src: test.j2
dest: /tmp/templateA
with_items: var_a
- name: parametrized template - b
template:
src: test.j2
dest: /tmp/templateB
with_items: var_b
vars/main.yml
var_a:
- 'this is var_a'
var_b:
- 'this is var_b'
templates/test.j2:
{{ item }}
在 运行 之后,您在 /tmp/templateA 中得到 this is var_a
,在 /tmp/templateB 中得到 this is var_b
。
基本上,您滥用 with_items
来呈现包含单项列表中每一项的模板。之所以可行,是因为您可以在使用 with_items
.
这样做的缺点是您必须在模板中使用 item
作为变量名。
如果你想通过这种方式传递多个变量,你可以像这样将指令作为你的列表项:
var_a:
-
var_1: 'this is var_a1'
var_2: 'this is var_a2'
var_b:
-
var_1: 'this is var_b1'
var_2: 'this is var_b2'
然后像这样在您的模板中引用它们:
{{ item.var_1 }}
{{ item.var_2 }}
我是这样做的
在tasks/main.yml
- name: template test
template:
src=myTemplateFile.j2
dest={{item}}
with_dict: some_dict
并在 vars/main.yml
some_dict:
/path/to/dest1:
var1: 1
var2: 2
/path/to/dest2:
var1: 3
var2: 4
并在 templates/myTemplateFile.j2
some_var = {{ item.value.var1 }}
some_other_var = {{ item.value.var2 }}
希望这能解决您的问题。
- name: copy vhosts
template: src=site-vhost.conf dest=/etc/apache2/sites-enabled/{{ item }}.conf
with_items:
- somehost.local
- otherhost.local
notify: restart apache
重要提示:请注意,一个项目不必只是一个字符串,它可以是一个具有任意数量属性的对象,这样您就可以传递任意数量的变量。
在我的模板中:
<VirtualHost *:80>
ServerAdmin me@example.org
ServerName {{ item }}
DocumentRoot /vagrant/public
ErrorLog ${APACHE_LOG_DIR}/error-{{ item }}.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
借助 Ansible 2.x,您可以将 vars:
用于任务。
模板test.j2
:
mkdir -p {{myTemplateVariable}}
剧本:
- template: src=test.j2 dest=/tmp/File1
vars:
myTemplateVariable: myDirName
- template: src=test.j2 dest=/tmp/File2
vars:
myTemplateVariable: myOtherDir
这会将不同的 myTemplateVariable
值传递给 test.j2。
你可以很容易地做到这一点,看看我的主管食谱:
- name: Setup Supervisor jobs files
template:
src: job.conf.j2
dest: "/etc/supervisor/conf.d/{{ item.job }}.conf"
owner: root
group: root
force: yes
mode: 0644
with_items:
- { job: bender, arguments: "-m 64", instances: 3 }
- { job: mailer, arguments: "-m 1024", instances: 2 }
notify: Ensure Supervisor is restarted
job.conf.j2:
[program:{{ item.job }}]
user=vagrant
command=/usr/share/nginx/vhosts/parclick.com/app/console rabbitmq:consumer {{ item.arguments }} {{ item.job }} -e prod
process_name=%(program_name)s_%(process_num)02d
numprocs={{ item.instances }}
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/{{ item.job }}.stderr.log
stdout_logfile=/var/log/supervisor/{{ item.job }}.stdout.log
输出:
TASK [Supervisor : Setup Supervisor jobs files] ********************************
changed: [loc.parclick.com] => (item={u'instances': 3, u'job': u'bender', u'arguments': u'-m 64'})
changed: [loc.parclick.com] => (item={u'instances': 2, u'job': u'mailer', u'arguments': u'-m 1024'})
尽情享受吧!
我有一个类似的问题要解决,这里有一个简单的解决方案,如何将变量传递给模板文件,诀窍是利用变量编写模板文件。您需要创建一个字典(列表也是可能的),其中包含与每个文件对应的变量集。然后在模板文件中访问它们。
见下文:
the template file: test_file.j2
# {{ ansible_managed }} created by xbalaji@gmail.com
{% set dkey = (item | splitext)[0] %}
{% set fname = test_vars[dkey].name %}
{% set fip = test_vars[dkey].ip %}
{% set fport = test_vars[dkey].port %}
filename: {{ fname }}
ip address: {{ fip }}
port: {{ fport }}
剧本
---
#
# file: template_test.yml
# author: xbalaji@gmail.com
#
# description: playbook to demonstrate passing variables to template files
#
# this playbook will create 3 files from a single template, with different
# variables passed for each of the invocation
#
# usage:
# ansible-playbook -i "localhost," template_test.yml
- name: template variables testing
hosts: all
gather_facts: false
vars:
ansible_connection: local
dest_dir: "/tmp/ansible_template_test/"
test_files:
- file_01.txt
- file_02.txt
- file_03.txt
test_vars:
file_01:
name: file_01.txt
ip: 10.0.0.1
port: 8001
file_02:
name: file_02.txt
ip: 10.0.0.2
port: 8002
file_03:
name: file_03.txt
ip: 10.0.0.3
port: 8003
tasks:
- name: copy the files
template:
src: test_file.j2
dest: "{{ dest_dir }}/{{ item }}"
with_items:
- "{{ test_files }}"
另一个使用列表的真实示例
php.ini
模板的摘录{% if 'cli/php.ini' in item.d %}
max_execution_time = 0
memory_limit = 1024M
{% else %}
max_execution_time = 300
memory_limit = 512M
{% endif %}
这是变量
php_templates:
- { s: 'php.ini.j2', d: "/etc/php/{{php_version}}/apache2/php.ini" }
- { s: 'php.ini.j2', d: "/etc/php/{{php_version}}/cli/php.ini" }
然后我用这个部署
- name: push templated files
template:
src: "{{item.s}}"
dest: "{{item.d}}"
mode: "{{item.m | default(0644) }}"
owner: "{{item.o | default('root') }}"
group: "{{item.g | default('root') }}"
backup: yes
with_items: "{{php_templates}}"