Mon cas d'utilisation est le suivant:
J'ai un fichier de modèle et j'aimerais créer 2 fichiers différents à partir de ce modèle, les variables étant remplies par un ensemble de variables différent pour chaque fichier.
Par exemple, disons que je veux modéliser le fichier contenant la ligne:
mkdir -p {{myTemplateVariable}}
Je voudrais trouver un moyen approprié d'obtenir cette variable remplie par "Fichier1" et "Fichier2". Quelque chose comme :
- name: template test 1
template:
src=myTemplateFile
dest=result1
- name: template test 2
template:
src=myTemplateFile
dest=result2
où je pourrais spécifier pour le premier gabarit que la variable à utiliser est a = "Fichier1" et pour le second, b = "Fichier2".
Malheureusement, le module template
ne prend pas en charge le transfert de variables qui peuvent être utilisées dans le modèle. Il y avait une demande de fonctionnalité mais elle a été rejetée.
Je peux penser à deux solutions de contournement:
1. Inclure
L'instruction include
prend en charge le passage de variables. Ainsi, vous pourriez avoir votre tâche template
dans un fichier supplémentaire et l'inclure deux fois avec les paramètres appropriés:
mon_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. Redéfinissez myTemplateVariable
Une autre solution consisterait simplement à redéfinir myTemplateVariable juste avant chaque tâche 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
Avec Ansible 2.x, vous pouvez utiliser vars:
avec des tâches.
Modèle test.j2
:
mkdir -p {{myTemplateVariable}}
Playbook:
- template: src=test.j2 dest=/tmp/File1
vars:
myTemplateVariable: myDirName
- template: src=test.j2 dest=/tmp/File2
vars:
myTemplateVariable: myOtherDir
Cela transmettra différentes valeurs myTemplateVariable
dans test.j2.
Vous pouvez le faire très facilement, regardez ma recette de superviseur:
- 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
Sortie:
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'})
Prendre plaisir!
Ceci est une solution/bidouille que j'utilise:
tâches/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 }}
Après avoir exécuté ceci, vous obtenez this is var_a
dans/tmp/templateA et this is var_b
dans/tmp/templateB.
Fondamentalement, vous abusez de with_items
pour rendre le modèle avec chaque élément de la liste à un élément. Cela fonctionne car vous pouvez contrôler la liste lorsque vous utilisez with_items
.
L'inconvénient est que vous devez utiliser item
comme nom de variable dans votre modèle.
Si vous voulez passer plus d'une variable de cette façon, vous pouvez utiliser les éléments de votre liste comme ceci:
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'
puis faites-les référence dans votre modèle comme ceci:
{{ item.var_1 }}
{{ item.var_2 }}
Je l'ai fait de cette façon.
Dans tasks/main.yml
- name: template test
template:
src=myTemplateFile.j2
dest={{item}}
with_dict: some_dict
et dans vars/main.yml
some_dict:
/path/to/dest1:
var1: 1
var2: 2
/path/to/dest2:
var1: 3
var2: 4
et dans templates/myTemplateFile.j2
some_var = {{ item.value.var1 }}
some_other_var = {{ item.value.var2 }}
J'espère que ceci résoudra votre problème.
J'ai eu un problème similaire à résoudre, voici une solution simple pour passer des variables à des fichiers de gabarit. L'astuce consiste à écrire le fichier de gabarit en tirant parti de la variable. Vous devez créer un dictionnaire (une liste est également possible), qui contient l'ensemble des variables correspondant à chacun des fichiers. Ensuite, accédez-y dans le fichier de modèle.
voir ci-dessous:
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 }}
le playbook
---
#
# 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
IMPORTANT: Notez qu'un élément ne doit pas nécessairement être une simple chaîne. Il peut s'agir d'un objet avec autant de propriétés que vous le souhaitez. Vous pouvez ainsi transmettre autant de variables que vous le souhaitez.
Dans le modèle, j'ai:
<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>
Un autre exemple concret utilisant une liste
un extrait pour un template pour 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 %}
C'est le 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" }
Ensuite, je déploie avec cette
- 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}}"