如何在不同的詹金斯管道阶段使用Terraform Plan和应用

时间:2019-03-27 00:22:27

标签: jenkins continuous-integration jenkins-pipeline terraform

我正在为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
                           """
                        }
                    }
                }
            }
        }
    }
}

0 个答案:

没有答案