Mögliche Änderung des Standardwerts entsprechend einer Bedingung

16

Ist es möglich, einen Rollenvariablen-Standardwert gemäß einer bestimmten Bedingung (dh dem Wert einer anderen Variablen) zu ändern?

Einzelheiten

Ich habe zwei verwandte Variablen für einen Befehl envund composer_opts.

Wenn beide auf Standard ( env = "prod"und composer_opts = "--no-dev") belassen werden, ist alles in Ordnung.

Wenn ich ändern envzu dev, wird die Standardeinstellung für die anderen meinen Befehl brechen, so dass ich immer beide müssen eingestellt werden . Wäre es möglich, dies zu vermeiden, indem Sie einen bedingten Standardwert mit einem benutzerdefinierten Skript festlegen / if?

Wichtig: Ich möchte den Wert nicht immer dem composer_optsWert entsprechend einstellen env. Ich möchte es nur einstellen, wenn es nicht bereits eingestellt ist (dh ein dynamischer Standardwert).

Pseudocode

Ich möchte so etwas tun (folgender Code ist nicht gültig, nur Pseudocode, um mein Bedürfnis auszudrücken)

---
# defaults/main.yml

env: prod
composer_opts: 
    when: "{{env}}" = 'prod'
        '--no-dev --optimize-autoloader --no-interaction'
    when: "{{env}}" = 'dev'
        '' 
Francesco Abeni
quelle

Antworten:

12

Ich schlage folgende Lösung vor:

---
 - set_fact:
     composer_opts: ""
   when: "{{env}}" == 'dev'

Es setzt die composer_optsVariable auf string, ""wenn die Variable envgleich ' dev' ist.

Hier ist ein Beispiel für ein Spielbuch, das auf einer aktualisierten Frage basiert:

$ cat test.yml

---
- hosts: 127.0.0.1
  connection: local
  tasks:
  - set_fact:
      composer_opts: "{% if env == 'prod' %} '--no-dev --optimize-autoloader --no-interaction' {% else %} '' {% endif %}"

  - debug: var=composer_opts

Beispielausgabe:

sudo ansible-playbook test.yml -e env=dev

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [set_fact ] ************************************************************* 
ok: [127.0.0.1]

TASK: [debug var="{{composer_opts}}"] ***************************************** 
ok: [127.0.0.1] => {
    "var": {
        " '' ": " '' "
    }
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   


sudo ansible-playbook test.yml -e env=prod

PLAY [127.0.0.1] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [127.0.0.1]

TASK: [set_fact ] ************************************************************* 
ok: [127.0.0.1]

TASK: [debug var="{{composer_opts}}"] ***************************************** 
ok: [127.0.0.1] => {
    "var": {
        " '--no-dev --optimize-autoloader --no-interaction' ": " '--no-dev --optimize-autoloader --no-interaction' "
    }
}

PLAY RECAP ******************************************************************** 
127.0.0.1                  : ok=3    changed=0    unreachable=0    failed=0   
Navern
quelle
1
Dies ist ein Teil der Lösung. Es wird immer composer_optsauf leere Zeichenfolge gesetzt, wenn env"dev" ist, und jeder tatsächliche Wert wird überschrieben. Ich denke , dass die bedingte sollte wie folgt erweitert werden: when: "{{env}}" == 'dev' and "{{composer_opts}}" is undefined. Sieht es gut aus Können Sie Ihre Frage entsprechend udpate?
Francesco Abeni
composer_opts wird definiert, weil es den Standardwert hat. Sie benötigen einen anderen Ausdruck, um Ihre Aufgabe zu lösen. Zum Beispiel Variable custom_composer_opts.
Navern,
Bitte erarbeiten Sie mit Pseudocode, was Sie tun möchten. Ich werde meine Antwort entsprechend aktualisieren.
Navern
Ich habe meine Frage mit zusätzlicher Erklärung und Pseudocode-Beispiel aktualisiert. Vielen Dank.
Francesco Abeni
Ich habe meine Antwort aktualisiert. Prüfen Sie. Ich glaube, ich habe verstanden, was Sie brauchen.
Navern,
4

Während die Antwort von @ Navern funktioniert, stellte ich fest, dass die eingebettete Jinja2-Notation ( "{% if env == 'prod' %} ...) extrem anfällig für Notationen und daher ziemlich zerbrechlich ist. Wenn Sie beispielsweise die betreffende Zeile zur besseren Lesbarkeit umbrechen, wie in diesem nicht getesteten Code :

composer_opts: >
               "{% if env == 'prod' %}
                   '--no-dev --optimize-autoloader --no-interaction'
                {% else %}
                   ''
                {% endif %}"

Am Ende hatte ich unerwartete Ergebnisse, z. B. zusätzliches Leerzeichen oder \nin composer_opts.

Der Ansatz, den ich benutze, ist viel langweiliger, aber auch stabiler:

- name: set composer_opts for dev env
  set_fact:
     composer_opts: ''
     when: "{{env}}" == 'dev'

- name: set composer_opts for prod env
  set_fact:
     composer_opts: '--no-dev --optimize-autoloader --no-interaction'
     when: "{{env}}" == 'prod'

Ich fand auch diesen Blog-Beitrag nützlich, der im Wesentlichen dem gleichen Ansatz folgt.

ssc
quelle
Wenn Sie @sec |anstelle von verwenden >, besteht möglicherweise kein Problem mit Leerzeichen. (oder du bekommst mehr davon LOL)
Michael
@sec Verwenden Sie '> -' und überprüfen Sie die ansible-Spezifikation. Es gibt viele Optionen für die korrekte Bearbeitung mehrzeiliger Zeichenfolgen. yaml-multiline.info Beachten Sie insbesondere den Block-Chomping-Indikator.
DylanYoung
Beachten Sie, dass diese Lösung auch Vorrangprobleme hatte. Eine Tatsache ist keine Vorgabe.
DylanYoung
2

Ansible set_fact basierend auf der Bedingung in einem Liner:

- name: "set composer_opts based on environment"
  set_fact:
     composer_opts:  "{{ '--no-dev --optimize-autoloader --no-interaction' if (env == 'prod') else '' }}"
SK Venkat
quelle
Gleiche Priorität wie bei den anderen Lösungen (Fakt ist keine Standardeinstellung). Wenn Sie diese Bedingung jedoch in Ihre Datei defaults.yml aufnehmen, funktioniert diese Lösung. Es wird sehr hässlich, sehr schnell, wenn Sie eine Reihe von Standardeinstellungen abhängig von der Bedingung haben
DylanYoung