Wie verwende ich ein Vorlagenmodul mit verschiedenen Variablen?


92

Mein Anwendungsfall ist der folgende:

Ich habe eine Vorlagendatei und möchte aus dieser Vorlage zwei verschiedene Dateien erstellen, wobei die Variablen für jede Datei mit einem anderen Satz von Variablen gefüllt werden.

Angenommen, ich möchte die Datei mit der Zeile vorlegen:

mkdir -p {{myTemplateVariable}}

Ich möchte einen geeigneten Weg finden, um diese Variable mit "File1" und "File2" zu füllen. Etwas wie :

- name: template test 1
  template: 
        src=myTemplateFile
        dest=result1


- name: template test 2
  template: 
        src=myTemplateFile
        dest=result2

wo ich für die erste Vorlage angeben könnte, dass die zu verwendende Variable a = "File1" und für die zweite b = "File2" ist.


Ist das genau das, was ich mit all meinen Rezepten mache? Schauen Sie sich diesen Kommentar an stackoverflow.com/a/40189525/1571310 , hoffe diese Hilfe!
Tecnocat

Antworten:


49

Für 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

Für Ansible 1.x:

Leider unterstützt das templateModul keine Übergabe von Variablen an das Modul, die innerhalb der Vorlage verwendet werden können. Es gab eine Funktionsanfrage, die jedoch abgelehnt wurde.

Ich kann mir zwei Problemumgehungen vorstellen:

1. Einschließen

Die includeAnweisung unterstützt vorbei Variablen. Sie können Ihre templateAufgabe also in einer zusätzlichen Datei speichern und zweimal mit den entsprechenden Parametern einfügen:

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. Definieren Sie myTemplateVariable neu

Eine andere Möglichkeit wäre, myTemplateVariable direkt vor jeder templateAufgabe neu zu definieren .

- 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

Danke für die Antwort. Ist es jedoch wirklich unmöglich, auf Problemumgehungen zu verzichten? Ich versuche gerade etwas wie: stackoverflow.com/questions/26020465/… , habe aber immer noch einige Fehler (möglicherweise nicht direkt verwandt).
Kestemont Max

Ja, Sie können dies auch mit einer Schleife tun - dennoch ist es eine Problemumgehung. :)
Udondan

14
nicht mehr benötigt. "vars" wird jetzt unterstützt. siehe @ konstantin-suvorov Antwort unten.
Sonjz

123

Mit Ansible 2.x können Sie vars:mit Aufgaben verwenden.

Vorlage test.j2:

mkdir -p {{myTemplateVariable}}

Spielbuch:

- template: src=test.j2 dest=/tmp/File1
  vars:
    myTemplateVariable: myDirName

- template: src=test.j2 dest=/tmp/File2
  vars:
    myTemplateVariable: myOtherDir

Dadurch werden unterschiedliche myTemplateVariableWerte an test.j2 übergeben.


9
anfangs habe ich einen fehler gemacht und vars: eingerückt wie die restlichen vorlagenargumente (wie src :). Ich denke, die Einrückungsstufe bedeutet vars: ist von der Aufgabe, nicht von der Vorlage. Sie können dies also überall tun, nicht nur in Vorlagen. nett.
Greg

37

Sie können dies sehr einfach tun, schauen Sie sich mein Supervisor-Rezept an:

- 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

Ausgabe:

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'})

Genießen!


Dies sollte als richtige Antwort markiert werden. Da es jetzt unterstützt wird
PoX

23

Dies ist eine Lösung / ein Hack, den ich verwende:

Aufgaben / 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 }}

Nachdem Sie dies ausgeführt haben, gelangen Sie this is var_ain / tmp / templateA und this is var_bin / tmp / templateB.

Grundsätzlich missbrauchen Sie with_itemses, die Vorlage mit jedem Element in der Liste mit einem Element zu rendern. Dies funktioniert, weil Sie steuern können, was die Liste bei der Verwendung ist with_items.

Der Nachteil dabei ist, dass Sie itemals Variablennamen in Ihrer Vorlage verwenden müssen.

Wenn Sie auf diese Weise mehr als eine Variable übergeben möchten, können Sie als Listenelemente wie folgt diktieren:

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'

und verweisen Sie dann in Ihrer Vorlage wie folgt darauf:

{{ item.var_1 }}
{{ item.var_2 }}

1
Saubere Lösung, aber Hut zu verwendenwith_items: '{{ var_a }}'
Peter Ajtai

8

Ich habe es so gemacht.

In Aufgaben / main.yml

- name: template test
  template: 
        src=myTemplateFile.j2
        dest={{item}}
   with_dict: some_dict

und in vars / main.yml

some_dict:
  /path/to/dest1:
    var1: 1
    var2: 2
  /path/to/dest2:
    var1: 3
    var2: 4

und in templates / myTemplateFile.j2

some_var = {{ item.value.var1 }}
some_other_var = {{ item.value.var2 }}

Hoffe das löst dein Problem.


with_dictist die bessere Lösung.
zx1986

1
- name: copy vhosts
  template: src=site-vhost.conf dest=/etc/apache2/sites-enabled/{{ item }}.conf
  with_items:
    - somehost.local
    - otherhost.local
  notify: restart apache

WICHTIG: Beachten Sie, dass ein Element nicht nur eine Zeichenfolge sein muss, sondern ein Objekt mit so vielen Eigenschaften sein kann, wie Sie möchten. Auf diese Weise können Sie eine beliebige Anzahl von Variablen übergeben.

In der Vorlage habe ich:

<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>

1
Wie könnte ich es zu einem Objekt machen?
Camdixon

1

Ich hatte ein ähnliches Problem zu lösen. Hier ist eine einfache Lösung, wie Variablen an Vorlagendateien übergeben werden. Der Trick besteht darin, die Vorlagendatei unter Ausnutzung der Variablen zu schreiben. Sie müssen ein Wörterbuch erstellen (Liste ist ebenfalls möglich), das die Variablen enthält, die den einzelnen Dateien entsprechen. Greifen Sie dann innerhalb der Vorlagendatei darauf zu.

siehe unten:

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 }}

das Spielbuch

---
#
# 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 }}"

0

Ein weiteres Beispiel aus der Praxis anhand einer Liste

ein Auszug für eine Vorlage für 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 %}

Dies ist die 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" }

Dann stelle ich damit bereit

- 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}}"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.