automated terminal push

This commit is contained in:
lenape
2025-07-15 15:23:58 +00:00
parent 59820f5ab0
commit e58315de9d

197
Jenkinsfile vendored
View File

@@ -12,6 +12,11 @@ pipeline {
defaultValue: false, defaultValue: false,
description: 'Skip SonarQube quality gates (use with caution)' description: 'Skip SonarQube quality gates (use with caution)'
) )
booleanParam(
name: 'DESTROY_INFRASTRUCTURE',
defaultValue: false,
description: 'Destroy all infrastructure (use with extreme caution)'
)
} }
environment { environment {
@@ -111,6 +116,14 @@ pipeline {
steps { steps {
checkout scm checkout scm
script { script {
// Check for infrastructure destruction first
if (params.DESTROY_INFRASTRUCTURE) {
env.DEPLOYMENT_TYPE = "DESTROY"
currentBuild.displayName = "DESTROY-${BUILD_NUMBER}"
echo "🚨 DESTROY MODE: Infrastructure destruction requested"
return
}
def infrastructureFiles = sh( def infrastructureFiles = sh(
script: ''' script: '''
if git rev-parse HEAD~1 >/dev/null 2>&1; then if git rev-parse HEAD~1 >/dev/null 2>&1; then
@@ -130,33 +143,17 @@ pipeline {
echo "✅ Deployment type set to: INFRASTRUCTURE (forced)" echo "✅ Deployment type set to: INFRASTRUCTURE (forced)"
} else if (infrastructureFiles == "initial") { } else if (infrastructureFiles == "initial") {
env.DEPLOYMENT_TYPE = "INFRASTRUCTURE" env.DEPLOYMENT_TYPE = "INFRASTRUCTURE"
currentBuild.displayName = "INFRASTRUCTURE-INITIAL-${BUILD_NUMBER}"
echo "✅ First run detected. Deploying infrastructure." echo "✅ First run detected. Deploying infrastructure."
} else if (infrastructureFiles != "none") { } else if (infrastructureFiles != "none") {
env.DEPLOYMENT_TYPE = "INFRASTRUCTURE" env.DEPLOYMENT_TYPE = "INFRASTRUCTURE"
currentBuild.displayName = "INFRASTRUCTURE-CHANGED-${BUILD_NUMBER}"
echo "🚨 SECURITY NOTICE: Infrastructure changes detected - elevated permissions required" echo "🚨 SECURITY NOTICE: Infrastructure changes detected - elevated permissions required"
echo " Changed files: ${infrastructureFiles}" echo " Changed files: ${infrastructureFiles}"
} else { } else {
// Check if infrastructure actually exists in AWS env.DEPLOYMENT_TYPE = "APPLICATION"
def clusterExists = false currentBuild.displayName = "APPLICATION-${BUILD_NUMBER}"
try { echo "✅ SECURITY: Application-only deployment - using restricted permissions"
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) {
def clusterCheck = sh(
script: "aws ecs describe-clusters --clusters ${TF_VAR_cluster_name} --region ${AWS_REGION} --query 'clusters[0].status' --output text 2>/dev/null || echo 'NOTFOUND'",
returnStdout: true
).trim()
clusterExists = (clusterCheck == "ACTIVE")
}
} catch (Exception e) {
echo "⚠️ Could not check cluster status: ${e.getMessage()}"
}
if (!clusterExists) {
env.DEPLOYMENT_TYPE = "INFRASTRUCTURE"
echo "🚨 CLEAN AWS DETECTED: No existing infrastructure found - deploying from scratch"
} else {
env.DEPLOYMENT_TYPE = "APPLICATION"
echo "✅ SECURITY: Application-only deployment - using restricted permissions"
}
} }
def gitCommit = sh(script: 'git rev-parse HEAD', returnStdout: true).trim() def gitCommit = sh(script: 'git rev-parse HEAD', returnStdout: true).trim()
@@ -239,6 +236,9 @@ pipeline {
} }
stage('Secure Container Build & Registry') { stage('Secure Container Build & Registry') {
when {
not { expression { env.DEPLOYMENT_TYPE == "DESTROY" } }
}
steps { steps {
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) {
script { script {
@@ -276,6 +276,9 @@ pipeline {
} }
stage('Infrastructure Readiness Check') { stage('Infrastructure Readiness Check') {
when {
not { expression { env.DEPLOYMENT_TYPE == "DESTROY" } }
}
steps { steps {
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) {
script { script {
@@ -301,13 +304,14 @@ pipeline {
echo "🔍 Container Instances: ${instanceCount}" echo "🔍 Container Instances: ${instanceCount}"
if (serviceExists == "false" || instanceCount == "0" || instanceCount == "null") { if (serviceExists == "false" || instanceCount == "0" || instanceCount == "null") {
echo "🚨 SECURITY NOTICE: Infrastructure not ready - forcing deployment" echo "🚨 SECURITY NOTICE: Infrastructure not ready - forcing infrastructure deployment"
env.DEPLOYMENT_TYPE = "INFRASTRUCTURE" env.DEPLOYMENT_TYPE = "INFRASTRUCTURE"
currentBuild.displayName = "INFRASTRUCTURE-AUTO-${BUILD_NUMBER}"
currentBuild.description = "INFRASTRUCTURE (auto-detected) | ${env.IMAGE_TAG}" currentBuild.description = "INFRASTRUCTURE (auto-detected) | ${env.IMAGE_TAG}"
echo "✅ Changed deployment type to: ${env.DEPLOYMENT_TYPE}" echo "✅ Changed deployment type to: INFRASTRUCTURE"
} }
} else { } else {
echo "✅ Infrastructure deployment already forced - skipping readiness check" echo "✅ Infrastructure deployment already scheduled - skipping readiness check"
} }
echo "📋 SECURITY: Infrastructure readiness assessment completed" echo "📋 SECURITY: Infrastructure readiness assessment completed"
@@ -317,6 +321,50 @@ pipeline {
} }
} }
stage('Destroy Infrastructure') {
when {
expression { env.DEPLOYMENT_TYPE == "DESTROY" }
}
steps {
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) {
dir('terraform') {
script {
echo "🚨 DESTRUCTION: Destroying infrastructure..."
sh """
echo "🔄 Initializing Terraform with remote backend..."
terraform init \\
-backend-config="bucket=${TF_BACKEND_BUCKET}" \\
-backend-config="key=${TF_BACKEND_PREFIX}" \\
-backend-config="region=${AWS_REGION}" \\
-backend-config="dynamodb_table=${TF_DDB_TABLE}"
echo "🔄 Planning infrastructure destruction..."
terraform plan -destroy \\
-var="cluster_name=${TF_VAR_cluster_name}" \\
-var="vpc_cidr=${TF_VAR_vpc_cidr}" \\
-var="public_subnets=${TF_VAR_public_subnets}" \\
-var="instance_type=${TF_VAR_instance_type}" \\
-var="key_pair_name=${TF_VAR_key_pair_name}" \\
-var="jenkins_ip_cidr=${TF_VAR_jenkins_ip_cidr}" \\
-var="aws_region=${TF_VAR_aws_region}"
echo "🔄 Destroying infrastructure..."
terraform destroy -auto-approve \\
-var="cluster_name=${TF_VAR_cluster_name}" \\
-var="vpc_cidr=${TF_VAR_vpc_cidr}" \\
-var="public_subnets=${TF_VAR_public_subnets}" \\
-var="instance_type=${TF_VAR_instance_type}" \\
-var="key_pair_name=${TF_VAR_key_pair_name}" \\
-var="jenkins_ip_cidr=${TF_VAR_jenkins_ip_cidr}" \\
-var="aws_region=${TF_VAR_aws_region}"
"""
echo "✅ Infrastructure destruction completed"
}
}
}
}
}
stage('Deploy Infrastructure') { stage('Deploy Infrastructure') {
when { when {
anyOf { anyOf {
@@ -334,35 +382,44 @@ pipeline {
echo "🏗️ ARCHITECTURE: Deploying ECS Cluster with SSM access (secure, keyless)" echo "🏗️ ARCHITECTURE: Deploying ECS Cluster with SSM access (secure, keyless)"
echo "🔐 In production: This would require infrastructure-admin role" echo "🔐 In production: This would require infrastructure-admin role"
echo "🚀 Attempting infrastructure deployment..." echo "🚀 Attempting infrastructure deployment..."
sh """
echo "🔄 Initializing Terraform with remote backend..."
terraform init \\
-backend-config="bucket=${TF_BACKEND_BUCKET}" \\
-backend-config="key=${TF_BACKEND_PREFIX}" \\
-backend-config="region=${AWS_REGION}" \\
-backend-config="dynamodb_table=${TF_DDB_TABLE}"
echo "🔄 Planning infrastructure changes..." // Add error handling for Terraform operations
terraform plan \\ try {
-var="cluster_name=${TF_VAR_cluster_name}" \\ sh """
-var="vpc_cidr=${TF_VAR_vpc_cidr}" \\ echo "🔄 Initializing Terraform with remote backend..."
-var="public_subnets=${TF_VAR_public_subnets}" \\ terraform init \\
-var="instance_type=${TF_VAR_instance_type}" \\ -backend-config="bucket=${TF_BACKEND_BUCKET}" \\
-var="key_pair_name=${TF_VAR_key_pair_name}" \\ -backend-config="key=${TF_BACKEND_PREFIX}" \\
-var="jenkins_ip_cidr=${TF_VAR_jenkins_ip_cidr}" \\ -backend-config="region=${AWS_REGION}" \\
-var="aws_region=${TF_VAR_aws_region}" -backend-config="dynamodb_table=${TF_DDB_TABLE}"
echo "🔄 Applying infrastructure changes..." echo "🔄 Planning infrastructure changes..."
terraform apply -auto-approve \\ terraform plan \\
-var="cluster_name=${TF_VAR_cluster_name}" \\ -var="cluster_name=${TF_VAR_cluster_name}" \\
-var="vpc_cidr=${TF_VAR_vpc_cidr}" \\ -var="vpc_cidr=${TF_VAR_vpc_cidr}" \\
-var="public_subnets=${TF_VAR_public_subnets}" \\ -var="public_subnets=${TF_VAR_public_subnets}" \\
-var="instance_type=${TF_VAR_instance_type}" \\ -var="instance_type=${TF_VAR_instance_type}" \\
-var="key_pair_name=${TF_VAR_key_pair_name}" \\ -var="key_pair_name=${TF_VAR_key_pair_name}" \\
-var="jenkins_ip_cidr=${TF_VAR_jenkins_ip_cidr}" \\ -var="jenkins_ip_cidr=${TF_VAR_jenkins_ip_cidr}" \\
-var="aws_region=${TF_VAR_aws_region}" -var="aws_region=${TF_VAR_aws_region}"
"""
echo "✅ SECURITY: Infrastructure deployment completed with compliance verification" echo "🔄 Applying infrastructure changes..."
terraform apply -auto-approve \\
-var="cluster_name=${TF_VAR_cluster_name}" \\
-var="vpc_cidr=${TF_VAR_vpc_cidr}" \\
-var="public_subnets=${TF_VAR_public_subnets}" \\
-var="instance_type=${TF_VAR_instance_type}" \\
-var="key_pair_name=${TF_VAR_key_pair_name}" \\
-var="jenkins_ip_cidr=${TF_VAR_jenkins_ip_cidr}" \\
-var="aws_region=${TF_VAR_aws_region}"
"""
echo "✅ SECURITY: Infrastructure deployment completed successfully"
} catch (Exception e) {
echo "❌ Infrastructure deployment failed: ${e.getMessage()}"
echo "📋 Checking current Terraform state..."
sh "terraform show || echo 'No state found'"
throw e
}
} }
} }
} }
@@ -417,6 +474,9 @@ pipeline {
} }
stage('Configure & Deploy Application') { stage('Configure & Deploy Application') {
when {
not { expression { env.DEPLOYMENT_TYPE == "DESTROY" } }
}
parallel { parallel {
stage('Configure EC2 Instance via SSM') { stage('Configure EC2 Instance via SSM') {
when { when {
@@ -609,6 +669,9 @@ pipeline {
} }
stage('Verify Deployment') { stage('Verify Deployment') {
when {
not { expression { env.DEPLOYMENT_TYPE == "DESTROY" } }
}
steps { steps {
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) { withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: env.AWS_CRED_ID]]) {
script { script {
@@ -706,22 +769,26 @@ pipeline {
success { success {
script { script {
echo "🎉 SUCCESS: Deployment completed successfully!" if (env.DEPLOYMENT_TYPE == "DESTROY") {
echo " Version ${IMAGE_TAG} deployed to ECS cluster ${TF_VAR_cluster_name}" echo "🎉 SUCCESS: Infrastructure destroyed successfully!"
} else {
echo "🎉 SUCCESS: Deployment completed successfully!"
echo " Version ${IMAGE_TAG} deployed to ECS cluster ${TF_VAR_cluster_name}"
// Get application URL for success message // Get application URL for success message
def appUrl = "" def appUrl = ""
try { try {
appUrl = sh( appUrl = sh(
script: "cd terraform && terraform output -raw ecs_instance_public_ip 2>/dev/null || echo 'unknown'", script: "cd terraform && terraform output -raw ecs_instance_public_ip 2>/dev/null || echo 'unknown'",
returnStdout: true returnStdout: true
).trim() ).trim()
if (appUrl != "unknown" && appUrl != "") { if (appUrl != "unknown" && appUrl != "") {
echo "🌐 Application available at: http://${appUrl}:8080" echo "🌐 Application available at: http://${appUrl}:8080"
echo "🏥 Health check: http://${appUrl}:8080/health" echo "🏥 Health check: http://${appUrl}:8080/health"
}
} catch (Exception e) {
echo "⚠️ Could not determine application URL"
} }
} catch (Exception e) {
echo "⚠️ Could not determine application URL"
} }
} }
} }