Ansible: เรียกใช้งานเฉพาะเมื่อระบุแท็ก


76

แท็กที่สามารถบันทึกได้สามารถใช้เพื่อเรียกใช้งาน / บทบาทเพียงบางส่วน ซึ่งหมายความว่าโดยค่าเริ่มต้นงานทั้งหมดจะถูกดำเนินการและเราสามารถป้องกันงานบางอย่างที่จะดำเนินการเท่านั้น

เราสามารถ จำกัด งานที่จะ exectued เฉพาะเมื่อมีการระบุแท็ก "foo" เราสามารถใช้แท็กปัจจุบันในwhenส่วนของงานได้หรือไม่?


2
ดูเหมือนสิ่งที่คุณต้องการคือการตั้งค่างานบางอย่างเช่น limit_to_tags: foo ที่ไม่มีอยู่และฉันไม่คิดว่ามันจะเป็นไปได้ในขณะนี้ การใช้งานในอนาคตยังต้องมีแผนว่าจะให้แท็กเหล่านั้นพร้อมกันหรือไม่หรือ
dgh

ลองดูที่ anwser ของฉันใน "Ansible - ค่าเริ่มต้น / แท็กที่ชัดเจน" stackoverflow.com/questions/28789912/…
sirkubax

คำตอบ:


38

เบิ้ล 2.5 มาพร้อมกับแท็กพิเศษและnever สามารถใช้alwaysแท็กneverได้อย่างแม่นยำเพื่อจุดประสงค์นี้ เช่น:

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

ในตัวอย่างนี้งานจะทำงานเฉพาะเมื่อมีการร้องขอแท็กdebug(หรือnever) อย่างชัดเจน [อ้างอิงเอกสารที่บันทึกได้]


20

แม้ว่านี่จะเป็นทางออกของวงเวียน แต่ก็ใช้งานได้

ภายในรายการงานลงทะเบียนตัวแปรเมื่อมีการเรียกใช้งานปกติ จากนั้นเพิ่มเงื่อนไขเวลาที่ตรวจสอบตัวแปรนั้นในงานที่ติดแท็ก

- shell: /bin/true
  register: normal_task_list

- name: Only run when tag is specified
  shell: /bin/echo "Only running because of specified tag"
  when: normal_task_list is not defined
  tags: specified

คุณยังสามารถใช้untaggedเพื่อให้บรรลุสิ่งนี้:- set_fact: untagged_run=true tags: untagged
Pyzo

คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับเรื่องนี้หน่อยได้ไหม? ตัวอย่างโลกแห่งความจริง?
Quintin Par

17

ฉันไม่มีชื่อเสียงพอที่จะ upvote หรือแสดงความคิดเห็นในคำตอบที่แนะนำการใช้ตัวแปรบรรทัดคำสั่ง ( --extra-vars) แต่ฉันมีสิ่งนี้เพื่อเพิ่ม:

ข้อแม้ของวิธีนี้คือการเล่นจะผิดพลาดและล้มเหลวหากคุณไม่ได้กำหนดตัวแปรเพิ่มเติมนั้น

คุณสามารถป้องกันความล้มเหลวในการเล่นในกรณีที่ไม่มี--extra-varsคำจำกัดความโดยการกำหนดค่าเริ่มต้นใน playbook เอง:

---
- hosts: ...
# ↓↓↓
  vars:
    thorough: false
# ↑↑↑
  tasks:
  - name: apt - install nfs-common only when thorough is true
    when: thorough | bool
    apt:
      cache_valid_time: 86400
      force: yes
      pkg:
        - nfs-common

การเอาชนะผ่าน--extra-varsจะยังคงทำงานได้เนื่องจากตัวแปรที่กำหนดไว้ในบรรทัดคำสั่งมีความสำคัญมากกว่าคำจำกัดความอื่นทั้งหมด

ผลลัพธ์ก็คือการเล่นจะทำงานโดยไม่มีข้อผิดพลาดเมื่อthoroughไม่มีการเปลี่ยนแปลงเป็นtrueบนบรรทัดคำสั่ง


5
thorough | default('no') | boolเช่นเดียวกับที่สามารถทำได้โดยใช้
Costi Ciudatu

2
หรือwhen: thorough is defined and thoroughถ้าคุณชอบที่ไวยากรณ์
KCD

ขอบคุณที่รักis defined andไวยากรณ์มากขึ้น มากกว่าท่อหลายท่อที่ฉันไม่รู้สึกว่าใช้งานง่าย
Elijah Lynn

10

คุณสามารถใช้เงื่อนไขเพื่อป้องกันงานที่ตั้งใจทำงานซึ่งจะถูกดำเนินการหากคุณไม่ระบุแท็ก ข้อแม้ของวิธีนี้คือการเล่นจะผิดพลาดและล้มเหลวหากคุณไม่ได้กำหนดตัวแปรเพิ่มเติมนั้น

การใช้อาร์กิวเมนต์พิเศษ vars คุณสามารถเรียกใช้เงื่อนไขของคุณเพื่อดำเนินการ

จาก ansible-playbook - ช่วย:

 -e EXTRA_VARS, --extra-vars=EXTRA_VARS
    set additional variables as key=value or YAML/JSON

ตัวอย่าง:

ansible-playbook test.yaml -e "thorough=true"

test.yaml:

...
- name: apt - install nfs-common only when thorough is true
  apt:
    cache_valid_time: 86400
    force: yes
    pkg:
    - nfs-common
  when: thorough | default(False)
...

2
เพื่อหลีกเลี่ยงข้อผิดพลาดถ้าคุณไม่ได้กำหนด "อย่างละเอียด" thorough | default("false") | match("true")เพียงแค่ใช้ ค่าเริ่มต้นไม่จำเป็นต้องเป็นfalseเพียงแค่สิ่งใดที่ไม่ตรงกันtrueแต่จะปรับปรุงความสามารถในการอ่าน
Tom Wilson

4

การตรวจสอบตัวแปร 'แท็ก' ไม่ทำงานใน Ansible 2.1.1.0 ดูด้านล่างสำหรับการทดสอบ ฉันมีความคิดอื่นที่จะทำงานเฉพาะเมื่อมีการกำหนดแท็กทำงานทั้ง Ansible 1.9.X และ 2.XY:

- set_fact: foo=true
  tags: bar
- set_fact: foo=false
- name: do something when 'bar' tag is defined
  debug: var=foo
  when: foo
  tags: bar

เมื่อใช้ playbook ที่ไม่มีแท็กตัวแปร 'foo' จะถูกตั้งค่าเป็น true จากนั้นเป็น false จึงไม่มีการดำเนินการใด ๆ หากคุณเพิ่มแท็ก 'บาร์' จะมีการใช้การตั้งค่าแรกเท่านั้นดังนั้นตัวแปร 'foo' จะเป็นจริงดังนั้นงานของคุณจะถูกดำเนินการ สนุก!


และนี่คือการทดสอบเกี่ยวกับตัวแปร 'แท็ก' ใน Ansible 2.1.1.0:

นี่คือ playbook:

- hosts: localhost
  connection: local
  tasks:
    - name: display tags variable
      debug: var=tags
      tags: foo

    - name: do something only when tag 'foo' is provided
      debug: var=tag
      when: tags is defined
      tags: foo

และนี่คือผลลัพธ์:

$ ansible-playbook --version ; ansible-playbook ./test.yml -t foo
ansible-playbook 2.1.1.0
  config file = /home/nootal/projects/ivy/src/ansible/ansible.cfg
  configured module search path = Default w/o overrides

PLAY [localhost] ***************************************************************

TASK [display tags variable] ***************************************************
ok: [localhost] => {
    "tags": "VARIABLE IS NOT DEFINED!"
}

TASK [do something only when tag 'foo' is provided] ****************************

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

2

ใช่. การรันเพลย์บุ๊คแบบอ่านไม่ได้พร้อมการ--tags fooตั้งค่าสถานะจะช่วยให้มั่นใจได้ว่าfooมีการดำเนินการเฉพาะงานที่ติดแท็กด้วย ตัวอย่างเช่นสมมติว่าเรามี playbook ชื่อ example.yml:

tasks:

  - yum: name={{ item }} state=installed
    with_items:
       - httpd
       - memcached
    tags:
       - packages

  - name: some other task
    ..
    tags:
      - some other tag

วิ่ง:

ansible-playbook example.yml --tags "packages"

จะทำให้แน่ใจว่ามีการใช้งาน yum เท่านั้น

ดังนั้นจริงๆแล้วคุณไม่จำเป็นต้องใช้แท็กในเมื่อส่วนเพื่อดำเนินงานตามเงื่อนไข โปรดสังเกตว่าขึ้นอยู่กับความซับซ้อนของ playbooks / บทบาทที่คุณอาจต้องใช้ --tags และ --skip-tags เพื่อควบคุมงานที่จะถูกดำเนินการ ตัวอย่างเช่นหากมีการรวมงานไว้แท็กเป็น 'foo' และงานบางอย่างภายใน playbook ที่รวมถูกติดแท็กเป็น 'bar' และคุณเรียกใช้

ansible-playbook --tags "foo"

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

ansible-playbook --tags foo --skip-tags bar

7
สิ่งนี้ไม่เป็นความจริง: "การระบุแท็กบนงานหมายความว่าเฉพาะเมื่อแท็กนี้ถูกส่งผ่านไปยังคำสั่ง ansible-playbook อย่างชัดเจนว่างานจะถูกดำเนินการ"
gimboland

1
ประการที่สองคำสั่งไม่เป็นความจริง
คริส

10
ใช่คุณสามารถบรรลุพฤติกรรมได้โดยให้แน่ใจว่าคุณใช้ansible-playbookตัวเลือกที่ถูกต้องเสมอแต่ฉันคิดว่า OP กำลังขอวิธีในการใส่คำอธิบายประกอบงานเพื่อไม่ให้ทำงานเว้นแต่ว่าจะมีการเพิ่มแท็กเฉพาะในansible-playbookคำสั่งอย่างชัดเจน
dgh

4
ใช่นี่ไม่ได้ตอบคำถามของ OP
Allen Luce

การทำงานทั้งหมดที่ติดแท็ก / ไม่ติดแท็กทำงานเมื่อคุณไม่ได้ระบุแท็ก แท็กไม่สามารถยกเว้นการทำงานที่จะเรียกใช้รวมถึงเท่านั้น ไม่มีตรรกะที่แยกได้ยกเว้นตัวกรองเพิ่มเติม
bbaassssiiee

1

มีแท็กพิเศษคือ "ไม่เคย"ซึ่งจะป้องกันไม่ให้งานทำงานจนกว่าจะมีการร้องขอแท็กโดยเฉพาะ

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]

พูดถึงแล้วในคำตอบข้างต้น: serverfault.com/a/907329/105928
Taha Jahangir

0

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

เช่นลองนึกภาพ playbook และคลังโฆษณา

สินค้าคงคลัง #
[dev]
192.168.1.1

# site.yml
- โฮสต์: dev
  บทบาท:
    - {บทบาท: ทั่วไป}

และโดยทั่วไป / task / main.yml

# role / common / task / main.yaml
- ชื่อ: ติดตั้งลิงก์
  apt: name = links state = present

- รวมถึง: uninstall.yml
  เมื่อ: uninstall_links ถูกกำหนดไว้
  Tags:
    - ถอนการติดตั้ง

# role / common / task / uninstall.yml
- ชื่อ: ถอนการติดตั้งลิงก์
  apt: name = links state = ไม่มีอยู่

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

วิธีเรียกใช้ทุกอย่าง (จะติดตั้งและถอนการติดตั้ง):

$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true"

วิธีรันเฉพาะแท็ก 'ถอนการติดตั้ง' ในกลุ่ม dev

$ ansible-playbook -i inventory site.yml -l dev -s -k -e "uninstall_links=true" -t uninstall

ดังนั้นตัวแปรและแท็กอาจอยู่ใน site.yml / ไฟล์คลังข้อมูลซึ่งช่วยให้คุณสามารถกำหนด SCM และบันทึกความตั้งใจของคุณได้


0

nootal ถูกต้องแนวทางของฉันใช้งานไม่ได้ - ละเว้นมัน :( ตอนนี้ฉันใช้ "เมื่อ: myvar ถูกกำหนด" และสวิตช์บรรทัดคำสั่ง "-e" myvar = X "เพื่อทำงานเฉพาะเมื่อมีการร้องขออย่างชัดเจนเท่านั้น

ง่ายยิ่งขึ้น (อย่างน้อยด้วย ansible 2.1.1.0):

- name: do something only when tag 'foo' is provided
  when: tags is defined
  tags: foo

-> จะทำงานเมื่อมีการจัดเตรียมแท็กและแท็กมี "foo"


0

บนAnsible 2.3.2.0นี่เป็นวิธีแก้ปัญหาของฉัน:

---
- hosts: localhost
  gather_facts: no
  vars:
    in_tag: yes
  tasks:
    - set_fact: in_tag=no
    - fail:
        msg: "recently_added is set and you're using blah tag"
      when: ( in_tag | bool )
      tags:
        - blah
    - debug:
        msg: "always remember"

มันเริ่มต้นด้วยการตั้งค่าin_tagไปTrueแล้วมีความเป็นset_factที่ชุดมันกลับไปFalseเมื่อคุณไม่ได้ระบุใด ๆจากtagsansible-playbook

เมื่อคุณระบุแท็กin_tagอยู่ที่Trueและfailงานจะทำงาน

PS: คุณสามารถเพิ่มตรรกะในงานใด ๆ ที่คุณต้องการ

PS2: คุณสามารถขยายตรรกะและฮาร์ดโค้ดแท็กทั้งหมดที่คุณมีและset_fact: in_tag_blah=Trueใช้ร่วมกับtags: ["blah"]หลักสูตรได้

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