Bagaimana cara menggunakan modul template dengan set variabel yang berbeda?

92

Kasus penggunaan saya adalah sebagai berikut:

Saya memiliki file template, dan saya ingin membuat 2 file berbeda dari template itu, dengan variabel diisi oleh variabel yang berbeda untuk setiap file.

Sebagai contoh, katakanlah saya ingin membuat template file yang berisi baris:

mkdir -p {{myTemplateVariable}}

Saya ingin mencari cara yang tepat untuk mengisi variabel ini dengan "File1" dan "File2". Sesuatu seperti :

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


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

di mana saya dapat menentukan untuk template pertama bahwa variabel yang digunakan adalah a = "File1" dan untuk yang kedua, b = "File2".

Kestemont Max
sumber
Apakah itu persis yang saya lakukan dengan semua resep saya, lihat komentar ini stackoverflow.com/a/40189525/1571310 , semoga bantuan ini!
Tecnocat

Jawaban:

51

Untuk 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

Untuk Ansible 1.x:

Sayangnya templatemodul tersebut tidak mendukung penerusan variabel ke dalamnya, yang dapat digunakan di dalam template. Ada permintaan fitur tapi ditolak.

Saya dapat memikirkan dua solusi:

1. Sertakan

The includemendukung pernyataan lewat variabel. Jadi Anda bisa memiliki templatetugas Anda di dalam file tambahan dan memasukkannya dua kali dengan parameter yang sesuai:

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. Definisikan ulang myTemplateVariable

Cara lain adalah dengan mendefinisikan ulang myTemplateVariable tepat sebelum setiap templatetugas.

- 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
udondan
sumber
Terima kasih atas jawabannya. Namun, apakah benar-benar tidak mungkin dilakukan tanpa solusi? Saat ini saya mencoba sesuatu seperti: stackoverflow.com/questions/26020465/… , tetapi masih mengalami beberapa kesalahan (mungkin tidak terkait langsung).
Kestemont Max
Ya, Anda juga dapat melakukannya dengan loop - tetap saja itu solusinya. :)
udondan
14
tidak diperlukan lagi. "vars" sekarang didukung. lihat jawaban @ konstantin-suvorov di bawah ini.
sonjz
123

Dengan Ansible 2.x Anda dapat menggunakan vars:tugas-tugas.

Template 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

Ini akan meneruskan myTemplateVariablenilai yang berbeda ke test.j2.

Konstantin Suvorov
sumber
9
awalnya saya membuat kesalahan dan vars: menjorok seperti sisa argumen template (seperti src :). Saya kira tingkat indentasi berarti vars: adalah tugasnya, bukan templatnya. Jadi Anda bisa melakukan ini di mana saja, bukan hanya template. bagus.
Greg
39

Anda dapat melakukan ini dengan sangat mudah, lihat resep Supervisor saya:

- 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

Keluaran:

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

Nikmati!

Tecnocat
sumber
Ini harus ditandai sebagai jawaban yang benar. Sejak didukung sekarang
PoX
23

Ini adalah solusi / retasan yang saya gunakan:

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

Setelah menjalankan ini, Anda masuk this is var_a/ tmp / templateA dan this is var_bdi / tmp / templateB.

Pada dasarnya Anda menyalahgunakan with_itemsuntuk membuat template dengan setiap item dalam daftar satu item. Ini berfungsi karena Anda dapat mengontrol apa daftar tersebut saat menggunakan with_items.

Kelemahannya adalah Anda harus menggunakan itemnama variabel di template Anda.

Jika Anda ingin meneruskan lebih dari satu variabel dengan cara ini, Anda dapat memilih sebagai item daftar Anda seperti ini:

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'

dan kemudian lihat mereka di template Anda seperti ini:

{{ item.var_1 }}
{{ item.var_2 }}
asmigala
sumber
1
Solusi bersih, tetapi topi untuk digunakanwith_items: '{{ var_a }}'
Peter Ajtai
8

Saya melakukannya dengan cara ini.

Dalam tugas / main.yml

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

dan di vars / main.yml

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

dan di templates / myTemplateFile.j2

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

Semoga ini menyelesaikan masalah Anda.

Nabarun Chatterjee
sumber
with_dictadalah solusi yang lebih baik.
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

PENTING: Perhatikan bahwa item tidak harus hanya berupa string, item dapat berupa objek dengan properti sebanyak yang Anda suka, sehingga Anda dapat meneruskan sejumlah variabel.

Dalam template saya punya:

<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>
Bart McLeod
sumber
1
Bagaimana saya bisa menjadikannya sebuah objek?
camdixon
1

Saya memiliki masalah serupa untuk dipecahkan, berikut adalah solusi sederhana tentang cara meneruskan variabel ke file template, triknya adalah menulis file template dengan memanfaatkan variabel. Anda perlu membuat kamus (daftar juga dimungkinkan), yang menampung kumpulan variabel yang sesuai dengan setiap file. Kemudian di dalam file template mengaksesnya.

Lihat di bawah:

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

pedoman

---
#
# 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 }}"
xbalaji
sumber
0

Contoh dunia nyata lainnya menggunakan daftar

ekstrak untuk template untuk 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 %}

Ini adalah 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" }

Lalu saya menyebarkan dengan 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}}"
krad
sumber