Ansible: Jalankan tugas hanya ketika tag ditentukan

75

Tag yang dapat digunakan hanya dapat menjalankan sebagian tugas / peran. Ini berarti bahwa secara default semua tugas dijalankan dan kami hanya dapat mencegah beberapa tugas untuk dijalankan.

Bisakah kita membatasi tugas yang akan dikecualikan hanya ketika tag "foo" ditentukan? Bisakah kita menggunakan tag saat ini di whenbagian tugas?

Taha Jahangir
sumber
2
kedengarannya seperti yang Anda butuhkan adalah beberapa pengaturan tugas seperti limit_to_tags: foo yang tidak ada dan saya pikir itu tidak mungkin saat ini. Implementasi di masa mendatang juga perlu memiliki rencana apakah akan DAN atau ATAU tag-tag itu bersama.
dgh
Lihatlah anwser saya di "Ansible - Default / Explicit Tags" stackoverflow.com/questions/28789912/…
sirkubax

Jawaban:

38

Kemungkinan 2,5 dilengkapi dengan tag khusus neverdan always. Tag neverdapat digunakan tepat untuk tujuan ini. Misalnya:

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

Dalam contoh ini, tugas hanya akan berjalan ketika tag debug(atau never) diminta secara eksplisit. [Referensi tentang dokumen yang memungkinkan]

Taha Jahangir
sumber
20

Meskipun ini adalah solusi bundaran, ia bekerja.

Di dalam daftar tugas, daftarkan variabel saat eksekusi normal berjalan. Kemudian, tambahkan kondisi ketika yang memeriksa variabel itu ke tugas yang ditandai.

- 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
Chris Chipman
sumber
Anda juga dapat menggunakannya untaggeduntuk mencapai ini:- set_fact: untagged_run=true tags: untagged
Pyzo
Bisakah Anda menjelaskan lebih banyak tentang ini? Contoh dunia nyata?
Quintin Par
17

Saya tidak memiliki reputasi yang cukup untuk meningkatkan atau mengomentari jawaban yang menyarankan penggunaan variabel baris perintah ( --extra-vars), tetapi saya memiliki ini untuk ditambahkan:

Peringatan untuk metode ini adalah bahwa permainan akan kesalahan dan gagal jika Anda tidak mendefinisikan variabel tambahan itu.

Anda dapat mencegah kegagalan bermain dengan tidak adanya --extra-varsdefinisi dengan menetapkan nilai default di dalam buku pedoman itu sendiri:

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

Mengganti melalui --extra-varsmasih akan berfungsi karena variabel yang ditentukan pada baris perintah didahulukan dari semua definisi lainnya.

Hasilnya adalah bahwa permainan berjalan tanpa kesalahan ketika thoroughtidak diubah ke truepada baris perintah.

Alex Peters
sumber
5
Hal yang sama dapat dicapai dengan menggunakan thorough | default('no') | bool.
Costi Ciudatu
2
Atau when: thorough is defined and thoroughjika Anda lebih menyukai sintaks itu
KCD
Terima kasih, lebih menyukai is defined andsintaksis. lebih dari beberapa pipa yang saya rasa tidak intuitif.
Elijah Lynn
10

Anda dapat menggunakan Kondisional untuk melindungi terhadap tugas yang tidak sengaja berjalan yang seharusnya dieksekusi jika Anda tidak menentukan tag. Peringatan untuk metode ini adalah bahwa permainan akan kesalahan dan gagal jika Anda tidak mendefinisikan variabel tambahan itu.

Menggunakan argumen extra-vars Anda dapat memicu kondisi Anda untuk dieksekusi.

Dari ansible-playbook --help:

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

Contoh:

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)
...
Ava
sumber
2
Untuk menghindari kesalahan jika Anda tidak mendefinisikan "menyeluruh" gunakan saja thorough | default("false") | match("true"). Default tidak harus false, hanya apa saja yang tidak cocok true, tetapi meningkatkan keterbacaan.
Tom Wilson
4

Memeriksa variabel 'tag' tidak berfungsi di An 2.1.1.0. Lihat di bawah untuk tes. Saya punya ide lain untuk mengeksekusi tugas hanya ketika tag didefinisikan, bekerja untuk Ansible 1.9.X dan 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

Dengan itu, saat menjalankan playbook tanpa tag apa pun, variabel 'foo' akan disetel ke true lalu menjadi false, sehingga tidak ada yang dijalankan. Jika Anda menambahkan tag 'bilah', hanya pengaturan pertama yang akan diterapkan, sehingga variabel 'foo' akan benar, maka tugas Anda akan dieksekusi. Nikmati!


Dan inilah tes tentang variabel 'tag' di An 2.1.1.0:

Ini buku pedomannya:

- 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

Dan inilah hasilnya:

$ 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   
nootal
sumber
2

Iya. Menjalankan playbook yang mungkin dengan --tags foobendera akan memastikan bahwa hanya tugas yang ditandai dengan fooyang dijalankan. Misalnya, anggap kita memiliki buku pedoman bernama example.yml:

tasks:

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

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

berlari:

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

Akan memastikan hanya tugas yum yang dieksekusi.

Jadi sebenarnya Anda tidak benar-benar perlu menggunakan tag ketika bagian untuk menjalankan tugas kondisional. Perhatikan bahwa tergantung pada kerumitan buku pedoman / peran Anda, Anda mungkin perlu menggunakan kombinasi --tags dan --skip-tag untuk mengontrol tugas yang dijalankan. Misalnya, jika tugas yang disertakan ditandai sebagai 'foo' dan beberapa tugas di dalam buku pedoman yang disertakan ditandai sebagai 'bilah' dan Anda menjalankan

ansible-playbook --tags "foo"

Tugas internal (hanya ditandai sebagai 'bilah') akan dieksekusi. Untuk menghindari pelaksanaan semua tugas internal yang ditandai sebagai 'bilah' Anda harus menjalankan perintah berikut

ansible-playbook --tags foo --skip-tags bar
Shahar
sumber
7
Ini tidak benar: "Menentukan tag pada tugas berarti bahwa hanya ketika tag ini diteruskan secara eksplisit ke perintah playbook yang memungkinkan tugas itu akan dieksekusi."
gimboland
1
Yang kedua, pernyataan itu tidak benar.
Chris
10
ya, Anda dapat mencapai perilaku dengan memastikan Anda selalu menggunakan ansible-playbookopsi yang tepat , tetapi saya pikir OP meminta cara untuk membubuhi keterangan tugas sehingga tidak dieksekusi kecuali tag tertentu ditambahkan secara eksplisit dalam ansible-playbookperintah.
dgh
4
Ya, ini tidak menjawab pertanyaan OP.
Allen Luce
semua tindakan yang ditandai / tidak ditandai dijalankan ketika Anda tidak menentukan tag. Tag tidak dapat mengecualikan tindakan untuk dijalankan, hanya sertakan. Tidak ada logika predikat kecuali filter aditif.
bbaassssiiee
1

Ada tag khusus - "tidak pernah" , yang akan mencegah tugas berjalan kecuali jika tag diminta secara khusus.

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]
xtoznaxto
sumber
Sudah disebutkan dalam jawaban di atas: serverfault.com/a/907329/105928
Taha Jahangir
0

ketika klausa tidak dapat mengevaluasi keberadaan tag. Sebagai solusinya, saya menggunakan variabel dan tag secara bersamaan untuk menjalankan tugas khusus untuk tag / variabel tersebut.

Contoh: Bayangkan sebuah buku pedoman dan inventaris

# inventaris
[dev]
192.168.1.1

# site.yml
- host: dev
  peran:
    - {peran: umum}

dan secara umum / task / main.yml

# peran / umum / tugas / main.yaml
- nama: Instal tautan
  apt: name = links state = present

- termasuk: uninstall.yml
  ketika: uninstall_links didefinisikan
  tag:
    - uninstall

# peran / umum / tugas / uninstall.yml
- name: Copot tautan
  apt: name = tautan status = tidak ada

Dengan pendekatan ini, Anda menggunakan tag untuk hanya memilih tugas di uninstall.yml, tetapi Anda juga perlu mengatur variabel 'uninstall_links' menjadi sesuatu untuk mengaktifkannya. Jadi, jika Anda menjalankan playbook tanpa parameter apa pun, secara default, akan menjalankan tugas instal. Untuk mencopot pemasangan, Anda dapat mengatur tag 'mencopot' ke buku pedoman Anda (atau cmdline) dan HARUS mengatur variabel. Jika Anda tidak menetapkan tag, itu akan menjalankan semuanya (instal dan hapus instalan) dalam urutan itu, yang bagus untuk menguji seluruh proses.

Cara menjalankan semuanya (ini akan menginstal dan menghapus instalan):

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

Cara menjalankan hanya tag 'copot pemasangan' pada grup dev

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

Karenanya, variabel dan tag juga bisa ada di file site.yml / inventaris, memungkinkan Anda untuk berkomitmen ke dalam SCM Anda dan mencatat niat Anda.

Anderson Goulart
sumber
0

nootal benar, pendekatan saya tidak bekerja - abaikan saja :( Saya sekarang menggunakan "kapan: myvar didefinisikan" dan saklar baris perintah "-e" myvar = X "untuk menjalankan tugas hanya ketika diminta secara eksplisit.

Bahkan lebih mudah (setidaknya dengan an 2.1.1.0):

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

-> hanya akan mengeksekusi ketika tag telah disediakan DAN tag termasuk "foo"

DrPsychick
sumber
0

Pada Ansible 2.3.2.0, inilah solusi saya untuk masalah ini:

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

Dimulai dengan menetapkan in_taguntuk Truemaka ada set_factyang menetapkan kembali ke Falseatas ketika Anda tidak menentukan tagsdari ansible-playbook.

Ketika Anda menentukan tag, in_tagtetap di Truedan failtugas berjalan.

PS: Anda dapat menambahkan logika ke tugas apa pun yang Anda inginkan

PS2: Anda juga dapat memperluas logika dan hardcode semua tag yang Anda miliki dan set_fact: in_tag_blah=Truedikombinasikan dengan tags: ["blah"]tentu saja.

teh bulan
sumber