Как использовать Terraform Plan и Apply на разных этапах конвейера Jenkins - PullRequest
0 голосов
/ 27 марта 2019

Я работаю над декларативным конвейером Jenkins для развертываний Terraform.Я хочу, чтобы рабочая область / план terraform init / select была запущена на одном этапе, запросить подтверждение на другом этапе, а затем подать заявку на другом этапе.У меня в верхней части агента установлено значение none, а затем используется агент kubernetes для созданного нами образа докера, в котором есть пакеты, необходимые для этапов.Я объявляю эти изображения на каждом этапе.Когда я выполняю конвейер, я получаю сообщение об ошибке, что мне нужно повторно инициализировать Terraform на этапе применения, даже если я инициализировал на этапе init / plan.Я полагаю, что это природа этапов, выполняющихся в разных узлах.

У меня это работает, выполняя 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
                           """
                        }
                    }
                }
            }
        }
    }
}
...