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

Local task fails on realm creation due to missing dirs #78

Open antoineco opened 8 years ago

antoineco commented 8 years ago

When I declare a new realm in a playbook, the task Sign certificate requests for current hosts fails with the following error:

fatal: [noah.host -> localhost]: FAILED! =>
{
  "changed": false,
  "cmd": [
    "./lib/pki-authority",
    "sign-by-host",
    "noah.host"
  ],
  "delta": "0:00:00.760960",
  "end": "2016-08-09 12:58:03.344391",
  "failed": true,
  "rc": 1,
  "start": "2016-08-09 12:58:02.583431",
  "stderr": "pki-authority: Error: failed to run ca -batch -notext -in /ansible/ansible/secret/pki/requests/domain/noah.host/k8s/request.pem -out /ansible/ansible/secret/pki/realms/by-host/noah.host/k8s/internal/cert.pem.tmp -config config/openssl-sign.conf (Exitcode: 1)\n\nDetails:\nUsing configuration from config/openssl-sign.conf\n/ansible/ansible/secret/pki/realms/by-host/noah.host/k8s/internal/cert.pem.tmp: No such file or directory\n140100935210648:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('/ansible/ansible/secret/pki/realms/by-host/noah.host/k8s/internal/cert.pem.tmp','w')\n140100935210648:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400:",
  "stdout": "",
  "stdout_lines": [],
  "warnings": []
}

It looks like some directory creations are missing, since the playbooks runs perfectly when I create the following empty directory structure locally:

ansible/secret/pki/realms/by-host/noah.host/
`-- k8s
    |-- external
    `-- internal

Extract from the playbook:

  vars:

    kubernetes_pki_dependent_realms:
      - name: 'k8s'
        subject_alt_names:
          - 'ip:{{ ansible_default_ipv4.address }}'
          - 'ip:10.200.0.1'
          - 'dns:kubernetes.default.svc.gini.cluster'
          - 'dns:kubernetes.default.svc'
          - 'dns:kubernetes.default'
          - 'dns:kubernetes'

  roles:

    - role: debops.pki
      tags: [ 'role::pki' ]
      pki_dependent_realms:
        - '{{ kubernetes_pki_dependent_realms }}'
drybjed commented 8 years ago

You need to include debops.pki/env and debops.secret roles in your playbook. Check the example debops.pki playbook to see how they are used.

antoineco commented 8 years ago

Oh, I see, thanks for the quick answer @drybjed !

antoineco commented 8 years ago

@drybjed for some reason it doesn't work with the following addition:

  roles:

    - role: debops.pki/env
      tags: [ 'role::pki' ]
      pki_dependent_realms:
        - '{{ kubernetes_pki_dependent_realms }}'

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

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

But it should according to this template: pki_env_secret_directories.j2.

I added 2 debug tasks to env/tasks/main.yml:

---

- name: DEBUG
  debug:
    var: pki_dependent_realms

- name: Prepare debops.pki environment
  set_fact:
    pki_env_secret_directories: '{{ lookup("template", "lookup/pki_env_secret_directories.j2") | from_yaml }}'

- name: DEBUG
  debug:
    var: pki_env_secret_directories

The result is surprising me:

Running Ansible playbook from:
/ansible/ansible/playbooks/kubernetes.yml ...

PLAY [Kubernetes] **************************************************************

TASK [setup] *******************************************************************
ok: [noah.host]

TASK [debops.pki/env : DEBUG] **************************************************
ok: [noah.host] => {
    "pki_dependent_realms": [
        [
            {
                "name": "k8s", 
                "subject_alt_names": [
                    "ip:192.168.3.2", 
                    "ip:10.200.0.1", 
                    "dns:kubernetes.default.svc.gini.cluster", 
                    "dns:kubernetes.default.svc", 
                    "dns:kubernetes.default", 
                    "dns:kubernetes"
                ]
            }
        ]
    ]
}

TASK [debops.pki/env : Prepare debops.pki environment] *************************
ok: [noah.host]

TASK [debops.pki/env : DEBUG] **************************************************
ok: [noah.host] => {
    "pki_env_secret_directories": [
        "pki/lib", 
        "pki/ca-certificates/by-host/noah.host", 
        "pki/ca-certificates/by-group/all", 
        "pki/ca-certificates/by-group/debops_service_pki", 
        "pki/realms/by-group/all/domain/external", 
        "pki/realms/by-group/all/domain/private", 
        "pki/realms/by-group/debops_service_pki/domain/external", 
        "pki/realms/by-group/debops_service_pki/domain/private", 
        "pki/realms/by-host/noah.host/domain/external", 
        "pki/realms/by-host/noah.host/domain/internal", 
        "pki/realms/by-host/noah.host/domain/private"
    ]
}

Am I missing something?

drybjed commented 8 years ago

@antoineco Your playbook looks correct. I'm not sure why it doesn't want to work this way. Can you try and debug the variables inside the template? Perhaps add another task that saves the result in a temporary file to see what's happening there.

antoineco commented 8 years ago

@drybjed: Got it. That's because I'm passing my variable as a list like this:

    - role: debops.pki/env
      tags: [ 'role::pki' ]
      pki_dependent_realms:
        - '{{ kubernetes_pki_dependent_realms }}'

However kubernetes_pki_dependent_realms is already a list, so printing the value of each realm in pki_dependent_realms results in:

- {u'name': u'domain', u'acme': False}
- [{u'subject_alt_names': [u'ip:192.168.3.2', u'ip:10.200.0.1', u'dns:kubernetes.default.svc.gini.cluster', u'dns:kubernetes.default.svc', u'dns:kubernetes.default', u'dns:kubernetes'], u'name': u'k8s'}]

That's why the template doesn't catch it.

A quick workaround is to pass the variable as a string to the debops.pki/env role, but in that case I can not express dependencies like I do with your other ferm role, something like:

    - role: debops.pki/env
      tags: [ 'role::pki' ]
      pki_dependent_realms:
        - '{{ kubernetes_pki_dependent_realms }}'
        - '{{ etcd_pki_dependent_realms }}'
drybjed commented 8 years ago

@antoineco Right. The template in 1debops.pki/env` would need to flatten the list to work around it. I'll get to it when I have the time, for now try something like this:

- role: debops.pki/env
  pki_dependent_realms: '{{ kubernetes_pki_dependent_realms + etcd_pki_dependent_realms }}'

That should make the role work correctly.

antoineco commented 8 years ago

@drybjed: Sure, on my side it's easy to work around that. What I was pointing out is that the behavior of the debops.pki/env role is not what the user might expect at first. At least people who have familiarity with the rest of the DebOps framework.

Thanks again for responding so quickly 👌