{"id":879,"sha1":"ae9ada673b5d9003d4e522b480da496a3c7057e9","playbook":{"id":4,"items":{"plays":32,"tasks":1505,"results":1497,"hosts":12,"files":487,"records":0},"arguments":{"version":null,"verbosity":0,"private_key_file":null,"remote_user":null,"connection":"openstack.osa.ssh","timeout":null,"ssh_common_args":null,"sftp_extra_args":null,"scp_extra_args":null,"ssh_extra_args":null,"ask_pass":false,"connection_password_file":null,"force_handlers":true,"flush_cache":false,"become":false,"become_method":"sudo","become_user":null,"become_ask_pass":false,"become_password_file":null,"tags":["all"],"skip_tags":[],"check":false,"diff":false,"inventory":["/home/zuul/src/opendev.org/openstack/openstack-ansible/inventory/dynamic_inventory.py","/home/zuul/src/opendev.org/openstack/openstack-ansible/inventory/inventory.ini","/etc/openstack_deploy/inventory.ini"],"listhosts":false,"subset":null,"extra_vars":"Not saved by ARA as configured by 'ignored_arguments'","vault_ids":[],"ask_vault_pass":false,"vault_password_files":[],"forks":4,"module_path":null,"syntax":false,"listtasks":false,"listtags":false,"step":false,"start_at_task":null,"args":["setup-openstack.yml"]},"labels":[{"id":1,"name":"check:False"},{"id":2,"name":"tags:all"}],"started":"2025-12-08T13:57:07.871967Z","ended":"2025-12-08T14:21:54.049657Z","duration":"00:24:46.177690","name":null,"ansible_version":"2.18.6","client_version":"1.7.4","python_version":"3.12.11","server_version":"1.7.4","status":"failed","path":"/home/zuul/src/opendev.org/openstack/openstack-ansible/playbooks/setup-openstack.yml","controller":"aio1.openstack.local","user":"root"},"content":"---\n# Copyright 2021, BBC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n- name: Create certificate {{ cert.name }}\n  vars:\n    ansible_python_interpreter: \"{{ pki_setup_host_python_interpreter }}\"\n    _cert_file: \"{{ cert_dir ~ '/certs/' ~ cert.name ~ '.crt' }}\"\n    _cert_full_chain_file: \"{{ cert_dir ~ '/certs/' ~ cert.name ~ '-chain.crt' }}\"\n    _cert_ca_bundle_file: \"{{ cert_dir ~ '/certs/' ~ cert.name ~ '-ca_bundle.crt' }}\"\n    _ca_file: \"{{ pki_dir ~ '/roots/' ~ cert.signed_by ~ '/certs/' ~ cert.signed_by ~ '.crt' }}\"\n    _ca_bundle_file: \"{{ pki_dir ~ '/roots/' ~ cert.signed_by ~ '/certs/' ~ cert.signed_by ~ '-chain.crt' }}\"\n  delegate_to: \"{{ pki_setup_host }}\"\n  block:\n    - name: Generate certificate private key for {{ cert.name }}\n      community.crypto.openssl_privatekey:\n        path: \"{{ cert_dir ~ '/private/' ~ cert.name ~ '.key.pem' }}\"\n        passphrase: \"{{ cert.key_passphrase | default(omit) }}\"\n        cipher: \"{{ ('key_passphrase' in cert and cert.key_passphrase) | ternary('auto', omit) }}\"\n        force: \"{{ pki_regen_cert == cert.name or ((pki_regen_cert | lower) == 'true') }}\"\n        format: \"{{ cert.key_format | default(omit) }}\"\n      register: cert_privkey\n\n    - name: Create the CSR for {{ cert.name }}\n      vars:\n        generated_san: >-\n          {{\n            ['DNS:' + (cert.san.dns | unique | join(',DNS:')) if cert.san.dns | default([]) else '',\n             'IP:' + (cert.san.ip | unique | join(',IP:')) if cert.san.ip | default([]) else '']\n            | select() | join(',')\n          }}\n      community.crypto.openssl_csr:\n        path: \"{{ cert_dir ~ '/csr/' ~ cert.name ~ '.csr' }}\"\n        privatekey_path: \"{{ cert_privkey.filename }}\"\n        privatekey_passphrase: \"{{ cert.key_passphrase | default(omit) }}\"\n        common_name: \"{{ cert.cn | default(omit) }}\"\n        basic_constraints_critical: true\n        basic_constraints: \"{{ cert.basic_constraints | default(omit) }}\"\n        key_usage: \"{{ cert.key_usage | default(omit) }}\"\n        extended_key_usage: \"{{ cert.extended_key_usage | default(omit) }}\"\n        # NOTE(damiandabrowski) After 2026.1 switch to just:\n        #                       subject_alt_name: \"{{ generated_san | default(omit) }}\"\n        subject_alt_name: \"{{ (cert.san is defined and cert.san is not string) | ternary(generated_san, cert.san | default(omit)) }}\"\n        country_name: \"{{ cert.country_name | default(omit) }}\"\n        state_or_province_name: \"{{ cert.state_or_province_name | default(omit) }}\"\n        locality_name: \"{{ cert.locality_name | default(omit) }}\"\n        organization_name: \"{{ cert.organization_name | default(omit) }}\"\n        organizational_unit_name: \"{{ cert.organization_unit_name | default(omit) }}\"\n        subject: \"{{ cert.subject | default(omit) }}\"\n        force: \"{{ pki_regen_cert == cert.name or ((pki_regen_cert | lower) == 'true') }}\"\n      register: cert_csr\n\n    - name: Sign the certificate CSR for {{ cert.name }}\n      community.crypto.x509_certificate:\n        path: \"{{ _cert_file }}\"\n        csr_path: \"{{ cert_csr.filename }}\"\n        ownca_path: \"{{ _ca_file }}\"\n        ownca_privatekey_path: \"{{ pki_dir ~ '/roots/' ~ cert.signed_by ~ '/private/' ~ cert.signed_by ~ '.key.pem' }}\"\n        ownca_privatekey_passphrase: \"{{ cert.ownca_key_passphrase | default(omit) }}\"\n        ownca_not_after: \"{{ ('ttl' in cert) | ternary('+' ~ cert.get('ttl'), omit) }}\"\n        provider: ownca\n        force: \"{{ pki_regen_cert == cert.name or ((pki_regen_cert | lower) == 'true') }}\"\n      register: cert_crt\n      when:\n        - cert.provider == 'ownca'\n        - cert_csr is changed\n      notify:\n        - \"{{ pki_handler_cert_changed }}\"\n      ignore_errors: \"{{ ansible_check_mode }}\"\n\n    - name: Get certificate info for {{ cert.name }}\n      community.crypto.x509_certificate_info:\n        path: \"{{ cert_crt.filename }}\"\n      register: cert_info\n      when: cert_crt is changed\n\n    - name: Save certificate info for {{ cert.name }}\n      ansible.builtin.copy:\n        content: \"{{ cert_info | to_nice_yaml }}\"\n        dest: \"{{ cert_dir ~ '/certs/' ~ cert.name ~ '.info' }}\"\n      when: cert_crt is changed\n\n    - name: Create certificate ca bundle for {{ cert.name }}\n      ansible.builtin.copy:\n        src: \"{{ _ca_bundle_file }}\"\n        remote_src: true\n        dest: \"{{ _cert_ca_bundle_file }}\"\n\n    - name: Create certificate full chain for {{ cert.name }}\n      shell:\n        cmd: \"cat {{ _cert_file }} {{ _ca_file }} > {{ _cert_full_chain_file }}\"\n        creates: \"{{ (cert_crt is not changed) | ternary(_cert_full_chain_file, omit) }}\"\n","created":"2025-12-08T14:14:20.007391Z","updated":"2025-12-08T14:14:20.007412Z","path":"/home/zuul/src/opendev.org/openstack/ansible-role-pki/tasks/standalone/sign_cert.yml"}