diff --git a/.secrets.baseline b/.secrets.baseline index 8085ebd9..53021726 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-10-11T11:57:05Z", + "generated_at": "2025-10-15T14:30:02Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -110,7 +110,7 @@ "hashed_secret": "8c7c51db5075ebd0369c51e9f14737d9b4c1c21d", "is_secret": false, "is_verified": false, - "line_number": 413, + "line_number": 415, "type": "Base64 High Entropy String", "verified_result": null } diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 0a63f7e8..c51c694a 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -464,15 +464,20 @@ locals { code_engine_project_id = var.existing_code_engine_project_id != null ? var.existing_code_engine_project_id : null code_engine_project_name = local.code_engine_project_id != null ? null : (var.prefix != null && var.prefix != "") ? "${var.prefix}-${var.kibana_code_engine_new_project_name}" : var.kibana_code_engine_new_project_name code_engine_app_name = (var.prefix != null && var.prefix != "") ? "${var.prefix}-${var.kibana_code_engine_new_app_name}" : var.kibana_code_engine_new_app_name - kibana_version = var.enable_kibana_dashboard ? jsondecode(data.http.es_metadata[0].response_body).version.number : null + kibana_version = var.enable_kibana_dashboard ? try(data.external.es_metadata[0].result.version_number, null) : null kibana_system_password = var.enable_kibana_dashboard ? startswith(random_password.kibana_system_password[0].result, "-") ? "J${substr(random_password.kibana_system_password[0].result, 1, -1)}" : startswith(random_password.kibana_system_password[0].result, "_") ? "K${substr(random_password.kibana_system_password[0].result, 1, -1)}" : random_password.kibana_system_password[0].result : null kibana_app_login_password = var.enable_kibana_dashboard ? startswith(random_password.kibana_app_login_password[0].result, "-") ? "J${substr(random_password.kibana_app_login_password[0].result, 1, -1)}" : startswith(random_password.kibana_app_login_password[0].result, "_") ? "K${substr(random_password.kibana_app_login_password[0].result, 1, -1)}" : random_password.kibana_app_login_password[0].result : null } -data "http" "es_metadata" { - count = var.enable_kibana_dashboard ? 1 : 0 - url = "https://${local.elasticsearch_username}:${local.admin_pass}@${local.elasticsearch_hostname}:${local.elasticsearch_port}" - ca_cert_pem = base64decode(local.elasticsearch_cert) +data "external" "es_metadata" { + count = var.enable_kibana_dashboard ? 1 : 0 + program = ["bash", "${path.module}/scripts/es_metadata.sh"] + query = { + url = "https://${local.elasticsearch_hostname}:${local.elasticsearch_port}" + username = local.elasticsearch_username + password = local.admin_pass + ca_cert_b64 = local.elasticsearch_cert + } } module "code_engine_kibana" { diff --git a/solutions/fully-configurable/scripts/es_metadata.sh b/solutions/fully-configurable/scripts/es_metadata.sh new file mode 100755 index 00000000..1f9bac6e --- /dev/null +++ b/solutions/fully-configurable/scripts/es_metadata.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Read JSON from stdin +INPUT_JSON="$(cat)" + +# Extract fields using jq +URL="$(echo "$INPUT_JSON" | jq -r '.url')" +USERNAME="$(echo "$INPUT_JSON" | jq -r '.username')" +PASSWORD="$(echo "$INPUT_JSON" | jq -r '.password')" # pragma: allowlist secret +CA_CERT_B64="$(echo "$INPUT_JSON" | jq -r '.ca_cert_b64')" + +# Create a temporary directory for the CA cert +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +CA_PEM="$TMPDIR/ca.pem" +# Decode the base64 CA cert to a PEM file +echo "$CA_CERT_B64" | base64 -d > "$CA_PEM" + +# Build Basic Auth header value +BASIC_AUTH="$(printf '%s:%s' "$USERNAME" "$PASSWORD" | base64)" # pragma: allowlist secret + +# Fetch ES root endpoint, which returns cluster metadata including version +# -s silent, -S show errors, --fail for HTTP errors +# --cacert to trust the provided CA +RESP="$(curl -sS --fail \ + -H "Authorization: Basic $BASIC_AUTH" \ + --cacert "$CA_PEM" \ + "$URL")" + +# Parse version.number using jq +VERSION_NUMBER="$(echo "$RESP" | jq -r '.version.number // empty')" + +# The external data source expects a flat JSON object on stdout. +# If version_number is empty, still return valid JSON but with null. +if [[ -z "$VERSION_NUMBER" ]]; then + echo '{"version_number":null}' +else + echo "{\"version_number\":\"$VERSION_NUMBER\"}" +fi diff --git a/solutions/fully-configurable/version.tf b/solutions/fully-configurable/version.tf index 5ceb6484..26b92023 100644 --- a/solutions/fully-configurable/version.tf +++ b/solutions/fully-configurable/version.tf @@ -14,9 +14,9 @@ terraform { source = "hashicorp/random" version = "3.7.2" } - http = { - source = "hashicorp/http" - version = "3.5.0" + external = { + source = "hashicorp/external" + version = "~> 2.3" } } } diff --git a/tests/pr_test.go b/tests/pr_test.go index 474972b7..a0bafe32 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -69,6 +69,7 @@ func TestRunFullyConfigurableSolutionSchematics(t *testing.T) { TarIncludePatterns: []string{ "*.tf", fmt.Sprintf("%s/*.tf", fullyConfigurableSolutionTerraformDir), + fmt.Sprintf("%s/scripts/*.sh", fullyConfigurableSolutionTerraformDir), fmt.Sprintf("%s/*.sh", "scripts"), }, TemplateFolder: fullyConfigurableSolutionTerraformDir, @@ -201,6 +202,7 @@ func TestRunSecurityEnforcedSolutionSchematics(t *testing.T) { "*.tf", fmt.Sprintf("%s/*.tf", fullyConfigurableSolutionTerraformDir), fmt.Sprintf("%s/*.tf", securityEnforcedSolutionTerraformDir), + fmt.Sprintf("%s/scripts/*.sh", fullyConfigurableSolutionTerraformDir), fmt.Sprintf("%s/*.sh", "scripts"), }, TemplateFolder: securityEnforcedSolutionTerraformDir,