debops / ansible-pki

Bootstrap and manage internal PKI, Certificate Authorities and OpenSSL/GnuTLS certificates
GNU General Public License v3.0
65 stars 29 forks source link

Unexpected templating type error, coercing to Unicode: need string or buffer #80

Open antoineco opened 8 years ago

antoineco commented 8 years ago

The execution of the following playbook...


---

- name: PKI realms
  hosts: all
  become: True

  vars:

    custom_pki_realms:

      - name: 'k8s'
        subject_alt_names:
          - 'ip:{{ ansible_default_ipv4.address }}'
          - 'ip:{{ kubernetes_services_net | ipaddr("1") | ipaddr("host") | ipaddr("address") }}'
          - 'dns:kubernetes.default.svc.{{ kubernetes_cluster_domain }}'
          - 'dns:kubernetes.default.svc'
          - 'dns:kubernetes.default'
          - 'dns:kubernetes'

      - name: 'etcd'
        subject_alt_names:
          - 'ip:{{ ansible_default_ipv4.address }}'
          - 'ip:{{ kubernetes_services_net | ipaddr("3") | ipaddr("host") | ipaddr("address") }}'
          - 'dns:etcd.kube-system.svc.{{ kubernetes_cluster_domain }}'
          - 'dns:etcd.kube-system.svc'
          - 'dns:etcd.kube-system'
          - 'dns:etcd'

  roles:

    - role: debops.pki/env
      tags: [ 'role::pki' ]
      pki_dependent_realms: '{{ custom_pki_realms }}'  # see issue #78

    - role: debops.secret
      tags: [ 'role::pki' ]
      secret_directories:
        - '{{ pki_env_secret_directories }}'

    - role: debops.pki
      tags: [ 'role::pki' ]
      pki_dependent_realms:
        - '{{ custom_pki_realms }}'

..throws the following error:

TASK [debops.pki : Download public realm contents by host] *********************
ok: [noah] => (item=[{u'name': u'domain', u'acme': False}, u'external'])
ok: [noah] => (item=[{u'name': u'domain', u'acme': False}, u'internal'])
fatal: [noah]: FAILED! => {"failed": true, "msg": "Unexpected templating type error occurred on ({{ secret + \"/pki/realms/by-host/\" + pki_fqdn + \"/\" + item.0.name + \"/\" + item.1 + \"/\" }}): coercing to Unicode: need string or buffer, dict found"}
drybjed commented 8 years ago

Sounds like one of the kubernetes_* variables is a dictionary instead of a string. Check all of them to see their value during the role execution by setting some debug tasks in the debops.pki role.

antoineco commented 8 years ago

@drybjed I don't think the issue is related to these variables, they are both explicitly set to a string value:

TASK [DEBUG kubernetes_services_net] *******************************************
ok: [nemo] => {
    "kubernetes_services_net": "10.0.0.0/16"
}

TASK [DEBUG kubernetes_cluster_domain] *******************************************************************
ok: [nemo] => {
    "kubernetes_cluster_domain": "my.cluster"
}
drybjed commented 8 years ago

Can you show the debug value of custom_pki_realms variable?

antoineco commented 8 years ago

Sure thing:

TASK [Print 'custom_pki_realms' on each node] **********************************
ok: [nemo] => {
    "custom_pki_realms": [
        {
            "name": "k8s", 
            "subject_alt_names": [
                "ip:192.168.3.1", 
                "ip:10.0.0.1", 
                "dns:kubernetes.default.svc.my.cluster", 
                "dns:kubernetes.default.svc", 
                "dns:kubernetes.default", 
                "dns:kubernetes"
            ]
        }, 
        {
            "name": "etcd", 
            "subject_alt_names": [
                "ip:192.168.3.1", 
                "ip:10.0.0.3", 
                "dns:etcd.kube-system.svc.my.cluster", 
                "dns:etcd.kube-system.svc", 
                "dns:etcd.kube-system", 
                "dns:etcd"
            ]
        }
    ]
}
drybjed commented 8 years ago

Well, hmm, they look ok... How about this - can you remove all subject_alt_names that contain any variables and see if the result works? Just to eliminate any other issues elsewhere.

antoineco commented 8 years ago

Done, I left only the 3 last dns: entries, without success.

antoineco commented 8 years ago

It works when custom_pki_realms contains a single entry (single dictionary).

drybjed commented 8 years ago

And the normal debops.pki role runs fine?

If yes then I'm out of ideas... How about this, before that problematic task, add:

- name: Show all the things
  debug:
    msg: '{{ pki_realms + pki_group_realms + pki_host_realms + pki_default_realms + pki_dependent_realms }}'

Let's see whats templated just before it.

drybjed commented 8 years ago

Hmm, OK - it might be the same problem that with debops.pki/env because this specific task is nested, and not flattened. Try moving the variable the same way as with debops.pki/env.

I guess it's time for a custom lookup for these tasks.

antoineco commented 8 years ago

It also works with multiple entries (see first post) if I call the role as follows:

    - role: debops.pki
      tags: [ 'role::pki' ]
      pki_dependent_realms: '{{ custom_pki_realms }}'

This definitely reminds me of #78, as you mentioned.

The normal debops.pki role runs fine.

The debug you asked me to post, just in case it helps:

TASK [Show all the things] *****************************************************
ok: [noah] => {
    "msg": [
        {
            "acme": false, 
            "name": "domain"
        }
    ]
}
drybjed commented 8 years ago

@antoineco So when you move the custom_pki_realms variable in the playbook it works? I guess that confirms the issue, these lists need to be flattened by templates in specific places.