Skip to content

Commit 283a92e

Browse files
PMM-14242: Implement automatic SSL certificate configuration for OpenShift clusters (#3504)
* Implement automatic SSL certificate configuration for OpenShift clusters - Add Let's Encrypt support via cert-manager for OpenShift routes - Add AWS ACM certificate management for LoadBalancer services - Implement DNS automation with Route53 - Auto-switch PMM to LoadBalancer when SSL is enabled - Add ACM certificate creation with DNS validation Changes: - New vars/openshiftSSL.groovy library for Let's Encrypt management - New vars/awsCertificates.groovy library for ACM and Route53 - Enhanced openshift_cluster_create pipeline with SSL parameters - Modified deployPMM() to support ACM certificates automatically Related to: PMM-14242 * Add missing newlines at end of files - Add newline to vars/openshiftSSL.groovy - Add newline to vars/awsCertificates.groovy Per code style guidelines, all files should end with a newline character.
1 parent 98fd149 commit 283a92e

File tree

5 files changed

+1527
-4
lines changed

5 files changed

+1527
-4
lines changed

pmm/openshift/openshift-cluster-create.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,37 @@
145145
description: "Product/project tag for billing allocation"
146146
trim: true
147147

148+
# === SSL Certificate Configuration ===
149+
- bool:
150+
name: ENABLE_SSL
151+
default: false
152+
description: "Enable automatic SSL certificate configuration for cluster services"
153+
- choice:
154+
name: SSL_METHOD
155+
choices:
156+
- "acm"
157+
- "letsencrypt"
158+
description: "SSL certificate provider (AWS ACM or Let's Encrypt via cert-manager)"
159+
- string:
160+
name: SSL_EMAIL
161+
default: "[email protected]"
162+
description: "Email address for Let's Encrypt registration (required for letsencrypt method)"
163+
trim: true
164+
- bool:
165+
name: USE_STAGING_CERT
166+
default: false
167+
description: "Use Let's Encrypt staging certificates for testing (avoids rate limits)"
168+
- string:
169+
name: CONSOLE_CUSTOM_DOMAIN
170+
default: ""
171+
description: "Custom domain for OpenShift console (optional, auto-generates if empty)"
172+
trim: true
173+
- string:
174+
name: PMM_CUSTOM_DOMAIN
175+
default: ""
176+
description: "Custom domain for PMM interface (optional, auto-generates if empty)"
177+
trim: true
178+
148179
# === Advanced Options ===
149180
- string:
150181
name: BASE_DOMAIN

pmm/openshift/openshift_cluster_create.groovy

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,13 @@ Starting cluster creation process...
372372
pmmHelmChartVersion: params.PMM_HELM_CHART_VERSION,
373373
pmmImageRepository: params.PMM_IMAGE_REPOSITORY,
374374
pmmAdminPassword: params.PMM_ADMIN_PASSWORD ?: '<GENERATED>', // Default to auto-generation
375+
// SSL Configuration
376+
enableSSL: params.ENABLE_SSL,
377+
sslMethod: params.SSL_METHOD,
378+
sslEmail: params.SSL_EMAIL,
379+
useStaging: params.USE_STAGING_CERT,
380+
consoleCustomDomain: params.CONSOLE_CUSTOM_DOMAIN,
381+
pmmCustomDomain: params.PMM_CUSTOM_DOMAIN,
375382
buildUser: env.BUILD_USER_ID ?: 'jenkins',
376383
accessKey: AWS_ACCESS_KEY_ID,
377384
secretKey: AWS_SECRET_ACCESS_KEY
@@ -411,6 +418,103 @@ Starting cluster creation process...
411418
}
412419
}
413420

421+
stage('Configure SSL Certificates') {
422+
when {
423+
expression { params.ENABLE_SSL && env.CLUSTER_DIR }
424+
}
425+
steps {
426+
script {
427+
echo ""
428+
echo "====================================================================="
429+
echo "Configuring SSL Certificates"
430+
echo "====================================================================="
431+
echo ""
432+
echo "SSL Method: ${params.SSL_METHOD}"
433+
echo "Base Domain: ${params.BASE_DOMAIN}"
434+
435+
def sslConfig = [
436+
clusterName: env.FINAL_CLUSTER_NAME,
437+
baseDomain: params.BASE_DOMAIN,
438+
kubeconfig: env.KUBECONFIG,
439+
method: params.SSL_METHOD,
440+
email: params.SSL_EMAIL,
441+
useStaging: params.USE_STAGING_CERT
442+
]
443+
444+
def sslResults = [:]
445+
446+
if (params.SSL_METHOD == 'letsencrypt') {
447+
echo "Setting up Let's Encrypt certificates..."
448+
449+
// Configure console domain
450+
def consoleDomain = params.CONSOLE_CUSTOM_DOMAIN ?:
451+
"console-${env.FINAL_CLUSTER_NAME}.${params.BASE_DOMAIN}"
452+
453+
sslConfig.consoleDomain = consoleDomain
454+
455+
// Setup Let's Encrypt
456+
sslResults = openshiftSSL.setupLetsEncrypt(sslConfig)
457+
458+
if (sslResults.consoleCert) {
459+
echo "✓ Console certificate configured for: ${consoleDomain}"
460+
env.CONSOLE_SSL_DOMAIN = consoleDomain
461+
}
462+
} else if (params.SSL_METHOD == 'acm') {
463+
echo "Setting up AWS ACM certificates..."
464+
465+
withCredentials([
466+
aws(
467+
credentialsId: 'jenkins-openshift-aws',
468+
accessKeyVariable: 'AWS_ACCESS_KEY_ID',
469+
secretKeyVariable: 'AWS_SECRET_ACCESS_KEY'
470+
)
471+
]) {
472+
def services = []
473+
474+
// Add PMM service if deployed
475+
if (params.DEPLOY_PMM && env.PMM_URL) {
476+
def pmmDomain = params.PMM_CUSTOM_DOMAIN ?:
477+
"pmm-${env.FINAL_CLUSTER_NAME}.${params.BASE_DOMAIN}"
478+
479+
services.add([
480+
name: 'monitoring-service',
481+
namespace: 'pmm-monitoring',
482+
domain: pmmDomain
483+
])
484+
}
485+
486+
sslConfig.services = services
487+
sslConfig.accessKey = AWS_ACCESS_KEY_ID
488+
sslConfig.secretKey = AWS_SECRET_ACCESS_KEY
489+
490+
sslResults = awsCertificates.setupACM(sslConfig)
491+
492+
if (sslResults.services) {
493+
sslResults.services.each { name, config ->
494+
if (config.configured) {
495+
echo "✓ Service ${name} configured with ACM certificate"
496+
if (config.domain) {
497+
echo " Domain: https://${config.domain}"
498+
}
499+
}
500+
}
501+
}
502+
}
503+
}
504+
505+
// Store SSL results for post-creation display
506+
env.SSL_CONFIGURED = sslResults ? 'true' : 'false'
507+
508+
if (sslResults.errors && !sslResults.errors.isEmpty()) {
509+
echo "SSL configuration completed with warnings:"
510+
sslResults.errors.each { error ->
511+
echo "${error}"
512+
}
513+
}
514+
}
515+
}
516+
}
517+
414518
stage('Post-Creation Tasks') {
415519
steps {
416520
script {
@@ -436,6 +540,12 @@ Starting cluster creation process...
436540
echo "------------------"
437541
echo "API URL: ${env.CLUSTER_API_URL}"
438542
echo "Console URL: ${env.CLUSTER_CONSOLE_URL ?: 'Pending...'}"
543+
544+
// Display SSL console URL if configured
545+
if (params.ENABLE_SSL && params.SSL_METHOD == 'letsencrypt' && env.CONSOLE_SSL_DOMAIN) {
546+
echo "Console SSL URL: https://${env.CONSOLE_SSL_DOMAIN}"
547+
}
548+
439549
echo "Kubeconfig: Available in Jenkins artifacts"
440550
echo ""
441551

@@ -462,6 +572,13 @@ Starting cluster creation process...
462572
echo "IP Address: ${env.PMM_IP}"
463573
echo "Username: admin"
464574
echo "Password: ${passwordInfo}"
575+
576+
// Display SSL info if configured
577+
if (params.ENABLE_SSL && params.SSL_METHOD == 'acm' && env.SSL_CONFIGURED == 'true') {
578+
def pmmDomain = params.PMM_CUSTOM_DOMAIN ?:
579+
"pmm-${env.FINAL_CLUSTER_NAME}.${params.BASE_DOMAIN}"
580+
echo "SSL Access: https://${pmmDomain}"
581+
}
465582
echo ""
466583
} else if (params.DEPLOY_PMM) {
467584
echo "PMM DEPLOYMENT STATUS: NOT DEPLOYED"

0 commit comments

Comments
 (0)