我正在为Terraform部署开发声明性的Jenkins管道。我想在一个阶段中使用Terraform初始化/选择工作空间/计划,在另一个阶段中寻求批准,然后在另一个阶段中进行申请。我将顶部的代理设置为none,然后将kubernetes代理用于我们创建的Docker映像,该映像具有阶段所需的软件包。我在每个阶段都声明这些图像。执行管道时,即使在初始化/计划阶段进行了初始化,也出现了一个错误,我需要在应用阶段重新初始化Terraform。我认为这是在不同节点上运行的阶段的本质。
我通过执行init / plan并存储该计划来使其工作。在应用阶段,它将取消计划的存储,再次调用init / select工作空间,然后最终应用未执行的计划。
我意识到我可以将代理设置在顶部,但是根据Jenkins文档,这是一种不好的做法,因为等待用户输入会阻止执行。
我觉得必须有一种方法可以更优雅地做到这一点。有什么建议吗?
这是我的代码:
def repositoryURL = env.gitlabSourceRepoHttpUrl != null && env.gitlabSourceRepoHttpUrl != "" ? env.gitlabSourceRepoHttpUrl : env.RepoURL def repositoryBranch = env.gitlabTargetBranch != null && env.gitlabTargetBranch != "" ? env.gitlabTargetBranch : env.RepoBranch def notificationEmail = env.gitlabUserEmail != null && env.gitlabUserEmail != "" ? env.gitlabSourceRepoHttpUrl : env.Email def projectName = env.ProjectName def deployAccountId = env.AccountId pipeline { agent none stages { stage("Checkout") { agent any steps { git branch: "${repositoryBranch}", credentialsId: '...', url: "${repositoryURL}" stash name: 'tf', useDefaultExcludes: false } } stage("Terraform Plan") { agent { kubernetes { label 'myagent' containerTemplate { name 'cis' image 'docker-local.myrepo.com/my-image:v2' ttyEnabled true command 'cat' } } } steps { container('cis') { unstash 'tf' script { sh "terraform init" try { sh "terraform workspace select ${deployAccountId}_${projectName}_${repositoryBranch}" } catch (Exception e) { sh "terraform workspace new ${deployAccountId}_${projectName}_${repositoryBranch}" } sh "terraform plan -out=${deployAccountId}_${projectName}_${repositoryBranch}_plan.tfplan -input=false" stash includes: "*.tfplan" name: "tf-plan", useDefaultExcludes: false } } } post{ success{ echo "Terraform init complete" } failure{ echo "Terraform init failed" } } } stage ("Terraform Plan Approval") { agent none steps { script { def userInput = input(id: 'confirm', message: 'Apply Terraform?', parameters: [ [$class: 'BooleanParameterDefinition', defaultValue: false, description: 'Apply terraform', name: 'confirm'] ]) } } } stage ("Terraform Apply") { agent { kubernetes { label 'myagent' containerTemplate { name 'cis' image 'docker-local.myrepo.com/my-image:v2' ttyEnabled true command 'cat' } } } steps { container("cis") { withCredentials([[ $class: 'AmazonWebServicesCredentialsBinding', credentialsId: 'my-creds', accessKeyVariable: 'AWS_ACCESS_KEY_ID', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY' ]]) { script { unstash "tf" unstash "tf-plan" sh "terraform init" try { sh "terraform workspace select ${deployAccountId}_${projectName}_${repositoryBranch}" } catch (Exception e) { sh "terraform workspace new ${deployAccountId}_${projectName}_${repositoryBranch}" } sh """ set +x temp_role="\$(aws sts assume-role --role-arn arn:aws:iam::000000000000:role/myrole --role-session-name jenkinzassume)" > /dev/null 2>&1 export AWS_ACCESS_KEY_ID=\$(echo \$temp_role | jq .Credentials.AccessKeyId | xargs) > /dev/null 2>&1 export AWS_SECRET_ACCESS_KEY=\$(echo \$temp_role | jq .Credentials.SecretAccessKey | xargs) > /dev/null 2>&1 export AWS_SESSION_TOKEN=\$(echo \$temp_role | jq .Credentials.SessionToken | xargs) > /dev/null 2>&1 set -x terraform apply ${deployAccountId}_${projectName}_${repositoryBranch}_plan.tfplan """ } } } } } } }