web-dev-qa-db-fra.com

Ansible variables entières en YAML

J'utilise Ansible pour déployer une application Web. J'aimerais attendre que l'application soit en cours d'exécution en vérifiant qu'une page donnée renvoie un JSON avec une clé/valeur donnée.

Je veux que la tâche soit essayée plusieurs fois avant d’échouer. J'utilise donc la combinaison de until/retries/delay keybwords.

La question est, je veux que le nombre de retries soit pris à partir d'une variable. Si j'écris:

  retries: {{Apache_test_retries}}

Je tombe dans l'habituel Yaml Gotcha ( http://docs.ansible.com/YAMLSyntax.html#gotchas ).

Si, au contraire, j'écris:

  retries: "{{Apache_test_retries}}"

On me dit que la valeur n'est pas un entier.

ValueError: littéral non valide pour int () avec base 10: '{{Apache_test_retries}}'

Voici mon code complet:

- name: Wait for the application to be running
  local_action:
    uri
    url=http://{{webapp_url}}/health
    timeout=60
  register: res
  Sudo: false
  when: updated.changed and Apache_test_url is defined
  until: res.status == 200 and res['json'] is defined and res['json']['status'] == 'UP'
  retries: "{{Apache_test_retries}}"
  delay: 1

Une idée sur la façon de contourner ce problème? Merci.

15
Alexis Seigneurin

J'avais complètement le même problème et j'essayais beaucoup de choses qui ne fonctionnaient pas, alors je le faisais tourner sans variable, mais je trouvais la réponse qui convenait à tous ceux qui le possédaient.

La solution de Daniels devrait en effet fonctionner:

retries: "{{ Apache_test_retries | int }}"

Mais si vous utilisez une version un peu plus ancienne de ansible, cela ne fonctionnera pas. Donc, assurez-vous que vous avez mise à jour ansible j'ai testé le 1.8.4 et que cela fonctionne et que cela ne fonctionne pas le 1.8.2

C’était le bogue original sur ansible: https://github.com/ansible/ansible/issues/5865

18
iblazevic

Vous devriez pouvoir le convertir en un entier avec le filtre int :

retries: "{{ Apache_test_retries | int }}"
9
udondan

J'ai rencontré un problème similaire. Dans mon cas, je voulais redémarrer le service celeryd. Le redémarrage prend parfois beaucoup de temps et je voulais lui donner un maximum de 30 secondes pour un redémarrage progressif, puis le redémarrer de force. J'ai utilisé async pour cela (interrogation du résultat du redémarrage toutes les 5 secondes).

celery/handlers/main.yml

- name: restart celeryd
  service:
    name=celeryd
    state=restarted
  register: celeryd_restart_result
  ignore_errors: true
  async: "{{ async_val | default(30) }}"
  poll: 5

- name: check celeryd restart result and force restart if needed
  Shell: service celeryd kill && service celeryd start
  when: celeryd_restart_result|failed

Et puis j'utilise ci-dessus dans le livre de lecture comme gestionnaires d'une tâche (restart celeryd est toujours le premier dans la liste notify


Dans votre cas, quelque chose comme ci-dessous pourrait éventuellement fonctionner. Je n'ai pas vérifié si c'était le cas, mais cela pourrait vous donner une bonne idée de le résoudre autrement. De plus, étant donné que vous allez ignorer les erreurs dans la première tâche, vous devez vous assurer que tout va bien dans la deuxième:

- name: Poll to check if the application is running
  local_action:
    uri
    url=http://{{webapp_url}}/health
    timeout=60
  register: res
  Sudo: false
  when: updated.changed and Apache_test_url is defined
  failed_when: res.status != 200 and res['json'] is not defined and not res['json']['status'] == 'UP'
  ignore_errors: true
  async: "{{ Apache_test_retries | default(60) }}"
  poll: 1

  # Task above will exit as early as possible on success
  # It will keep trying for 60 secs, polling every 1 sec
  # You need to make sure it's fine **again** because it has ignore_errors: true

- name: Final UP check
  local_action:
    uri
    url=http://{{webapp_url}}/health
    timeout=60
  register: res
  Sudo: false
  when: updated.changed and Apache_test_url is defined
  failed_when: res.status != 200 and res['json'] is not defined and not res['json']['status'] == 'UP'

J'espère que cela vous aidera à résoudre le problème avec un bogue dans retries.

0
Michal Gasek

Avez-vous vérifié que vous avez le bon nom de variable? 

Ansible utilise le modèle de variable Jinja2. Donc, si la variable n'existe pas, elle est remplacée par une chaîne vide. 

http://jinja.pocoo.org/docs/dev/templates/

Si une variable ou un attribut n'existe pas, vous récupérerez une valeur indéfinie. Ce que vous pouvez faire avec ce type de valeur dépend de la configuration de l’application: le comportement par défaut est qu’elle est évaluée comme chaîne vide, et que vous pouvez effectuer une itération dessus, mais toutes les autres opérations échouent.

0
Thomas Betous