Puedo usar Jinja2 `mapa` de filtro en un Ansible juego para obtener los valores de un array de objetos?

Tengo una playbook para la creación de algunas instancias de EC2 y luego de hacer algunas cosas con ellos. Las piezas pertinentes son aproximadamente como:

- name: create ec2 instances
  ec2:
    id: '{{ item.name }}'
    instance_type: '{{ item.type }}'
  register: ec2
  with_items: '{{ my_instance_defs }}'
- name: wait for SSH
  wait_for:
    host: '{{ item.instances[0].private_ip }}'
    port: 22
  with_items: '{{ ec2.results }}'

Esto funciona como está previsto, pero no estoy especialmente contento con el item.instances[0].private_ip expresión, en parte porque muestra muy grande de objetos en el juego en el resumen. Me encantaría tener la with_items parte en una matriz de direcciones IP, en lugar de un array de objetos con las matrices de los objetos dentro de ellos. En Python, sólo quiero hacer algo como:

ips = [r['instances'][0]['private_ip'] for r in ec2['results']]

Y, a continuación, me gustaría utilizar with_items: '{{ ips }}' en la segunda tarea.

Es hay alguna manera de hacer lo mismo con una J2 filtro en el archivo YAML de la obra? Parece http://docs.ansible.com/ansible/playbooks_filters.html#extracting-values-from-containers podría ser útil, pero creo que se supone que tengo una matriz de teclas/índices/lo que sea.

InformationsquelleAutor amacleod | 2016-12-22

2 Kommentare

  1. 12

    mapa filtro de su amigo aquí.

    Algo como esto:

    with_items: "{{ ec2.results | map(attribute='instances') | map('first') | map(attribute='private_ip') | list }}"
    

    El código anterior no está probado.

    Puede que desee probar con debug primera y añadir poco a poco maps para obtener resultado requerido.

    No te olvides de poner | list al final para hacer que su mapa legible.

    • Funciona como un encanto! Yo no entiendo muy bien cómo map se supone que funciona hasta que he leído tu ejemplo y el de google docs en jinja.pocoo.org/docs/dev/templates/#builtin-filters. También +1 para el list asesoramiento.
    • Ya que estoy utilizando la matriz de IPs en varios lugares, me decidí a utilizar set_fact: ec2_ips={{ ec2.results | map(attribute="instances") | map("first") | map(attribute="private_ip") | list }}.
  2. 0

    Mi ejemplo es extraído de mi playbook extracción de una autoescala ecs clúster. He modificado la respuesta anterior, para obtener la mina a trabajar.

    - name: get list of instances in ASG
      ec2_instance_facts:
        filters:
          "tag:aws:autoscaling:groupName": "{{item.name}}-{{stack}}-scalinggroup"
      register: asg_host_list
    
    - name: list ecs info
      debug:
        msg: "{{asg_host_list}}"
    
    - name: get just hosts id's
      set_fact:
        hostlist: "{{ asg_host_list.instances | map(attribute='instance_id') | list }}"
    

    Para mi uso hostlist pueden ser alimentados directamente en ecs_instance ya que toma una lista de id de instancia de proceso.

    Así, esto está probado y funciona.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea