Ansible: Chỉ thực thi tác vụ khi thẻ được chỉ định


76

Thẻ ansible có thể được sử dụng để chỉ chạy một tập hợp con của các tác vụ / vai trò. Điều này có nghĩa là theo mặc định tất cả các tác vụ được thực thi và chúng tôi chỉ có thể ngăn một số tác vụ thực thi.

Chúng ta có thể giới hạn một tác vụ chỉ được thực hiện khi thẻ "foo" được chỉ định không? Chúng ta có thể sử dụng các thẻ hiện tại trong whenphần của một nhiệm vụ?


2
có vẻ như những gì bạn cần là một số cài đặt tác vụ như giới hạn_to_tags: foo không tồn tại và tôi không nghĩ rằng điều đó là có thể ngay bây giờ. Việc triển khai trong tương lai cũng cần phải có kế hoạch về việc VÀ VÀ HOẶC các thẻ đó cùng nhau.
3:39

Hãy xem anwser của tôi trong "Ansible - Thẻ mặc định / Thẻ rõ ràng" stackoverflow.com/questions/28789912/
Kẻ

Câu trả lời:


38

Ansible 2.5 đi kèm với các thẻ đặc biệt neveralways. Tag nevercó thể được sử dụng chính xác cho mục đích này. Ví dụ:

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

Trong ví dụ này, tác vụ sẽ chỉ chạy khi thẻ debug(hoặc never) được yêu cầu rõ ràng. [Tham khảo về tài liệu ansible]


20

Mặc dù đây là một giải pháp bùng binh, nhưng nó hoạt động.

Trong danh sách tác vụ đăng ký một biến khi thực thi bình thường chạy. Sau đó, thêm một điều kiện khi kiểm tra biến đó vào tác vụ được gắn thẻ.

- 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

Bạn cũng có thể sử dụng untaggedđể thực hiện điều này:- set_fact: untagged_run=true tags: untagged
Pyzo

Bạn có thể giải thích thêm một chút về điều này? Một ví dụ thực tế?
Quintin Par

17

Tôi không có đủ danh tiếng để nâng cấp hoặc nhận xét về câu trả lời cho thấy việc sử dụng các biến dòng lệnh ( --extra-vars), nhưng tôi có điều này để thêm vào nó:

Thông báo trước cho phương pháp này là phát sẽ lỗi và thất bại nếu bạn không xác định biến phụ đó.

Bạn có thể ngăn thất bại khi chơi mà không có --extra-varsđịnh nghĩa bằng cách xác định giá trị mặc định trong chính 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

Ghi đè thông qua --extra-varsvẫn sẽ hoạt động vì các biến được xác định trên dòng lệnh được ưu tiên hơn tất cả các định nghĩa khác.

Kết quả là vở kịch chạy không có lỗi khi thoroughkhông được thay đổi thành truedòng lệnh.


5
Điều tương tự có thể đạt được bằng cách sử dụng thorough | default('no') | bool.
Costi Ciudatu

2
Hoặc when: thorough is defined and thoroughnếu bạn thích cú pháp đó
KCD

Cảm ơn, yêu is defined andcú pháp nhiều hơn. nhiều hơn nhiều đường ống mà tôi không cảm thấy là trực quan.
Elijah Lynn

10

Bạn có thể sử dụng Điều kiện để bảo vệ chống lại các tác vụ đang vô tình chạy nếu không chỉ định thẻ. Thông báo trước cho phương pháp này là phát sẽ lỗi và thất bại nếu bạn không xác định biến phụ đó.

Sử dụng đối số ngoại lệ, bạn có thể kích hoạt điều kiện của mình để được thực thi.

Từ ansible-playbook - trợ giúp:

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

Thí dụ:

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

kiểm tra.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
Để tránh lỗi nếu bạn không xác định "triệt để" chỉ cần sử dụng thorough | default("false") | match("true"). Mặc định không phải là false, chỉ là bất cứ điều gì không phù hợp true, nhưng nó cải thiện khả năng đọc.
Tom Wilson

4

Kiểm tra biến 'tags' không hoạt động trong Ansible 2.1.1.0. Xem dưới đây để kiểm tra. Tôi có một ý tưởng khác chỉ thực hiện tác vụ khi thẻ được xác định, hoạt động cho cả Ansible 1.9.X và 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

Cùng với đó, khi chạy playbook mà không có bất kỳ thẻ nào, biến 'foo' sẽ được đặt thành true rồi thành false, vì vậy không có gì được thực thi. Nếu bạn thêm thẻ 'bar', chỉ cài đặt đầu tiên sẽ được áp dụng, vì vậy biến 'foo' sẽ là đúng, thì tác vụ của bạn sẽ được thực thi. Thưởng thức!


Và đây là bài kiểm tra về biến 'tags' trong Ansible 2.1.1.0:

Đây là vở kịch:

- 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

Và đây là đầu ra:

$ 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

Đúng. Chạy ansible-playbook với --tags foocờ sẽ đảm bảo rằng chỉ các tác vụ được gắn thẻ mới foođược thực thi. Ví dụ: giả sử chúng ta có một playbook gọi là example.yml:

tasks:

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

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

đang chạy:

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

Sẽ đảm bảo chỉ có nhiệm vụ yum được thực thi.

Vì vậy, thực sự bạn không thực sự cần phải sử dụng thẻ khi phần để thực hiện một cách có điều kiện một nhiệm vụ. Lưu ý rằng tùy thuộc vào độ phức tạp của sách / vai trò của bạn, bạn có thể cần sử dụng kết hợp các thẻ --tags và --skip để kiểm soát tác vụ nào được thực hiện. Ví dụ: nếu một tác vụ bao gồm được gắn thẻ là 'foo' và một số tác vụ bên trong sổ chơi được bao gồm sẽ được gắn thẻ là 'thanh' và bạn chạy

ansible-playbook --tags "foo"

Tác vụ nội bộ (chỉ được gắn thẻ là 'bar') sẽ được thực thi. Để tránh việc thực thi tất cả các tác vụ nội bộ được gắn thẻ là 'bar', bạn sẽ phải thực hiện lệnh sau

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

7
Điều này không đúng: "Chỉ định thẻ trên một tác vụ có nghĩa là chỉ khi thẻ này được chuyển rõ ràng cho lệnh ansible-playbook thì tác vụ đó sẽ được thực thi."
gimboland

1
Thứ hai, tuyên bố là không đúng sự thật.
Chris

10
có, bạn có thể đạt được hành vi bằng cách đảm bảo bạn luôn sử dụng các ansible-playbooktùy chọn phù hợp , nhưng tôi nghĩ OP đang yêu cầu cách chú thích một tác vụ để nó không được thực thi trừ khi một thẻ cụ thể được thêm rõ ràng vào ansible-playbooklệnh.
dGH

4
Vâng, đây không phải là trả lời câu hỏi của OP.
Allen Luce

tất cả các hành động được gắn thẻ / không được gắn thẻ chạy khi bạn không chỉ định thẻ. Thẻ không thể loại trừ một hành động để chạy, chỉ bao gồm. Không có logic vị ngữ ngoại trừ bộ lọc phụ gia.
bbaassssiiee

1

Có một thẻ đặc biệt - "không bao giờ" , điều này sẽ ngăn tác vụ chạy trừ khi thẻ được yêu cầu cụ thể.

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

Đã được đề cập trong câu trả lời trên: serverfault.com/a/907329/105928
Taha Jahangir

0

khi mệnh đề không thể đánh giá sự hiện diện của thẻ. Như một giải pháp thay thế, tôi sử dụng các biến và thẻ cùng nhau để chạy các tác vụ cụ thể cho thẻ / biến đó.

Ví dụ: Hãy tưởng tượng một cuốn sách và hàng tồn kho

# hàng tồn kho
[dev]
192.168.1.1

# trang web.yml
- máy chủ: dev
  vai trò:
    - {vai trò: chung}

và trong chung / nhiệm vụ / main.yml

# vai trò / chung / nhiệm vụ / main.yaml
- tên: Cài đặt liên kết
  apt: name = links state = hiện tại

- bao gồm: Uninstall.yml
  khi: Uninstall_links được xác định
  thẻ:
    - gỡ cài đặt

# vai trò / chung / nhiệm vụ / Uninstall.yml
- tên: Gỡ cài đặt liên kết
  apt: name = links state = vắng mặt

Với cách tiếp cận này, bạn sử dụng thẻ để chỉ chọn các tác vụ trong Uninstall.yml, nhưng bạn cũng cần đặt biến 'Uninstall_links' thành thứ gì đó để kích hoạt nó. Vì vậy, nếu bạn chạy playbook mà không có bất kỳ tham số nào, theo mặc định, nó sẽ chạy tác vụ cài đặt. Để gỡ cài đặt, bạn có thể đặt thẻ 'gỡ cài đặt' vào sổ chơi của bạn (hoặc cmdline) và PHẢI đặt biến. Nếu bạn không đặt thẻ, nó sẽ chạy mọi thứ (cài đặt và gỡ cài đặt) theo thứ tự đó, rất tốt để kiểm tra toàn bộ quá trình.

Cách chạy mọi thứ (nó sẽ cài đặt và gỡ cài đặt):

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

Cách chỉ chạy thẻ 'gỡ cài đặt' trên nhóm dev

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

Do đó, các biến và thẻ cũng có thể nằm trong tệp site.yml / Inventory, cho phép bạn cam kết vào SCM của bạn và ghi lại ý định của bạn.


0

nootal là đúng, cách tiếp cận của tôi không hoạt động - bỏ qua nó :( Bây giờ tôi sử dụng "khi: myvar được xác định" và chuyển đổi dòng lệnh "-e" myvar = X "để thực hiện các tác vụ chỉ khi được yêu cầu rõ ràng.

Thậm chí dễ dàng hơn (ít nhất là với ansible 2.1.1.0):

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

-> sẽ chỉ thực thi khi các thẻ đã được cung cấp VÀ các thẻ bao gồm "foo"


0

Trên Ansible 2.3.2.0, đây là giải pháp của tôi cho vấn đề:

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

Nó bắt đầu bằng cách thiết lập in_tagđể Truesau đó có một set_factthiết lập lại Falsekhi bạn không chỉ định bất kỳ tagstừ ansible-playbook.

Khi bạn chỉ định các thẻ, hãy in_tagở lại Truefailtác vụ sẽ chạy.

PS: bạn có thể thêm logic vào bất kỳ tác vụ nào bạn muốn

PS2: bạn cũng có thể mở rộng logic và mã hóa cứng tất cả các thẻ bạn có và set_fact: in_tag_blah=Truekết hợp với tags: ["blah"]tất nhiên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.