ansible - examples - ¿Cómo usar el módulo de plantilla con diferentes conjuntos de variables?
comandos ansible (8)
Mi caso de uso es el siguiente:
Tengo un archivo de plantilla, y me gustaría crear 2 archivos diferentes a partir de esa plantilla, con las variables rellenadas por un conjunto diferente de variables para cada archivo.
Por ejemplo, supongamos que quiero crear una plantilla del archivo que contiene la línea:
mkdir -p {{myTemplateVariable}}
Me gustaría encontrar una manera adecuada de llenar esta variable con "Archivo1" y "Archivo2". Algo como :
- name: template test 1
template:
src=myTemplateFile
dest=result1
- name: template test 2
template:
src=myTemplateFile
dest=result2
donde podría especificar para la primera plantilla que la variable a usar es a = "File1" y para la segunda, b = "File2".
Con Ansible 2.x puede usar
vars:
con tareas.
Plantilla
test.j2
:
mkdir -p {{myTemplateVariable}}
Libro de jugadas:
- template: src=test.j2 dest=/tmp/File1
vars:
myTemplateVariable: myDirName
- template: src=test.j2 dest=/tmp/File2
vars:
myTemplateVariable: myOtherDir
Esto pasará diferentes valores de myTemplateVariable a test.j2.
Desafortunadamente, el módulo de
template
no admite pasarle variables, que pueden usarse dentro de la plantilla.
Hubo una
solicitud de función
pero fue rechazada.
Se me ocurren dos soluciones:
1. Incluir
La declaración
include
admite el paso de variables.
Entonces podría tener su tarea de
template
dentro de un archivo adicional e incluirla dos veces con los parámetros apropiados:
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. Vuelva a definir myTemplateVariable
Otra forma sería simplemente redefinir myTemplateVariable justo antes de cada tarea de
template
.
- 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
Esta es una solución / hack que estoy usando:
tareas / 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 }}
Después de ejecutar esto, obtienes
this is var_a
en / tmp / templateA y
this is var_b
en / tmp / templateB.
Básicamente abusa de los
with_items
para representar la plantilla con cada elemento en la lista de un elemento.
Esto funciona porque puedes controlar cuál es la lista cuando usas
with_items
.
La desventaja de esto es que debe usar el
item
como el nombre de la variable en su plantilla.
Si desea pasar más de una variable de esta manera, puede dictar como elementos de su lista de esta manera:
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''
y luego se refieren a ellos en su plantilla de esta manera:
{{ item.var_1 }}
{{ item.var_2 }}
Lo hice de esta manera.
En tareas / main.yml
- name: template test
template:
src=myTemplateFile.j2
dest={{item}}
with_dict: some_dict
y en vars / main.yml
some_dict:
/path/to/dest1:
var1: 1
var2: 2
/path/to/dest2:
var1: 3
var2: 4
y en templates / myTemplateFile.j2
some_var = {{ item.value.var1 }}
some_other_var = {{ item.value.var2 }}
Espero que esto resuelva tu problema.
Otro ejemplo del mundo real usando una lista
un extracto para una plantilla para 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 %}
Esta es la var
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" }
Luego despliegue con esto
- 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}}"
Puedes hacer esto muy fácil, mira mi receta de Supervisor:
- 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
Salida:
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''})
¡Disfrutar!
Tuve un problema similar que resolver, aquí hay una solución simple de cómo pasar variables a los archivos de plantilla, el truco es escribir el archivo de plantilla aprovechando la variable. Necesita crear un diccionario (la lista también es posible), que contiene el conjunto de variables correspondientes a cada uno de los archivos. Luego, dentro del archivo de plantilla, acceda a ellos.
vea abajo:
the template file: test_file.j2
# {{ ansible_managed }} created by [email protected]
{% 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 }}
el libro de jugadas
---
#
# file: template_test.yml
# author: [email protected]
#
# 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 }}"
- name: copy vhosts
template: src=site-vhost.conf dest=/etc/apache2/sites-enabled/{{ item }}.conf
with_items:
- somehost.local
- otherhost.local
notify: restart apache
IMPORTANTE: Tenga en cuenta que un elemento no tiene que ser solo una cadena, puede ser un objeto con tantas propiedades como desee, de modo que pueda pasar cualquier cantidad de variables.
En la plantilla tengo:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName {{ item }}
DocumentRoot /vagrant/public
ErrorLog ${APACHE_LOG_DIR}/error-{{ item }}.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>