จะใช้โมดูลเทมเพลตกับชุดตัวแปรต่างๆได้อย่างไร


93

กรณีการใช้งานของฉันมีดังต่อไปนี้:

ฉันมีไฟล์เทมเพลตและฉันต้องการสร้างไฟล์ 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"


นั่นคือสิ่งที่ฉันทำกับสูตรทั้งหมดของฉันดูความคิดเห็นนี้stackoverflow.com/a/40189525/1571310หวังว่านี่จะช่วยได้!
Tecnocat

คำตอบ:


52

สำหรับ 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โมดูลไม่รองรับการส่งผ่านตัวแปรไปซึ่งสามารถใช้ภายในเทมเพลตได้ มีคำขอคุณสมบัติแต่ถูกปฏิเสธ

ฉันคิดวิธีแก้ปัญหาได้สองวิธี:

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 ใหม่

อีกวิธีหนึ่งคือการกำหนด myTemplateVariable ใหม่ก่อนทุก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

ขอบคุณสำหรับคำตอบ อย่างไรก็ตามมันเป็นไปไม่ได้จริงๆที่จะทำโดยไม่มีวิธีแก้ปัญหา? ขณะนี้ฉันกำลังลองสิ่งที่ต้องการ: stackoverflow.com/questions/26020465/…แต่ยังคงมีข้อผิดพลาดบางอย่าง (อาจไม่เกี่ยวข้องโดยตรง)
Kestemont Max

ใช่คุณสามารถทำแบบวนซ้ำได้เช่นกัน แต่ก็ยังเป็นวิธีแก้ปัญหาชั่วคราว :)
udondan

14
ไม่จำเป็นอีกต่อไป "vars" ได้รับการสนับสนุนแล้ว ดูคำตอบของ @ konstantin-suvorov ด้านล่าง
sonjz

123

ด้วย Ansible 2.x คุณสามารถใช้vars:กับงานต่างๆ

แม่แบบ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

สิ่งนี้จะส่งผ่านmyTemplateVariableค่าต่างๆไปยัง test.j2


9
ตอนแรกฉันทำผิดพลาดและมี vars: เยื้องเหมือนกับอาร์กิวเมนต์เทมเพลตที่เหลือ (เช่น src :) ฉันเดาว่าระดับการเยื้องหมายถึง vars: เป็นของงานไม่ใช่เทมเพลต คุณจึงสามารถทำได้ทุกที่ไม่ใช่แค่เทมเพลต ดี.
Greg

39

คุณสามารถทำได้ง่ายมากดูสูตร 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

เอาท์พุต:

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

สนุก!


ควรทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง ตั้งแต่รองรับตอนนี้
PoX

23

นี่คือวิธีแก้ปัญหา / แฮ็คที่ฉันใช้:

งาน / 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'

แม่แบบ / test.j2:

{{ item }}

หลังจากรันสิ่งนี้คุณจะได้รับthis is var_aใน / tmp / templateA และthis is var_bใน / tmp / templateB

โดยทั่วไปคุณละเมิด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 }}

1
with_items: '{{ var_a }}'
น้ำยา

8

ฉันทำมันด้วยวิธีนี้

ในงาน / 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

และในเทมเพลต / myTemplateFile.j2

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

หวังว่านี่จะช่วยแก้ปัญหาของคุณได้


with_dictเป็นทางออกที่ดีกว่า
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

สิ่งสำคัญ: โปรดทราบว่ารายการไม่จำเป็นต้องเป็นเพียงสตริง แต่อาจเป็นวัตถุที่มีคุณสมบัติมากเท่าที่คุณต้องการเพื่อให้คุณสามารถส่งผ่านตัวแปรจำนวนเท่าใดก็ได้

ในเทมเพลตฉันมี:

<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
ฉันจะทำให้มันเป็นวัตถุได้อย่างไร?
camdixon

1

ฉันมีปัญหาที่คล้ายกันในการแก้ไขนี่คือวิธีง่ายๆในการส่งตัวแปรไปยังไฟล์เทมเพลตเคล็ดลับคือการเขียนไฟล์เทมเพลตโดยใช้ประโยชน์จากตัวแปร คุณต้องสร้างพจนานุกรม (รายการก็ทำได้เช่นกัน) ซึ่งเก็บชุดของตัวแปรที่สอดคล้องกับแต่ละไฟล์ จากนั้นภายในไฟล์เทมเพลตจะเข้าถึงได้

ดูด้านล่าง:

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

playbook

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

อีกตัวอย่างหนึ่งในโลกแห่งความเป็นจริงโดยใช้รายการ

สารสกัดสำหรับเทมเพลตสำหรับ 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 %}

นี่คือ 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" }

จากนั้นฉันปรับใช้กับสิ่งนี้

- 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}}"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.