Skip to content

Commit 877d38e

Browse files
committed
Verify previous Terraform state can be reused
1 parent c48d3d3 commit 877d38e

6 files changed

Lines changed: 260 additions & 13 deletions

jenkins_pipelines/environments/common/pipeline-build-validation.groovy

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def run(params) {
2828
}
2929
try {
3030
stage('Clone terracumber, susemanager-ci and sumaform') {
31-
// Create a directory for to place the directory with the build results (if it does not exist)
31+
// Create a directory in which to place the build results (if it does not exist)
3232
sh "mkdir -p ${resultdir}"
3333
git url: params.terracumber_gitrepo, branch: params.terracumber_ref
3434
dir("susemanager-ci") {
@@ -37,9 +37,50 @@ def run(params) {
3737
// Clone sumaform
3838
sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync"
3939

40-
// Restore Terraform states from artifacts
40+
// Attempt to restore Terraform states from artifacts
4141
if (params.use_previous_terraform_state) {
42-
copyArtifacts projectName: currentBuild.projectName, selector: specific("${currentBuild.previousBuild.number}")
42+
def terraformDir = "${env.WORKSPACE}/sumaform/terraform"
43+
def terraformTmpDir = "${terraformDir}/temp/"
44+
def filters = 'results/sumaform/terraform.tfstate, results/sumaform/.terraform/**/*'
45+
def terraformStatePath = "results/sumaform/terraform.tfstate"
46+
def previousBuild = currentBuild.previousBuild
47+
def found = false
48+
49+
// Loop through previous builds until we find one for which a terraform state was stored
50+
while (previousBuild != null) {
51+
found = fileExists("${WORKSPACE}/${previousBuild.getArtifactsDir()}/${terraformStatePath}")
52+
if (found){
53+
echo "Found previous Terraform state in build ${previousBuild.number}."
54+
55+
// Copy just the necessary files (state and Terraform config) from the previous build to a temporary directory
56+
sh "mkdir -p ${terraformTmpDir}"
57+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"), filter: "${filters}" , target: "${terraformDir}"
58+
// Copy the Terraform configuration files (like main.tf, variables.tf, etc) from the current workspace to the temp dir
59+
sh "cp ${terraformDir}/*.tf ${terraformTmpDir}"
60+
61+
// Validate the restored Terraform state
62+
dir(terraformTmpDir) {
63+
sh "terraform init"
64+
def planOutput = sh(script: "terraform plan -refresh=true", returnStatus: true)
65+
66+
if (planOutput == 0) {
67+
echo "Terraform state from build ${previousBuild.number} is valid."
68+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"
69+
break
70+
} else {
71+
echo "Terraform state from build ${previousBuild.number} is invalid. Searching for another build."
72+
foundState = false
73+
}
74+
}
75+
}
76+
previousBuild = previousBuild.previousBuild
77+
}
78+
// Clean up the temp directory
79+
sh "rm -rf ${terraformTmpDir}"
80+
81+
if (!found) {
82+
echo "No previous Terraform state to restore. Starting from scratch."
83+
}
4384
}
4485
}
4586

jenkins_pipelines/environments/common/pipeline-reference-new.groovy

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,50 @@ def run(params) {
2020
// Clone sumaform
2121
sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync"
2222

23-
// Restore Terraform states from artifacts
23+
// Attempt to restore Terraform states from artifacts
2424
if (params.use_previous_terraform_state) {
25-
copyArtifacts projectName: currentBuild.projectName, selector: specific("${currentBuild.previousBuild.number}")
25+
def terraformDir = "${env.WORKSPACE}/sumaform/terraform"
26+
def terraformTmpDir = "${terraformDir}/temp/"
27+
def filters = 'results/sumaform/terraform.tfstate, results/sumaform/.terraform/**/*'
28+
def terraformStatePath = "results/sumaform/terraform.tfstate"
29+
def previousBuild = currentBuild.previousBuild
30+
def found = false
31+
32+
// Loop through previous builds until we find one for which a terraform state was stored
33+
while (previousBuild != null) {
34+
found = fileExists("${WORKSPACE}/${previousBuild.getArtifactsDir()}/${terraformStatePath}")
35+
if (found){
36+
echo "Found previous Terraform state in build ${previousBuild.number}."
37+
38+
// Copy just the necessary files (state and Terraform config) from the previous build to a temporary directory
39+
sh "mkdir -p ${terraformTmpDir}"
40+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"), filter: "${filters}" , target: "${terraformDir}"
41+
// Copy the Terraform configuration files (like main.tf, variables.tf, etc) from the current workspace to the temp dir
42+
sh "cp ${terraformDir}/*.tf ${terraformTmpDir}"
43+
44+
// Validate the restored Terraform state
45+
dir(terraformTmpDir) {
46+
sh "terraform init"
47+
def planOutput = sh(script: "terraform plan -refresh=true", returnStatus: true)
48+
49+
if (planOutput == 0) {
50+
echo "Terraform state from build ${previousBuild.number} is valid."
51+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"
52+
break
53+
} else {
54+
echo "Terraform state from build ${previousBuild.number} is invalid. Searching for another build."
55+
foundState = false
56+
}
57+
}
58+
}
59+
previousBuild = previousBuild.previousBuild
60+
}
61+
// Clean up the temp directory
62+
sh "rm -rf ${terraformTmpDir}"
63+
64+
if (!found) {
65+
echo "No previous Terraform state to restore. Starting from scratch."
66+
}
2667
}
2768
}
2869
stage('Deploy') {

jenkins_pipelines/environments/common/pipeline-reference.groovy

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,50 @@ def run(params) {
2020
// Clone sumaform
2121
sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync"
2222

23-
// Restore Terraform states from artifacts
23+
// Attempt to restore Terraform states from artifacts
2424
if (params.use_previous_terraform_state) {
25-
copyArtifacts projectName: currentBuild.projectName, selector: specific("${currentBuild.previousBuild.number}")
25+
def terraformDir = "${env.WORKSPACE}/sumaform/terraform"
26+
def terraformTmpDir = "${terraformDir}/temp/"
27+
def filters = 'results/sumaform/terraform.tfstate, results/sumaform/.terraform/**/*'
28+
def terraformStatePath = "results/sumaform/terraform.tfstate"
29+
def previousBuild = currentBuild.previousBuild
30+
def found = false
31+
32+
// Loop through previous builds until we find one for which a terraform state was stored
33+
while (previousBuild != null) {
34+
found = fileExists("${WORKSPACE}/${previousBuild.getArtifactsDir()}/${terraformStatePath}")
35+
if (found){
36+
echo "Found previous Terraform state in build ${previousBuild.number}."
37+
38+
// Copy just the necessary files (state and Terraform config) from the previous build to a temporary directory
39+
sh "mkdir -p ${terraformTmpDir}"
40+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"), filter: "${filters}" , target: "${terraformDir}"
41+
// Copy the Terraform configuration files (like main.tf, variables.tf, etc) from the current workspace to the temp dir
42+
sh "cp ${terraformDir}/*.tf ${terraformTmpDir}"
43+
44+
// Validate the restored Terraform state
45+
dir(terraformTmpDir) {
46+
sh "terraform init"
47+
def planOutput = sh(script: "terraform plan -refresh=true", returnStatus: true)
48+
49+
if (planOutput == 0) {
50+
echo "Terraform state from build ${previousBuild.number} is valid."
51+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"
52+
break
53+
} else {
54+
echo "Terraform state from build ${previousBuild.number} is invalid. Searching for another build."
55+
foundState = false
56+
}
57+
}
58+
}
59+
previousBuild = previousBuild.previousBuild
60+
}
61+
// Clean up the temp directory
62+
sh "rm -rf ${terraformTmpDir}"
63+
64+
if (!found) {
65+
echo "No previous Terraform state to restore. Starting from scratch."
66+
}
2667
}
2768
}
2869
stage('Deploy') {

jenkins_pipelines/environments/common/pipeline-salt-shaker.groovy

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,51 @@ def run(params) {
2020
}
2121
// Clone sumaform
2222
sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync"
23-
// Restore Terraform states from artifacts
23+
24+
// Attempt to restore Terraform states from artifacts
2425
if (params.use_previous_terraform_state) {
25-
copyArtifacts projectName: currentBuild.projectName, selector: specific("${currentBuild.previousBuild.number}")
26+
def terraformDir = "${env.WORKSPACE}/sumaform/terraform"
27+
def terraformTmpDir = "${terraformDir}/temp/"
28+
def filters = 'results/sumaform/terraform.tfstate, results/sumaform/.terraform/**/*'
29+
def terraformStatePath = "results/sumaform/terraform.tfstate"
30+
def previousBuild = currentBuild.previousBuild
31+
def found = false
32+
33+
// Loop through previous builds until we find one for which a terraform state was stored
34+
while (previousBuild != null) {
35+
found = fileExists("${WORKSPACE}/${previousBuild.getArtifactsDir()}/${terraformStatePath}")
36+
if (found){
37+
echo "Found previous Terraform state in build ${previousBuild.number}."
38+
39+
// Copy just the necessary files (state and Terraform config) from the previous build to a temporary directory
40+
sh "mkdir -p ${terraformTmpDir}"
41+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"), filter: "${filters}" , target: "${terraformDir}"
42+
// Copy the Terraform configuration files (like main.tf, variables.tf, etc) from the current workspace to the temp dir
43+
sh "cp ${terraformDir}/*.tf ${terraformTmpDir}"
44+
45+
// Validate the restored Terraform state
46+
dir(terraformTmpDir) {
47+
sh "terraform init"
48+
def planOutput = sh(script: "terraform plan -refresh=true", returnStatus: true)
49+
50+
if (planOutput == 0) {
51+
echo "Terraform state from build ${previousBuild.number} is valid."
52+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"
53+
break
54+
} else {
55+
echo "Terraform state from build ${previousBuild.number} is invalid. Searching for another build."
56+
foundState = false
57+
}
58+
}
59+
}
60+
previousBuild = previousBuild.previousBuild
61+
}
62+
// Clean up the temp directory
63+
sh "rm -rf ${terraformTmpDir}"
64+
65+
if (!found) {
66+
echo "No previous Terraform state to restore. Starting from scratch."
67+
}
2668
}
2769
}
2870
stage('Deploy') {

jenkins_pipelines/environments/common/pipeline.groovy

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,50 @@ def run(params) {
6262
// Clone sumaform
6363
sh "set +x; source /home/jenkins/.credentials set -x; ./terracumber-cli ${common_params} --gitrepo ${params.sumaform_gitrepo} --gitref ${params.sumaform_ref} --runstep gitsync"
6464

65-
// Restore Terraform states from artifacts
65+
// Attempt to restore Terraform states from artifacts
6666
if (params.use_previous_terraform_state) {
67-
copyArtifacts projectName: currentBuild.projectName, selector: specific("${currentBuild.previousBuild.number}")
67+
def terraformDir = "${env.WORKSPACE}/sumaform/terraform"
68+
def terraformTmpDir = "${terraformDir}/temp/"
69+
def filters = 'results/sumaform/terraform.tfstate, results/sumaform/.terraform/**/*'
70+
def terraformStatePath = "results/sumaform/terraform.tfstate"
71+
def previousBuild = currentBuild.previousBuild
72+
def found = false
73+
74+
// Loop through previous builds until we find one for which a terraform state was stored
75+
while (previousBuild != null) {
76+
found = fileExists("${WORKSPACE}/${previousBuild.getArtifactsDir()}/${terraformStatePath}")
77+
if (found){
78+
echo "Found previous Terraform state in build ${previousBuild.number}."
79+
80+
// Copy just the necessary files (state and Terraform config) from the previous build to a temporary directory
81+
sh "mkdir -p ${terraformTmpDir}"
82+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"), filter: "${filters}" , target: "${terraformDir}"
83+
// Copy the Terraform configuration files (like main.tf, variables.tf, etc) from the current workspace to the temp dir
84+
sh "cp ${terraformDir}/*.tf ${terraformTmpDir}"
85+
86+
// Validate the restored Terraform state
87+
dir(terraformTmpDir) {
88+
sh "terraform init"
89+
def planOutput = sh(script: "terraform plan -refresh=true", returnStatus: true)
90+
91+
if (planOutput == 0) {
92+
echo "Terraform state from build ${previousBuild.number} is valid."
93+
copyArtifacts projectName: currentBuild.projectName, selector: specific("${previousBuild.number}"
94+
break
95+
} else {
96+
echo "Terraform state from build ${previousBuild.number} is invalid. Searching for another build."
97+
foundState = false
98+
}
99+
}
100+
}
101+
previousBuild = previousBuild.previousBuild
102+
}
103+
// Clean up the temp directory
104+
sh "rm -rf ${terraformTmpDir}"
105+
106+
if (!found) {
107+
echo "No previous Terraform state to restore. Starting from scratch."
108+
}
68109
}
69110

70111
// run minima sync on mirror

0 commit comments

Comments
 (0)