automated terminal push
This commit is contained in:
113
Jenkinsfile
vendored
113
Jenkinsfile
vendored
@@ -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,34 +143,18 @@ 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 {
|
|
||||||
// Check if infrastructure actually exists in AWS
|
|
||||||
def clusterExists = false
|
|
||||||
try {
|
|
||||||
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 {
|
} else {
|
||||||
env.DEPLOYMENT_TYPE = "APPLICATION"
|
env.DEPLOYMENT_TYPE = "APPLICATION"
|
||||||
|
currentBuild.displayName = "APPLICATION-${BUILD_NUMBER}"
|
||||||
echo "✅ SECURITY: Application-only deployment - using restricted permissions"
|
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()
|
||||||
def gitAuthor = sh(script: 'git log -1 --pretty=format:"%an"', returnStdout: true).trim()
|
def gitAuthor = sh(script: 'git log -1 --pretty=format:"%an"', 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,6 +382,9 @@ 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..."
|
||||||
|
|
||||||
|
// Add error handling for Terraform operations
|
||||||
|
try {
|
||||||
sh """
|
sh """
|
||||||
echo "🔄 Initializing Terraform with remote backend..."
|
echo "🔄 Initializing Terraform with remote backend..."
|
||||||
terraform init \\
|
terraform init \\
|
||||||
@@ -362,7 +413,13 @@ pipeline {
|
|||||||
-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 "✅ 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,6 +769,9 @@ pipeline {
|
|||||||
|
|
||||||
success {
|
success {
|
||||||
script {
|
script {
|
||||||
|
if (env.DEPLOYMENT_TYPE == "DESTROY") {
|
||||||
|
echo "🎉 SUCCESS: Infrastructure destroyed successfully!"
|
||||||
|
} else {
|
||||||
echo "🎉 SUCCESS: Deployment completed successfully!"
|
echo "🎉 SUCCESS: Deployment completed successfully!"
|
||||||
echo " Version ${IMAGE_TAG} deployed to ECS cluster ${TF_VAR_cluster_name}"
|
echo " Version ${IMAGE_TAG} deployed to ECS cluster ${TF_VAR_cluster_name}"
|
||||||
|
|
||||||
@@ -725,6 +791,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
failure {
|
failure {
|
||||||
script {
|
script {
|
||||||
|
Reference in New Issue
Block a user