From a8bf6c2c57635cf414dfad9baddc4259b5b5805c Mon Sep 17 00:00:00 2001 From: Sam Crauwels Date: Thu, 23 Apr 2026 15:03:15 +0200 Subject: [PATCH 1/2] fix(kibana): use HTTPS for readiness check when kibana_tls is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Kibana role's readiness probes hardcoded a plain `http://` curl against localhost:5601. With `kibana_tls: true` Kibana refuses HTTP, so the readiness check never satisfies `HTTP_CODE == 200|401` and the role times out. Switch the curl URL — and the task name — to `https` when `kibana_tls` is truthy, falling back to `http` otherwise. `-k` is already passed so self-signed or FreeIPA-issued certs work without extra CA wiring. Closes #141 --- roles/kibana/tasks/main.yml | 4 ++-- roles/kibana/tasks/restart_and_verify_kibana.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/kibana/tasks/main.yml b/roles/kibana/tasks/main.yml index d5ad60d..ed56b57 100644 --- a/roles/kibana/tasks/main.yml +++ b/roles/kibana/tasks/main.yml @@ -143,13 +143,13 @@ - name: Wait for Kibana to be ready when: not ansible_check_mode block: - - name: Wait for Kibana HTTP with service health check + - name: Wait for Kibana readiness ({{ 'HTTPS' if kibana_tls | default(false) | bool else 'HTTP' }}) ansible.builtin.shell: cmd: | if ! systemctl is-active --quiet kibana; then exit 2 fi - HTTP_CODE=$(curl -sk -o /dev/null -w '%{http_code}' http://localhost:5601/api/status 2>/dev/null) || true + HTTP_CODE=$(curl -sk -o /dev/null -w '%{http_code}' {{ 'https' if kibana_tls | default(false) | bool else 'http' }}://localhost:5601/api/status 2>/dev/null) || true if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "401" ]; then exit 0 fi diff --git a/roles/kibana/tasks/restart_and_verify_kibana.yml b/roles/kibana/tasks/restart_and_verify_kibana.yml index 4210e0c..1bffc50 100644 --- a/roles/kibana/tasks/restart_and_verify_kibana.yml +++ b/roles/kibana/tasks/restart_and_verify_kibana.yml @@ -21,10 +21,10 @@ retries: 5 delay: 3 - - name: restart_and_verify_kibana | Wait for Kibana HTTP readiness + - name: restart_and_verify_kibana | Wait for Kibana readiness ({{ 'HTTPS' if kibana_tls | default(false) | bool else 'HTTP' }}) ansible.builtin.shell: cmd: | - HTTP_CODE=$(curl -sk -o /dev/null -w '%{http_code}' http://localhost:5601/api/status 2>/dev/null) || true + HTTP_CODE=$(curl -sk -o /dev/null -w '%{http_code}' {{ 'https' if kibana_tls | default(false) | bool else 'http' }}://localhost:5601/api/status 2>/dev/null) || true if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "401" ]; then exit 0 fi From e04d1553b2a4b5f570c8ae45a68a6b2d7f9e2a60 Mon Sep 17 00:00:00 2001 From: Sam Crauwels Date: Thu, 23 Apr 2026 15:10:27 +0200 Subject: [PATCH 2/2] test(kibana): exercise kibana_tls: true in cert_renewal and kibana_custom_certs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit None of the existing molecule scenarios ran Kibana with web TLS turned on, so the HTTPS readiness regression in #141 would have slipped through CI. Flip kibana_tls: true in the two scenarios where it costs nothing extra: - kibana_custom_certs: reuse the test HTTP cert the scenario already generates as Kibana's server cert. Covers main.yml readiness on a fresh deploy and updates the verify to match (server.ssl.enabled is now expected; certificateAuthorities omission still holds since CA stays in the system trust store). - cert_renewal: turn TLS on in both the initial deploy and the renewal re-run. The renewal path notifies Restart Kibana, which covers restart_and_verify_kibana.yml — the only existing scenario that exercises that handler's readiness wait. Both verify steps flip to https:// with validate_certs: false (the CA is self-signed; the role's curl already uses -k for the same reason). --- molecule/cert_renewal/converge.yml | 5 +++++ molecule/cert_renewal/verify.yml | 5 +++-- molecule/kibana_custom_certs/converge.yml | 15 ++++++++++----- molecule/kibana_custom_certs/verify.yml | 13 +++++++------ 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/molecule/cert_renewal/converge.yml b/molecule/cert_renewal/converge.yml index 6f675a5..f094c14 100644 --- a/molecule/cert_renewal/converge.yml +++ b/molecule/cert_renewal/converge.yml @@ -16,6 +16,10 @@ elasticsearch_heap: "1" logstash_heap: "512m" logstash_pipeline_unsafe_shutdown: true + # Enable Kibana web TLS so the role's readiness check exercises the + # HTTPS code path (regression guard for #141). The role's curl uses -k, + # so the self-signed cert chain is fine. + kibana_tls: true tasks: - name: Include Elastic repos ansible.builtin.include_role: @@ -109,6 +113,7 @@ elasticsearch_heap: "1" logstash_heap: "512m" logstash_pipeline_unsafe_shutdown: true + kibana_tls: true # Force certificate renewal elasticstack_ca_will_expire_soon: true elasticsearch_cert_will_expire_soon: true diff --git a/molecule/cert_renewal/verify.yml b/molecule/cert_renewal/verify.yml index 6079ddd..22b7abb 100644 --- a/molecule/cert_renewal/verify.yml +++ b/molecule/cert_renewal/verify.yml @@ -87,15 +87,16 @@ - name: Run Kibana checks when: "'kibana' in group_names" block: - - name: Connect to Kibana + - name: Connect to Kibana (HTTPS — kibana_tls enabled) ansible.builtin.uri: - url: "http://localhost:5601/api/status" + url: "https://localhost:5601/api/status" method: GET force_basic_auth: true user: elastic password: "{{ elastic_pass.stdout }}" return_content: true status_code: [200, 503] + validate_certs: false register: kibana_status retries: 30 delay: 10 diff --git a/molecule/kibana_custom_certs/converge.yml b/molecule/kibana_custom_certs/converge.yml index 1f4ea4f..95dc5dc 100644 --- a/molecule/kibana_custom_certs/converge.yml +++ b/molecule/kibana_custom_certs/converge.yml @@ -165,12 +165,17 @@ elasticsearch_http_tls_key: /tmp/test-certs/http.key elasticsearch_tls_remote_src: true elasticsearch_ssl_verification_mode: certificate - # Kibana: external cert source, no web TLS, no CA provided. - # Skip cert verification since update-ca-certificates doesn't reliably - # update the CA bundle in containers (test is about config generation, - # not TLS verification). + # Kibana: external cert source with web TLS enabled, reusing the HTTP + # cert material generated above. Exercises the HTTPS readiness path + # (#141) and confirms certificateAuthorities is still omitted from + # kibana.yml when no CA is passed (the scenario's original intent). + # Skip ES-side cert verification: update-ca-certificates doesn't + # reliably update the CA bundle in containers. kibana_cert_source: external - kibana_tls: false + kibana_tls: true + kibana_tls_certificate_file: /tmp/test-certs/http.crt + kibana_tls_key_file: /tmp/test-certs/http.key + kibana_tls_remote_src: true kibana_extra_config: "elasticsearch.ssl.verificationMode: none" tasks: - name: Include Elastic repos diff --git a/molecule/kibana_custom_certs/verify.yml b/molecule/kibana_custom_certs/verify.yml index 10e40e5..45c639f 100644 --- a/molecule/kibana_custom_certs/verify.yml +++ b/molecule/kibana_custom_certs/verify.yml @@ -1,5 +1,5 @@ --- -- name: Verify Kibana with external cert source, no TLS, system trust store CA +- name: Verify Kibana with external cert source, web TLS on, system trust store CA hosts: all vars: elasticstack_elasticsearch_http_port: 9200 @@ -40,15 +40,16 @@ - name: Run Kibana checks when: "'kibana' in group_names" block: - - name: Connect to Kibana (HTTP — TLS is disabled) + - name: Connect to Kibana (HTTPS — kibana_tls enabled) ansible.builtin.uri: - url: "http://localhost:5601/api/status" + url: "https://localhost:5601/api/status" method: GET force_basic_auth: true user: elastic password: "{{ elastic_pass.stdout }}" return_content: true status_code: [200, 503] + validate_certs: false register: kibana_status retries: 18 delay: 10 @@ -71,8 +72,8 @@ - "'certificateAuthorities' not in (kibana_yml.content | b64decode)" fail_msg: "certificateAuthorities should not be present — CA is in system trust store" - - name: Verify server.ssl.enabled is NOT present (TLS disabled) + - name: Verify server.ssl.enabled IS present (TLS enabled) ansible.builtin.assert: that: - - "'server.ssl.enabled' not in (kibana_yml.content | b64decode)" - fail_msg: "server.ssl.enabled should not be present when kibana_tls is false" + - "'server.ssl.enabled: true' in (kibana_yml.content | b64decode)" + fail_msg: "server.ssl.enabled: true should be present when kibana_tls is true"