ตอบได้ - ใช้ค่าเริ่มต้นหากไม่ได้กำหนดตัวแปร


105

ฉันกำลังปรับแต่งusersการสร้างlinux ภายในบทบาทของฉัน ฉันต้องการที่จะให้ผู้ใช้ปรับแต่งบทบาทของฉันhome_directory, group_name, ,namepassword

ฉันสงสัยว่ามีวิธีที่ยืดหยุ่นกว่าในการจัดการกับค่าเริ่มต้นหรือไม่

ฉันรู้ว่ารหัสด้านล่างเป็นไปได้:

- name: Create default
  user:
    name: "default_name"
  when: my_variable is not defined

 - name: Create custom
  user:
    name: "{{my_variable}}"
  when: my_variable is defined

แต่อย่างที่ฉันพูดไปมีตัวแปรที่เป็นทางเลือกมากมายและสิ่งนี้สร้างความเป็นไปได้มากมาย

มีบางอย่างเหมือนโค้ดด้านบนหรือไม่?

user:
  name: "default_name", "{{my_variable}}"

ควรตั้งรหัสname="default_name"เมื่อmy_variableไม่ได้กำหนด

ฉันสามารถตั้งค่าตัวแปรทั้งหมดdefaults/main.ymlและสร้างผู้ใช้เช่นนั้น:

- name: Create user
  user:
    name: "{{my_variable}}"

แต่ตัวแปรเหล่านั้นอยู่ในแฮชที่ใหญ่มากและมีแฮชบางตัวอยู่ภายในแฮชที่ไม่สามารถเป็นค่าเริ่มต้นได้


คำตอบ:


199

คุณสามารถใช้ Jinja's default:

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"

10
และถ้าตัวแปรเริ่มต้นขึ้นอยู่กับตัวแปรอื่น ตัวอย่างเช่นdefault('/home/' {{ anothervar }})มีวิธีการเชื่อมต่อค่าเหล่านั้นหรือไม่?
Bernardo Vale

8
เพียงแค่ลบ 'รอบ ๆdefault_valueและจะใช้ตัวแปรที่เรียกว่า default_value
dagonza

7
{{ dict.key | default(5) }}ไม่ทำงานถ้าตัวแปรซ้อนเช่น มันจะล้มเหลวหากdictไม่ได้กำหนด
Jordan Stewart

1
FYI สิ่งนี้จะทำให้เกิดข้อผิดพลาด:[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
bryan kennedy

1
@JordanStewart ฉันมีกรณีเดียวกัน - มีตัวแปรซ้อน ฉันโพสต์คำตอบพร้อมวิธีแก้ไขที่เป็นไปได้ด้านล่าง
Roman Kruglov

12

ไม่เกี่ยวข้องทั้งหมด แต่คุณสามารถตรวจสอบตัวแปรundefinedAND empty(เช่นmy_variable:) ได้ด้วย (หมายเหตุ: ใช้ได้เฉพาะกับรุ่น ansible> 1.9 ดู: ลิงค์ )

- name: Create user
  user:
    name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
    if my_variable is defined else 'default_value' }}"

2
นี้ดีมีประโยชน์มาก
eagle33322

6

ถ้าใครที่กำลังมองหาตัวเลือกที่จะจัดการกับตัวแปรที่ซ้อนกันที่มีตัวเลือกหลายอย่างเช่นในเรื่องนี้ปัญหา GitHub

ในระยะสั้นคุณต้องใช้ตัวกรอง "ค่าเริ่มต้น" สำหรับ vars ที่ซ้อนกันทุกระดับ สำหรับตัวแปร "a.nested.var" จะมีลักษณะดังนี้:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ((a | default({})).nested | default({}) ).var | default('bar') }}"

หรือคุณสามารถตั้งค่าเริ่มต้นของคำสั่งว่างสำหรับแต่ละระดับของตัวแปรโดยอาจใช้ตัวกรอง "รวม" หรือใช้ตัวกรอง "json_query" แต่ตัวเลือกที่ฉันเลือกดูเหมือนจะง่ายกว่าสำหรับฉันถ้าคุณมีรังเพียงระดับเดียว


5

หากคุณมีการเล่นครั้งเดียวที่คุณต้องการวนซ้ำรายการให้กำหนดรายการนั้นใน group_vars / ทั้งหมดหรือที่อื่นที่เหมาะสม:

all_items:
  - first
  - second
  - third
  - fourth

จากนั้นงานของคุณจะมีลักษณะดังนี้:

  - name: List items or default list
    debug:
      var: item
    with_items: "{{ varlist | default(all_items) }}"

ส่งใน varlist เป็นอาร์เรย์ JSON:

ansible-playbook <playbook_name> --extra-vars='{"varlist": [first,third]}'

ก่อนหน้านั้นคุณอาจต้องการงานที่ตรวจสอบว่าแต่ละรายการในvarlistอยู่ในall_items ด้วย :

  - name: Ensure passed variables are in all_items
    fail:
      msg: "{{ item }} not  in all_items list"
    when: item not in all_items
    with_items: "{{ varlist | default(all_items) }}"

4

ในกรณีที่คุณใช้การค้นหาเพื่อตั้งค่าการอ่านเริ่มต้นจากสภาพแวดล้อมคุณได้ตั้งค่าพารามิเตอร์ที่สองของค่าเริ่มต้นเป็น true:

- set_facts:
    ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('foo', true) }}"

คุณยังสามารถเชื่อมต่อคำจำกัดความเริ่มต้นหลาย ๆ

- set_facts:
    ansible_ssh_user: "{{ some_var.split('-')[1] | default(lookup('env','USER'), true) | default('foo') }}"

2

คำถามค่อนข้างเก่า แต่สิ่งที่เกี่ยวกับ:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ( a | default({})).get('nested', {}).get('var','bar') }}"

มันดูยุ่งยากสำหรับฉันน้อยกว่า ...


1

หากคุณกำลังกำหนดค่าเริ่มต้นสำหรับข้อเท็จจริงบูลีนตรวจสอบให้แน่ใจว่าไม่มีการใช้เครื่องหมายคำพูดภายในค่าเริ่มต้น ()

- name: create bool default
  set_fact:
    name: "{{ my_bool | default(true) }}"

สำหรับตัวแปรอื่น ๆ ใช้วิธีการเดียวกันกับที่ระบุในคำตอบที่ยืนยันแล้ว

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.