将 HashiCorp Vault KV 秘密注入 Jenkins 管道

问题描述 投票:0回答:1

我试图构建一个构建和部署 Nodejs 应用程序的管道。在此管道中

NodeJS
代码正在部署。所有步骤均按要求通过。但看起来构建图像时缺少
env
文件。 现在我想在应用程序的根文件夹中创建一个
.env
文件并使用它来构建项目。

我将环境变量存储在部署在不同服务器上的 HashiCorp

Vault
中。 我想提取路径
secrets/creds/my-app
中的所有秘密并将其插入到
.env
文件中。

我对 Vault 和 Jenkins 都是新手,请帮助我。

管道将在推送到

BitBucket
存储库时触发。我正在使用 HashiCorp Vault

下面是我的管道(

Jenkinsfile
)

pipeline{
agent any
tools { nodejs "nodejs18" }
stages{
    stage ('Checkout'){
    steps{
        checkout scm
    }
    }
    stage ('Cleanup') {
    steps{
        sh 'rm -rf node_modules'
    }
    }
    stage('Setup Environment') {
        steps {
            script{
                def secrets = [
                    [
                        path: 'secrets/creds/my-app', 
                        engineVersion: 1, 
                        secretValues: [[vaultKey: 'PORT'], [vaultKey: 'MONGO_DB_URL']]
                    ]
                ]

                def configuration = [
                    vaultUrl: 'http:/my-vault.com',
                    vaultCredentialId: 'vault-jenkins',
                    engineVersion: 1
                ]
                withVault([configuration: configuration, vaultSecrets: secrets]) {
                    def secretData = vaultRead(path: 'secrets/creds/my-app')
                    sh 'echo "Vault KV Values"'
                    echo "All secrets: ${secretData.data}"
                }
            }
        }
    }
    stage ('Resolve Dependency'){
    steps{
        sh '''
        npm install
        '''
    }
    }
    stage ('Build Project') {
    steps{
        sh 'npm run build'
    }
    }
    stage('Build & Push Docker') {
        steps {
            script {
                def dockerImage = docker.build("my-username/my-app-api:master", '--network host .')
                docker.withRegistry('', 'my-username') {
                    dockerImage.push('master')
                }
            }
        }
    }
    stage('Pull') {
        steps {
            script {
                docker.withRegistry('', 'my-username') {
                    def dockerImage = docker.image("my-username/my-app-api:master")
                    dockerImage.pull()
                }
            }
        }
    }
    stage('Deploy') {
        steps {
            script {
                sh 'docker stop my-appapi || true'
                sh 'docker rm my-appapi || true'
                sh 'docker run -d --name my-appapi -p 3000:3000 my-username/my-app-api:master'
            }
        }
    }
}
}

此配置将引发以下错误

java.lang.NoSuchMethodError: No such DSL method 'vaultRead' found among steps

另外,我找到了一个答案,有人建议在管道开始时导入如下库。

@Library('hashicorp-vault') _
import com.datapipe.jenkins.vault.*

这将引发与上面不同的错误。

ERROR: Could not find any definition of libraries [hashicorp-vault]

我尝试了更多的事情,找到了一个答案,那就是转到 管理 Jenkins > 配置系统 > 全局管道库,然后添加

hashicorp-vault
作为库。

我找不到库 github 链接,因此尝试添加

https://github.com/jenkinsci/hashicorp-vault-plugin.git
作为库 URL。下面是错误日志。

Loading library [email protected]_1c04cf807d
11:17:41 Jenkins-Imposed API Limiter: Current quota for Github API usage has 51 remaining (2 over budget). Next quota of 60 in 59 min. Sleeping for 6 min 51 sec.
11:17:41 Jenkins is attempting to evenly distribute GitHub API requests. To configure a different rate limiting strategy, such as having Jenkins restrict GitHub API requests only when near or above the GitHub rate limit, go to "GitHub API usage" under "Configure System" in the Jenkins settings.
11:20:42 Jenkins-Imposed API Limiter: Still sleeping, now only 3 min 48 sec remaining.
11:23:43 Jenkins-Imposed API Limiter: Still sleeping, now only 47 sec remaining.
Examining jenkinsci/hashicorp-vault-plugin
Attempting to resolve 360.v0a_1c04cf807d as a branch
Attempting to resolve 360.v0a_1c04cf807d as a tag
Resolved 360.v0a_1c04cf807d as tag 360.v0a_1c04cf807d at revision 0a1c04cf807da08a74dcf499865fa96ee8dbae39
The recommended git tool is: NONE
No credentials specified
Cloning the remote Git repository
Cloning with configured refspecs honoured and with tags
Cloning repository https://github.com/jenkinsci/hashicorp-vault-plugin.git
> git init /var/jenkins_home/workspace/curiovy-api-v2@libs/cbf0f7307134c7e67151812899f055d0a075a06bbb887daaec9cd68facf7b289 # timeout=10
Fetching upstream changes from https://github.com/jenkinsci/hashicorp-vault-plugin.git
> git --version # timeout=10
> git --version # 'git version 2.30.2'
> git fetch --tags --force --progress -- https://github.com/jenkinsci/hashicorp-vault-plugin.git +refs/tags/360.v0a_1c04cf807d:refs/tags/360.v0a_1c04cf807d # timeout=10
> git config remote.origin.url https://github.com/jenkinsci/hashicorp-vault-plugin.git # timeout=10
> git config --add remote.origin.fetch +refs/tags/360.v0a_1c04cf807d:refs/tags/360.v0a_1c04cf807d # timeout=10
> git config remote.origin.url https://github.com/jenkinsci/hashicorp-vault-plugin.git # timeout=10
Fetching with tags
Fetching upstream changes from https://github.com/jenkinsci/hashicorp-vault-plugin.git
> git fetch --tags --force --progress -- https://github.com/jenkinsci/hashicorp-vault-plugin.git +refs/tags/360.v0a_1c04cf807d:refs/tags/360.v0a_1c04cf807d # timeout=10
Checking out Revision 0a1c04cf807da08a74dcf499865fa96ee8dbae39 (360.v0a_1c04cf807d)
> git config core.sparsecheckout # timeout=10
> git checkout -f 0a1c04cf807da08a74dcf499865fa96ee8dbae39 # timeout=10
Commit message: "Mark logger as transient (#285)"
First time build. Skipping changelog.
Excluding src/test/ from checkout of git https://github.com/jenkinsci/hashicorp-vault-plugin.git so that library test code cannot be accessed by Pipelines.
To remove this log message, move the test code outside of src/. To restore the previous behavior that allowed access to files in src/test/, pass -Dorg.jenkinsci.plugins.workflow.libs.SCMSourceRetriever.INCLUDE_SRC_TEST_IN_LIBRARIES=true to the java command used to start Jenkins.
ERROR: Library hashicorp-vault expected to contain at least one of src or vars directories
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: Loading libraries failed

1 error

    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1107)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:624)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:602)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:579)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:323)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:293)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox$Scope.parse(GroovySandbox.java:163)
    at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:190)
    at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:175)
    at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:568)
    at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:518)
    at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:336)
    at hudson.model.ResourceController.execute(ResourceController.java:101)
    at hudson.model.Executor.run(Executor.java:442)
Finished: FAILURE

如果我做错了什么,请给我解决方案或指出正确的方向。 我将

.env
添加到项目构建的方式是否正确?或者我需要执行其他步骤吗?

jenkins jenkins-pipeline jenkins-plugins jenkins-groovy hashicorp-vault
1个回答
0
投票

要将机密从保管库加载到管道中,您有两种方法

  1. 配置为代码插件+Vault插件 CASC 金库

你需要将 envs doc 通过 Vault auth 传递给 jenkins master

CASC_VAULT_URL 
CASC_VAULT_TOKEN
CASC_VAULT_PATHS

路径将在哪里

secrets/creds/my-app
jenkins 将通过 CASC 插件将机密加载到凭据中,如下所示

- credentials:
  - string:
    id: "cred-id"
    secret: "${my-secret}"

其中

my-secret
是金库秘密

vault path: secrets/creds/my-app
                          my-secret=secretvalue
                          my-secret2=secretvalue2

并在管道中与凭据绑定插件一起使用它,如下所示:

https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

withCredentials([string(credentialsId: 'cred-id', variable: 'TOKEN')]) {
    sh '''
      $TOKEN >> .env
    '''
}

2.使用hashicorp-vault-plugin,无需任何东西

// how vault secret structure looks like:
// secrets/creds/my-app
//               secret_one="my-super-secret-ssh-key"
//               secret_two="my-super-secret-ssh-key"

def secrets = [
  [
    path: 'secrets/creds/my-app', engineVersion: 2, secretValues: [
      [envVar: 'SSH_SECRET_ENV_VAR', vaultKey: 'secret_one'],
      [envVar: 'ANOTHER_SECRET_ENV_VAR', vaultKey: 'secret_two']
    ]
  ]
]

// optional configuration, if you do not provide this the next higher configuration
// (e.g. folder or global) will be used
def configuration = [
  vaultUrl: 'http:/my-vault.com',
  // 'vault-jenkins' -> key from global jenkins credentials or folder jenkins credentials
  // see https://plugins.jenkins.io/hashicorp-vault-plugin/#plugin-content-vault-token-credential
  vaultCredentialId: 'vault-jenkins',
  engineVersion: 2
]
// inside this block your credentials will be available as env variables
withVault([configuration: configuration, vaultSecrets: secrets]) {
    sh 'echo "sshkey=$SSH_SECRET" >> .env'
    sh 'echo "password=$ANOTHER_SECRET_ENV_VAR" >> .env'
}

它将把密钥的值从库路径加载到环境变量中,请参阅“秘密”^

© www.soinside.com 2019 - 2024. All rights reserved.