【问题标题】:How to do user input in Jenkisfile to carry on with terraform apply?如何在 Jenkisfile 中进行用户输入以进行 terraform 应用?
【发布时间】:2022-01-27 22:52:21
【问题描述】:

我正在使用 Jenkinsfile 运行 Jenkins 管道作业。主要目的是运行 terraform <plan|apply>,根据 choice 参数选择planapply,如下所示:

stages {
  stage('tf_run') {
    steps { 
      sh '''#!/usr/bin/env bash
        terragrunt ${Action} --terragrunt-source "/var/temp/tf_modules//${tfm}"
      '''
    }
  }
}

Action 是选择参数变量,这对 计划 来说都是好的,但对于 apply 来说却失败了em> 因为它要求确认是否继续,并且工作立即下降。我可以在这里做什么,以便用户输入yes/no(或从列表中选择),然后可以将其传递给terraform apply

我被困在了中间,如果有人能把我引向正确的方向,我将不胜感激。感谢您提供的任何帮助。

-S

【问题讨论】:

  • 这里的问题是 Jenkins Pipeline 输入步骤会先于用于执行 Terraform CLI(端到端)的 shell 脚本方法。因此,您将在查看计划之前批准terraform apply,这不是您想要的。可以重构此管道以适应正常的 Terraform 部署管道,在该管道中生成、批准计划,然后在获得批准后传递给应用程序。如果没问题,那我可以给你写答案。
  • 另外,如果这适合传统的 Terraform git 工作流程,那么您可以在 PR 上生成计划并在合并时应用,如果接口移动到您的 SCM 服务器并进行接口,这也适用于您到您的 Jenkins 流水线。
  • 感谢@MattSchuchard 的提议。这正是我对input 步骤的问题。只要我不盲目运行-auto-approve,我对其他选项持开放态度。如果您能按照您提到的方式写下答案,我将不胜感激。
  • 添加了答案。老实说,这种管道有很多不同的蓝图,所以除了下面的功能答案之外,还有很多定制和扩展的机会。

标签: jenkins groovy terraform jenkins-plugins jenkins-groovy


【解决方案1】:

为了适应用例,Jenkins Pipeline 将分为三个步骤:

  • 生成计划文件
  • 查询用户输入以进行计划审批
  • 如果获得批准,应用计划文件

假设:您声称plan 的管道是成功的,这对我来说意味着Actiontfm 是环境变量(即env.Action),否则sh 步骤方法的String 参数是无效的。鉴于该假设:

(现在应要求修改答案以将 tfm 演示为管道参数,并且不再位于 env 对象中)

parameters {
  string(name: 'tfm', description: 'Terraform module to act upon.')
}

stages {
  stage('TF Plan') {
    steps {
      // execute plan and capture plan output 
      sh(
         label:  'Terraform Plan',
         script: "terragrunt plan -out=plan.tfplan -no-color --terragrunt-source '/var/temp/tf_modules//${params.tfm}'"
      )
    }
  }
  stage('TF Apply') {
    // only execute stage if apply is desired
    when { expression { return env.Action == 'apply' } }
    steps {
      // query for user approval of plan
      input(message: 'Click "proceed" to approve the above Terraform Plan')
      // apply the plan if approved
      sh(
         label:  'Terraform Apply',
         script: 'terraform apply -auto-approve -input=false -no-color plan.tfplan'
      )
    }
  }
}

您可能还想将 env.TF_IN_AUTOMATION = true 的等效项添加到 environment 指令中。这在管道中执行 Terraform 时会很有帮助。

如果您还将管道agent 修改为例如Terraform CLI 镜像作为容器运行,那么计划输出文件也需要在阶段之间保留。

【讨论】:

  • 感谢@Matt Schuchard!我使用的 bash 脚本比这要复杂一些,${Action} 是参数(因此可以在任何地方使用),但 ${tfm} 是 bash 变量。知道如何将它分配给一个 groovy 变量,以便可以在稍后的 stage{} 中使用?
  • @MacUsers 是的,我也可以回答这个简单的问题,但我不确定它是如何关联的。
  • 正如我之前提到的,我要运行的实际 bash 脚本比那些简单的几行要多一些,并且很少有公共变量,由 bash 生成,包括我需要的 ${tfm}在两个阶段(计划和应用)中使用。我计划在 planapply 之前引入另一个阶段以生成所有这些必需的变量,然后在后面的两个阶段使用它们。因此,提出了额外的问题。没错,它没有直接关系。但是,如果你能告诉我,不胜感激。
  • @MacUsers 好的,我根据您之前的评论更新了答案,但根据您的新评论,您需要对问题进行重大更新,以提供有关该用例和示例代码的信息。您应该针对该信息提出一个新问题。
  • 感谢@Matt Schuchard!我已经尝试过parameters { ... } 块,但对我不起作用,因为这些变量是动态形成的,而不是静态类型的。相反,我在script { ...} 中使用多行sh( ... ) 做到了这一点——我认为这不是最好的,但对我有用。
【解决方案2】:

您可以在 Jenkins 作业中使用 terraform apply -auto-approve

See Docs

提示:当用户选择参数计划时,您可以在 Jenkins stage() 中添加条件,而不是自动添加 -auto-approve 选项,否则该命令将附加 -auto-approve 选项。

stage(plan&apply){
  if ${USER_INPUT} == "plan"{
    terraform plan
  }
  else{
   terraform apply -auto-approve
  }
}

注意:上面的 Jenkins 代码可能与正确的 Ans 不匹配,但可以作为示例。

【讨论】:

  • 问题是:我不想使用-auto-approve,这是一项有风险的业务。对于apply,我喜欢在 GUI 上复制与使用 CLI 相同的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2012-09-22
  • 2013-04-23
  • 1970-01-01
相关资源
最近更新 更多