Daniel
Daniel

Reputation: 1575

Ansible with_subelements (Lists)

I'm trying to use Ansible to set up Apache virtual hosts along with databases, but not all Vhosts will have databases (1 or more).

I've tried quite a lot and also tried to adapt from here, but nothing really worked. I did a lot of try&error for quite some hours and came up with this:

My host_vars (excerpt):

web_vhosts:
  - vhost:
      name: domain1.tld
      enabled: true
      serveradmin_email: [email protected]
      https: true
      redirect_to_https: true
      dns_a_record: 1.2.3.4
      update_dns: false
  - vhost:
      name: domain2.tld
      enabled: true
      serveradmin_email: [email protected]
      https: true
      redirect_to_https: true
      dns_a_record: 1.2.3.4
      update_dns: false
      mysql:
        - name: wordpress1
          user: myuser
          password: secret

This is how far I am:

- name: Ensure databases
  mysql_db:
    name: "{{ item.1.name }}"
    state: present
    login_unix_socket: /var/run/mysqld/mysqld.sock
  when: item.0.mysql is defined
  with_subelements:
    - "{{ web_vhosts }}"
    - "mysql"

Which errors in:

fatal: [examplehost]: FAILED! => {"msg": "could not find 'mysql' key in iterated item '{'vhost': {'name': 'domain1.tld', 'enabled': True, 'serveradmin_email': '[email protected]', 'https': True, 'redirect_to_https': True, 'dns_a_record': '1.2.3.4', 'update_dns': False}}'"}

Can anyone help me understand what's wrong?

Upvotes: 1

Views: 712

Answers (2)

Alassane Ndiaye
Alassane Ndiaye

Reputation: 4777

Your variable web_vhosts is a list composed of dictionaries where the first element is vhost. You need to find the subelement vhost.mysql instead of mysql. This should fix your issue:

- name: Ensure databases
  mysql_db:
    name: "{{ item.1.name }}"
    state: present
    login_unix_socket: /var/run/mysqld/mysqld.sock
  loop: "{{ web_vhosts | subelements('vhost.mysql', skip_missing=True) }}"

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68179

There is no mysql key in the first item of the list web_vhosts

{"msg": "could not find 'mysql' key in iterated item '{'vhost': {'name': domain1.tld' ...

Set {'skip_missing': True}. For example

- name: Ensure databases
  mysql_db:
    name: "{{ item.1.name }}"
    state: present
    login_unix_socket: /var/run/mysqld/mysqld.sock
  loop: "{{ lookup('subelements', web_vhosts, 'mysql', {'skip_missing': True}) }}"

It might be a good idea to test the loop first

- name: Debug
  debug:
    var: item
  loop: "{{ lookup('subelements', web_vhosts, 'mysql', {'skip_missing': True}) }}"

Alternatively, it's possible to use subelements as a filter

  loop: "{{ web_vhosts | subelements('mysql', skip_missing=True) }}"

Upvotes: 0

Related Questions