Ansible: Task nur ausführen, wenn ein Tag angegeben ist

76

Ansible-Tags können verwendet werden, um nur eine Teilmenge von Aufgaben / Rollen auszuführen. Dies bedeutet, dass standardmäßig alle Aufgaben ausgeführt werden und wir nur einige Aufgaben daran hindern können, ausgeführt zu werden.

Können wir eine auszuführende Aufgabe nur einschränken , wenn das Tag "foo" angegeben ist? Können wir aktuelle Tags in einem whenAbschnitt einer Aufgabe verwenden?

Taha Jahangir
quelle
2
Es hört sich so an, als ob Sie eine Aufgabeneinstellung wie limit_to_tags: foo benötigen, die nicht existiert und ich denke, dass dies im Moment nicht möglich ist. Eine zukünftige Implementierung muss auch einen Plan haben, ob diese Tags zusammen UND oder ODER verknüpft werden sollen.
dgh
Schauen Sie sich meine Antwort in "Ansible - Default / Explicit Tags" an. Stackoverflow.com/questions/28789912/…
sirkubax

Antworten:

38

Ansible 2.5 kommt mit speziellen Tags neverund always. Tag neverkann genau für diesen Zweck verwendet werden. Z.B:

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

In diesem Beispiel wird die Task nur ausgeführt, wenn das debug(oder never) -Tag explizit angefordert wird. [Verweis auf anible docs]

Taha Jahangir
quelle
20

Dies ist zwar eine Umgehungslösung, funktioniert aber.

Registrieren Sie in der Aufgabenliste eine Variable, wenn die normale Ausführung ausgeführt wird. Fügen Sie dann eine when-Bedingung hinzu, die diese Variable zur markierten Aufgabe prüft.

- 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
quelle
Sie können auch verwenden untagged, um dies zu erreichen:- set_fact: untagged_run=true tags: untagged
Pyzo
Können Sie uns das etwas näher erläutern? Ein reales Beispiel?
Quintin Par
17

Ich habe nicht genug Reputation, um die Antwort, die die Verwendung von Befehlszeilenvariablen ( --extra-vars) vorschlägt, zu verbessern oder zu kommentieren , aber ich muss Folgendes hinzufügen:

Die Einschränkung bei dieser Methode besteht darin, dass die Wiedergabe fehlerhaft ist und fehlschlägt, wenn Sie diese zusätzliche Variable nicht definieren.

Sie können Spielfehler verhindern, --extra-varswenn keine Definition vorliegt, indem Sie einen Standardwert im Playbook selbst definieren:

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

Das Überschreiben von Via --extra-varsfunktioniert weiterhin, da in der Befehlszeile definierte Variablen Vorrang vor allen anderen Definitionen haben.

Das Ergebnis ist, dass die Wiedergabe ohne Fehler ausgeführt wird, wenn thoroughin trueder Befehlszeile nicht auf geändert wird.

Alex Peters
quelle
5
Das gleiche kann mit erreicht werden thorough | default('no') | bool.
Costi Ciudatu
2
Oder when: thorough is defined and thoroughwenn Sie diese Syntax bevorzugen
KCD
Danke, liebe die is defined andSyntax mehr. Mehr als die vielen Pfeifen, die ich nicht fühle, sind intuitiv.
Elijah Lynn
10

Sie können Conditionals verwenden , um sich vor versehentlich ausgeführten Aufgaben zu schützen, die andernfalls ausgeführt würden, wenn Sie kein Tag angeben. Die Einschränkung bei dieser Methode besteht darin, dass die Wiedergabe fehlerhaft ist und fehlschlägt, wenn Sie diese zusätzliche Variable nicht definieren.

Mit dem Argument extra-vars können Sie die Ausführung Ihrer Bedingung auslösen.

Aus ansible-playbook --help:

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

Beispiel:

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
quelle
2
Um Fehler zu vermeiden, wenn Sie nicht "gründlich" definieren, verwenden Sie einfach thorough | default("false") | match("true"). Standard muss nicht sein false, nur alles, was nicht passt true, aber es verbessert die Lesbarkeit.
Tom Wilson
4

Das Überprüfen der Variablen 'tags' funktioniert in Ansible 2.1.1.0 nicht. Siehe unten für den Test. Ich habe eine andere Idee, eine Aufgabe nur dann auszuführen, wenn ein Tag definiert ist, und zwar für Ansible 1.9.X und 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

Wenn Sie das Playbook ohne Tags ausführen, wird die Variable 'foo' auf true und dann auf false gesetzt, sodass nichts ausgeführt wird. Wenn Sie das Tag "bar" hinzufügen, wird nur die erste Einstellung angewendet, sodass die Variable "foo" auf "true" gesetzt wird. Anschließend wird Ihre Aufgabe ausgeführt. Genießen!


Und hier ist der Test zur Variablen 'tags' in Ansible 2.1.1.0:

Hier ist das Spielbuch:

- 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

Und hier ist die Ausgabe:

$ 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
quelle
2

Ja. Wenn Sie ansible-playbook mit dem --tags fooFlag ausführen, wird sichergestellt, dass nur Aufgaben ausgeführt werden, die mit einem Tag versehen foosind. Angenommen, wir haben ein Playbook mit dem Namen example.yml:

tasks:

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

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

Laufen:

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

Stellt sicher, dass nur die YUM-Aufgabe ausgeführt wird.

Tatsächlich müssen Sie also keine Tags im when-Abschnitt verwenden, um eine Aufgabe bedingt auszuführen. Beachten Sie, dass Sie abhängig von der Komplexität Ihrer Playbooks / Rollen möglicherweise eine Kombination aus --tags und --skip-Tags verwenden müssen, um zu steuern, welche Aufgaben ausgeführt werden. Zum Beispiel, wenn eine Einschlussaufgabe als 'foo' markiert ist und eine Aufgabe im enthaltenen Playbook als 'bar' markiert ist und Sie ausgeführt werden

ansible-playbook --tags "foo"

Die interne Aufgabe (nur als "Balken" gekennzeichnet) wird ausgeführt. Um zu vermeiden, dass alle internen Aufgaben ausgeführt werden, die als "Balken" gekennzeichnet sind, müssen Sie den folgenden Befehl ausführen

ansible-playbook --tags foo --skip-tags bar
Shahar
quelle
7
Dies ist nicht wahr: "Das Angeben eines Tags für eine Aufgabe bedeutet, dass diese Aufgabe nur ausgeführt wird, wenn dieses Tag explizit an den ansible-playbook-Befehl übergeben wird."
Gimboland
1
Abgeordnet, Aussage ist nicht wahr.
Chris
10
Ja, Sie können das Verhalten erreichen, indem Sie sicherstellen, dass Sie immer die richtigen ansible-playbookOptionen verwenden, aber ich glaube, das OP fragt nach einer Möglichkeit, eine Aufgabe mit Anmerkungen zu versehen, damit sie nur ausgeführt wird, wenn dem ansible-playbookBefehl explizit ein bestimmtes Tag hinzugefügt wird .
dgh
4
Ja, das beantwortet nicht die Frage des OP.
Allen Luce
Alle Aktionen mit oder ohne Tags werden ausgeführt, wenn Sie kein Tag angeben. Tags können eine auszuführende Aktion nicht ausschließen, sondern nur einschließen. Es gibt keine Prädikatenlogik außer einem additiven Filter.
Baassssiiee
1

Es gibt ein spezielles Tag - "never" , das verhindert, dass eine Aufgabe ausgeführt wird, es sei denn, ein Tag wird speziell angefordert.

tasks:
  - debug: msg='{{ showmevar}}'
    tags: [ 'never', 'debug' ]
xtoznaxto
quelle
Bereits in der obigen Antwort erwähnt: serverfault.com/a/907329/105928
Taha Jahangir
0

Die when- Klausel kann das Vorhandensein von Tags nicht bewerten. Um dies zu umgehen, verwende ich Variablen und Tags zusammen, um Aufgaben auszuführen, die für dieses Tag / diese Variable spezifisch sind.

Bsp .: Stellen Sie sich ein Spielbuch und ein Inventar vor

# inventar
[dev]
192.168.1.1

# site.yml
- Gastgeber: dev
  Rollen:
    - {Rolle: gemeinsam}

und gemeinsam / tasks / main.yml

# role / common / tasks / main.yaml
- name: Installiere Links
  apt: name = links state = present

- Include: uninstall.yml
  wann: uninstall_links ist definiert
  Stichworte:
    - deinstallieren

# role / common / tasks / uninstall.yml
- name: Links deinstallieren
  apt: name = links state = abwesend

Bei diesem Ansatz verwenden Sie das Tag, um nur die Tasks in uninstall.yml auszuwählen. Sie müssen jedoch auch die Variable 'uninstall_links' auf einen Wert setzen, um sie zu aktivieren. Wenn Sie also das Playbook ohne Parameter ausführen, wird standardmäßig die Installationsaufgabe ausgeführt. So deinstallieren, können Sie den Tag ‚uninstall‘ auf Ihrem Textbuch (oder cmdline) festgelegt und muss die Variable gesetzt. Wenn Sie das Tag nicht festlegen, wird alles (installieren und deinstallieren) in dieser Reihenfolge ausgeführt. Dies ist gut, um den gesamten Prozess zu testen.

So führen Sie alles aus (es wird installiert und deinstalliert):

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

Wie man nur das 'uninstall'-Tag auf der dev-Gruppe ausführt

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

Daher können sich Variablen und Tags auch in den Dateien site.yml / inventory befinden. Auf diese Weise können Sie sich in Ihr SCM einfügen und Ihre Absichten aufzeichnen.

Anderson Goulart
quelle
0

nootal ist richtig, mein Ansatz funktioniert nicht - ignoriere es :( Ich benutze jetzt "when: myvar is defined" und die Befehlszeilenoption "-e" myvar = X ", um Aufgaben nur auf ausdrücklichen Wunsch auszuführen.

Noch einfacher (zumindest mit ansible 2.1.1.0):

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

-> wird nur ausgeführt, wenn Tags bereitgestellt wurden UND die Tags "foo" enthalten

DrPsychick
quelle
0

Auf Ansible 2.3.2.0, hier ist meine Lösung für das Problem:

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

Es beginnt mit der Einstellung in_tagzu , Truedann gibt es eine , set_factdie es zurück setzt , Falsewenn Sie angeben nicht tagsaus ansible-playbook.

Wenn Sie Tags angeben, in_tagbleibt bei Trueund die failTask wird ausgeführt.

PS: Sie können die Logik zu beliebigen Aufgaben hinzufügen

PS2: Sie können auch die Logik und den Hardcode für alle Tags erweitern, die Sie haben, und natürlich set_fact: in_tag_blah=Truein Kombination mit tags: ["blah"].

tehmoon
quelle