web-dev-qa-db-fra.com

Échappement de doubles accolades dans Ansible

Comment échapper aux doubles accolades dans Ansible 1.9.2?

Par exemple, comment puis-je échapper aux doubles accolades dans la commande Shell suivante?

- name: Test 
  Shell: "docker inspect --format '{{ .NetworkSettings.IPAddress }}' instance1"
45
Davide Guerri

Lorsque vous rencontrez des problèmes avec des caractères en conflit dans Ansible, vous devez les générer sous forme de chaîne dans une expression Jinja.

Donc, au lieu de {{, vous utiliseriez {{ '{{' }}:

- debug: msg="docker inspect --format '{{ '{{' }} .NetworkSettings.IPAddress {{ '}}' }}' instance1"

Sujet "Échapper" dans la documentation de Jinja2.

72
udondan

Ce:

- name: Test 
  Shell: "docker inspect --format {% raw %}'{{ .NetworkSettings.IPAddress }}' {% endraw %} instance1"

Devrait marcher

Une autre façon de faire consiste à utiliser des barres obliques inverses comme \{\{ .NetworkSettings.IPAddress \}\}

J'espère que ça aide

31
Filipe

Essayé avec ansible 2.1.1.0

Le bloc {% raw%} ... {% endraw%} semble être la solution

- name: list container images and name date on the server
  Shell: docker ps --format {%raw%}"{{.Image}} {{.Names}}"{%endraw%}

Seulement besoin d'échapper à la conduite '{{'

tasks:
- name: list container images and names
  Shell: docker ps --format "{{'{{'}}.Image}} {{'{{'}}.Names}}"

Aucun mal à échapper à la queue '}}', sauf plus difficile à lire.

tasks:
- name: list container images and names
  Shell: docker ps --format "{{'{{'}}.Image{{'}}'}} {{'{{'}}.Names{{'}}'}}"

La barre oblique inverse '\' semble ne pas fonctionner

16
Tiger peng

J'ai réussi à contourner mon problème à l'aide d'un petit script:

#!/usr/bin/env bash

docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$1"

Et le jeu Ansible suivant

- copy:
    src: files/get_docker_ip.sh
    dest: /usr/local/bin/get_docker_ip.sh
    owner: root
    group: root
    mode: 0770

- Shell: "/usr/local/bin/get_docker_ip.sh {{ Swift_ACCOUNT_HOSTNAME }}"
  register: Swift_account_info

Néanmoins, il est très surprenant que Ansible ne permette pas d’échapper aux doubles accolades!

3
Davide Guerri

J'ai un problème similaire: je dois publier un document JSON à partir d'un modèle jinja2 contenant des variables de modèles (par exemple, je sais :-P), telles que 

"NAME_TEMPLATE": %{{service_name}}.%{{stack_name}}.%{{environment_name}}

Essayer de clôturer cette partie du modèle entre 

{% raw %} ... {% endraw %}

n'a pas fonctionné car il y a une sorte de magie dans ansible qui exécute le modèle et le poste variable deux fois (je ne suis pas sûr de cela, mais ça ressemble vraiment à ça)

Vous vous retrouvez avec "variable non définie service_name" lorsque vous essayez d'utiliser le modèle ...

J'ai donc fini par utiliser une combinaison de !unsafe et {% raw %} ... {% endraw %} pour définir un fait qui sera utilisé plus tard dans le modèle.

- set_fact:
   __rancher_init_root_domain: "{{ rancher_root_domain }}"
   #!unsafe: try to trick ansible into not doing substitutions in that string, then use %raw% so the value won't substituted another time
   __rancher_init_name_template: !unsafe "{%raw%}%{{service_name}}.%{{stack_name}}.%{{environment_name}}{%endraw%}"

- name: build a template for a project
  set_fact:
    __rancher_init_template_doc: "{{ lookup('template', 'templates/project_template.json.j2') }}"

le modèle contient ceci:

    "ROOT_DOMAIN":"{{__rancher_init_root_domain}}",
    "ROUTE53_ZONE_ID":"",
    "NAME_TEMPLATE":"{{__rancher_init_name_template }}",
    "HEALTH_CHECK":"10000",

et la sortie est ok:

"NAME_TEMPLATE": "%{{service_name}}.%{{stack_name}}.%{{environment_name}}",
1
zuzur

Nouveau dans Ansible 2.0 est la possibilité de spécifier une valeur en tant que type non sécurisé.

Dans votre exemple, vous pourriez faire:

- name: Test 
  Shell: !unsafe "docker inspect --format '{{ .NetworkSettings.IPAddress }}' instance1"

Voir la documentation pour plus de détails.

1
Ben

Je n'ai pas pu obtenir la réponse de @ Ben au travail (Shell: !unsafe ...)

Ce qui suit est une réponse complète (et pratique!) À la question du PO, mise à jour pour Ansible> 2.0.

---
# file: play.yml

- hosts: localhost
  connection: local
  gather_facts: no
  vars:
    # regarding !unsafe, please see:
    # https://docs.ansible.com/ansible/latest/user_guide/playbooks_advanced_syntax.html
    #
    - NetworkSettings_IPAddress: !unsafe "{{.NetworkSettings.IPAddress}}"
  tasks:
    - Shell: "docker inspect --format '{{NetworkSettings_IPAddress}}' instance1"
      register: out
    - debug: var="{{item}}"                                                                                                   
      with_items:                                                                                                             
        - out.cmd                                                                                                             
        - out.stdout                                                                                                          

sorties: ([AVERTISSEMENTS] supprimé)

# ansible-playbook play.yml
PLAY [localhost] ***************************************************************

TASK [Shell] *******************************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => (item=out.cmd) => {
    "item": "out.cmd", 
    "out.cmd": "docker inspect --format '{{.NetworkSettings.IPAddress}}' instance1"
}
ok: [localhost] => (item=out.stdout) => {
    "item": "out.stdout", 
    "out.stdout": "172.17.0.2"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

# ansible --version | head -1
ansible 2.6.1
0
Marc Tamsky

Voici une alternative plus courte à la réponse de udondan ; entourez toute la chaîne de doubles crochets:

Shell: "docker inspect --format {{ '{{ .NetworkSettings.IPAddress }}' }} instance1"
0
bmaupin