Ansible: กำหนดตัวแปรในไฟล์ vars ตามเงื่อนไขหากตรงตามเงื่อนไขที่กำหนด


19

ขึ้นอยู่กับค่า (True / False) ของตัวแปรที่กำหนดไว้ใน group_vars ฉันพยายามกำหนดตัวแปรบางอย่างในไฟล์ vars ค่าของพวกเขาขึ้นอยู่กับค่าของกลุ่ม var

ไฟล์ var ปัจจุบันของฉันมีลักษณะดังนี้:

{% if my_group_var %}
test:
   var1: value
   var2: value
   ...
   varn: value
{% else %}
test:
   var1: other_value
   var2: other_value
   ...
   varn: other_value
{% endif %}

สำหรับบทบาทของฉันฉันใช้ตัวแปรที่กำหนดไว้ในไฟล์นี้

Playbook ทดสอบของฉันมีลักษณะดังนี้:

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/test_vars.yml
  roles: blabla 

ข้อผิดพลาดที่ฉันได้รับหลังจากเรียกใช้ playbook คือ:

{% if my_group_var %}
 ^ here

exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning for the next token
found character that cannot start any token
  in "<unicode string>"

ฉันกำลังทำสิ่งที่โง่ที่นี่หรือไม่สนับสนุนแม้กระทั่ง? ฉันพยายามหาวิธีอื่นในการกำหนด vars เหล่านี้ (ฉันมีจำนวนมาก) แต่ฉันไม่สามารถจัดการบางสิ่งบางอย่างได้ที่นี่ ข้อเสนอแนะใด ๆ


ขวดเหล่านี้ถูกใช้งานที่ไหน? สิ่งนี้อาจไม่จำเป็นถ้าคุณจะใช้มันเพื่อเป็นส่วนหนึ่งของการtemplateเรียกโมดูล
84104

หากtestขึ้นอยู่กับกลุ่มควรวางลงใน group_vars
Konstantin Suvorov

น่าเสียดายที่การทดสอบไม่ได้ขึ้นอยู่กับกลุ่ม ดังกล่าวในคำอธิบายการทดสอบขึ้นอยู่กับค่าของตัวแปร group_var
pandoJohn

คำตอบ:


11

ฉันไม่คิดว่าคุณสามารถทำได้ฉันมักจะสร้างไฟล์แยกต่างหากเพื่อเก็บคอลเลกชันตัวแปรตามเงื่อนไขและใช้ส่วนwhenคำสั่งเพื่อรวมไฟล์เหล่านั้นไว้ในเงื่อนไขเฉพาะ:

- include_vars: test_environment_vars.yml
  when: global_platform == "test"

- include_vars: staging_environment_vars.yml
  when: global_platform == "staging"

- include_vars: prod_environment_vars.yml
  when: 
    - global_platform != "test" 
    - global_platform != "staging" 

2
นี่คือสิ่งที่ฉันพยายามหลีกเลี่ยง ฉันไม่ต้องการใช้รวม vars หรือกำหนดไฟล์ var เพิ่มเติม 2 ไฟล์สำหรับงานของฉัน
pandoJohn

ฉันไม่เข้าใจ .. เมื่อเป็นไปได้ที่จะใช้ include_vars พร้อมเงื่อนไขทำไมไม่สามารถกำหนดตัวแปรด้วยเงื่อนไขได้
GP92

10

Ansible อนุญาตให้หนึ่งในรูปแบบต่อไปนี้เพื่อกำหนดตัวแปรตามเงื่อนไข:

    test:
      var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
      var2: "{{'value' if (my_group_var) else 'other_value'}}"

การรวมไวยากรณ์ข้างต้นเข้ากับการค้นหา vars เราสามารถโหลด vars ที่ซับซ้อน (รายการในกรณีนี้):

test_value_when_my_group_var_is_true:
   var1: value
   var2: value

test_value_when_my_group_var_is_false:
   var1: other_value
   var2: other_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"

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

test_value_when_my_group_var_is_foo:
   var1: value
   var2: value

test_value_when_my_group_var_is_bar:
   var1: other_value
   var2: other_value

test_value_when_my_group_var_is_baz:
   var1: yet_another_value
   var2: yet_another_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"

2

แม้จะเป็นเรื่องดี แต่ฉันก็กลัวว่าจะเป็นไปไม่ได้ (หรือฉันไม่รู้ตัว)

ฉันขอแนะนำให้เตรียมไฟล์ vars จากเทมเพลต jinja ก่อนแล้วจึงรวมมันไว้ใน include_vars ดูตัวอย่าง playbook:

---
- name: -Test-
  hosts: local
  vars:
    my_group_var: False
#    my_group_var: True

  tasks:

  - name: Prepare vars file from template.
    template: src=/tmp/vars.yaml.j2
              dest=/tmp/vars.yaml

  - name: Include vars
    include_vars: "/tmp/vars.yaml"

เนื้อหาของตัวอย่าง jinja template /tmp/vars.yaml.j2 คือ:

{% if my_group_var %}                                                                                                                                                                                             
test:                                                                                                                                                                                                             
   var1: value                                                                                                                                                                                                    
   var2: value                                                                                                                                                                                                    
{% else %}                                                                                                                                                                                                        
test:                                                                                                                                                                                                             
   var1: other_value                                                                                                                                                                                              
   var2: other_value                                                                                                                                                                                              
{% endif %}

ฉันชอบสิ่งนี้ แต่ปัญหาคือหลังจากสร้างไฟล์ .yml จากเทมเพลต jinja แล้วมันไม่สามารถใช้ได้สำหรับงานที่ตามมาจาก playbook ของฉัน
pandoJohn

ทำไม? เมื่อฉันพยายามที่จะขยาย playbook ทดสอบด้วยงานตรวจแก้จุดบกพร่อง- debug: var=testฉันเห็นว่ามีการกำหนดไว้ทั้งสองtest.var1และtest.var2มีค่าที่คาดหวัง ดังนั้นคุณควรจะสามารถใช้ตัวแปรเหล่านี้ในงานอื่น ๆ ของ playbook
Jaroslav Kucera

0

AFAIK สิ่งนี้ที่คุณพยายามทำคือเทมเพลต Jinja2 ไม่ใช่ไฟล์ yml จากเอกสาร :

ansible อนุญาตให้ Jinja2 ลูปและเงื่อนไขในเทมเพลต แต่ใน playbooks เราไม่ได้ใช้

คุณสามารถจัดเตรียมไฟล์ .yml แยกต่างหากด้วยการเล่นที่ตั้งค่าตัวแปรที่คุณต้องการใช้ในส่วนคำสั่งจากนั้นจึงนำเข้า (หรือรวมถึง) ไฟล์เหล่านั้นใน playbook หลักของคุณ ด้วยวิธีนี้คุณสามารถกำหนด vars ทั้งหมดแบบมีเงื่อนไขในไฟล์เดียว

หรือ: ใช้บทบาท ฉันคิดว่าบทบาทเป็นวิธีที่เพียงพอที่สุดในการแก้ปัญหาของคุณ


0

สิ่งที่ฉันได้ในท้ายที่สุดก็คือการสร้าง 2 ไฟล์ var แยกต่างหาก - ขอเรียกพวกเขาtype_a.ymlและtype_b.yml- และฉันกำหนดตัวแปรกลุ่มที่บ่งชี้ว่าสิ่งที่ไฟล์ที่จะใช้งาน - type_of_file: aสิ่งที่ชอบ นี่คือลักษณะที่ playbook ของฉันตอนนี้:

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/type_{{ type_of_file }}.yml
  roles: blabla

ขอบคุณสำหรับคำตอบทั้งหมด ฉันคิดว่ามันมีประโยชน์จริงๆ


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