1

I am trying to filter a YAML config file and collapse them based on a key.

For an ansible playbook I use the following config

    virtual_hosts:

      - vname: example
        server_name: "www.example.com example.com"
        port: 443
        ssl:
          cert: "star_example"


      - name: example_star
        server_name: "*.example.com"
        port: 443
        ssl:
          cert: "star_example"


      - name: foo
        server_name: "www.foo.com foo.com"
        port: 443
        ssl:
          cert: "foo"

I have tied to use a template

    - name: Certs Template
      set_fact:
        vhost_certs: "{{ lookup('template', './cert.yml') | from_yaml }}"

With the following cert.yml

      {% if virtual_hosts is defined %}
      {% for host in virtual_hosts %}
      {% if host.ssl is defined %}

    - name: "{{host.ssl.cert}}"
      private: " ... PRIV KEY ...."
      public:  " ... PUB KEY  ...." 

      {% endif %}
      {% endfor %}
      {% endif %}

The problem is that vhost_certs will contain star_example twice. In reality cert.yml does a lookup to get the private and the public keys using an Ansible plugin, so I would want to look them up only once.

I guess a better method would be to parse the virtual_hosts create a new object where the main key would be the ssl.cert add all the server_names do an actual lookup of the private and public keys and then check that the certificate is valid for all of the items in the server_name

e.g.

  vhost_certs: 

    - name: star_example
      server_names:
        - "www.example.com"
        - "example.com"
        - "*.example.com"

    - name: foo
      server_names:
        - "www.foo.com"
        - "foo.com"

Is there a way in Ansible to do this?

Update:

I have managed to create the list:

{{ virtual_hosts | json_query('[?ssl.cert].{cert: ssl.cert, domains: server_name }') | list }}

This does provide a list

item: {
   "cert" : "star_example"
   "domains" "www.example.com example.com"  
}
item: {
   "cert" : "star_example"
   "domains" "*.example.com"    
}
item: {
   "cert" : "foo"
   "domains" "www.foo.com foo.com"  
}

I would just need somehow to collapse it to

item: {
   "cert" : "star_example"
   "domains" 
      - "*.example.com" 
      - "www.example.com example.com"   
}
DuppyWeb
  • 43
  • 1
  • 4
  • Have you already tried [`virtual_hosts | subelements("ssl.cert")`](https://docs.ansible.com/ansible/2.7/user_guide/playbooks_filters.html#subelements-filter)? (I made up that dot notation, so the fact that your grouping key isn't at the top level may cause `subelements` to be tricker) – mdaniel Feb 10 '19 at 09:29
  • I am running Ansible v2.5.1 currently, I will give it a try using 2.7 – DuppyWeb Feb 10 '19 at 09:54

0 Answers0