web-dev-qa-db-ja.com

環境変数Jenkins Pipelineでファイルをロードする

私は単純なパイプラインをやっています:

ビルド->ステージング->本番

ステージングとプロダクションには異なる環境変数が必要なので、source変数にしようとしています。

sh 'source $JENKINS_HOME/.envvars/stacktest-staging.sh' 

しかし、それはNot foundを返します

[Stack Test] Running Shell script
+ source /var/jenkins_home/.envvars/stacktest-staging.sh
/var/jenkins_home/workspace/Stack Test@tmp/durable-bcbe1515/script.sh: 2: /var/jenkins_home/workspace/Stack Test@tmp/durable-bcbe1515/script.sh: source: not found

パスが正しいのは、ssh経由でログインするときに同じコマンドを実行し、正常に動作するためです。

パイプラインのアイデアは次のとおりです。

node {
    stage name: 'Build'
    // git and gradle build OK
    echo 'My build stage'

    stage name: 'Staging'
    sh 'source $JENKINS_HOME/.envvars/stacktest-staging.sh' // PROBLEM HERE
    echo '$DB_URL' // Expects http://production_url/my_db
    sh 'gradle flywayMigrate' // To staging
    input message: "Does Staging server look good?"    

    stage name: 'Production'
    sh 'source $JENKINS_HOME/.envvars/stacktest-production.sh'
    echo '$DB_URL' // Expects http://production_url/my_db
    sh 'gradle flywayMigrate' // To production
    sh './deploy.sh'
}

私は何をすべきか?

  • パイプラインを使用しないことを考えていました(ただし、Jenkinsfileを使用することはできません)。
  • または、EnvInjectプラグインを使用して、ステージングとプロダクションに異なるジョブを作成します(ただし、ステージビューが失われます)
  • またはwithEnvを作成します(ただし、今日は12のenv変数を使用しているため、コードが大きくなります)
21
Rafael

ファイルから環境変数をロードできる1つの方法は、Groovyファイルをロードすることです。

例えば:

  1. 「$ JENKINS_HOME/.envvars」に「stacktest-staging.groovy」という名前のgroovyファイルがあるとします。
  2. このファイル内で、ロードする2つの環境変数を定義します

    env.DB_URL="hello"
    env.DB_URL2="hello2"
    
  3. 次に、これを使用してロードできます

    load "$JENKINS_HOME/.envvars/stacktest-staging.groovy"
    
  4. その後、それらを後続のエコー/シェル手順で使用できます。

たとえば、以下は短いパイプラインスクリプトです。

node {
   load "$JENKINS_HOME/.envvars/stacktest-staging.groovy"
   echo "${env.DB_URL}"
   echo "${env.DB_URL2}"
}
37
Daniel Omoto

コメントから 承認された回答

グローバル「env」を使用せず、「withEnv」コンストラクトを使用してください。例:#9を参照してください: トップ10ベストプラクティスjenkins pipeline plugin

次の例では、VAR1はプレーンJava文字列(groovy変数展開なし)、VAR2はgroovy文字列です(変数 'someGroovyVar'は展開されます)。

渡されたスクリプトは、プレーンなJava文字列であるため、$ VAR1および$ VAR2は文字通りシェルに渡され、エコーは環境変数VAR1およびVAR2にアクセスしています。

stage('build') {
    def someGroovyVar = 'Hello world'
    withEnv(['VAR1=VALUE ONE',
             "VAR2=${someGroovyVar}"
            ]) {
        def result = sh(script: 'echo $VAR1; echo $VAR2', returnStdout: true)
        echo result
    }
}

シークレット/パスワードには、 credentials binding plugin を使用できます

例:

注:CREDENTIALS_ID1は、Jenkins設定で登録されたユーザー名/パスワードシークレットです。

stage('Push') {
    withCredentials([usernamePassword(
                         credentialsId: 'CREDENTIALS_ID1',
                         passwordVariable: 'PASSWORD',
                         usernameVariable: 'USER')]) {
        echo "User name: $USER"
        echo "Password:  $PASSWORD"
    }
}

Jenkisnコンソールログ出力は、実際の値を隠します。

[Pipeline] echo
User name: ****
[Pipeline] echo
Password:  ****

Jenkinsと資格情報は大きな問題です。おそらく以下を参照してください: credentials plugin

完全を期すために:ほとんどの場合、シェルスクリプトから使用するため、環境変数にシークレットが必要です。そのため、次のようにwithCredentialsとwithEnvを組み合わせます。

stage('Push') {
    withCredentials([usernamePassword(
                         credentialsId: 'CREDENTIALS_ID1',
                         passwordVariable: 'PASSWORD',
                         usernameVariable: 'USER')]) {
        withEnv(["ENV_USERNAME=${USER}",
                 "ENV_PASSWORD=${PASSWORD}"
            ]) {
                def result = sh(script: 'echo $ENV_USERNAME', returnStdout: true)
                echo result

        }
    }
}
18
huch

この問題を解決する別の方法は、readPropertiesメソッドを提供する「Pipeline Utility Steps」プラグインをインストールします(参照については、リンク https://jenkins.io/doc/pipeline/steps/pipeline-utility-steps/# pipeline-utility-steps )この例では、配列にキーを保存し、キーを使用して値を取得していることがわかります。しかし、その場合、本番環境では、後で変数をプロパティファイルに追加すると、その変数もJenkinsファイルの配列に追加する必要があるようになります。この密結合を取り除くために、Jenkinsビルド環境が現在Propertyファイルに存在するすべての既存のキーに関する情報を自動的に取得できるようにコードを記述できます。ここに参考例があります

def loadEnvironmentVariables(path){
    def props = readProperties  file: path
    keys= props.keySet()
    for(key in keys) {
        value = props["${key}"]
        env."${key}" = "${value}"
    }
} 

そして、クライアントコードは次のようになります

path = '\\ABS_Output\\EnvVars\\pic_env_vars.properties'
loadEnvironmentVariables(path)
4
Sumanta Mondal

Jenkins 2.0を使用している場合、プロパティファイル(必要なすべての環境変数と対応する値で構成されます)をロードし、そこにリストされているすべての環境変数を自動的に読み取り、Jenkinsが提供するenvエンティティにそれを注入できます。

上記のアクションを実行するメソッドを次に示します。

def loadProperties(path) {
    properties = new Properties()
    File propertiesFile = new File(path)
    properties.load(propertiesFile.newDataInputStream())
    Set<Object> keys = properties.keySet();
    for(Object k:keys){
    String key = (String)k;
    String value =(String) properties.getProperty(key)
    env."${key}" = "${value}"
    }
}

このメソッドを呼び出すには、プロパティファイルのパスを文字列変数として渡す必要があります。たとえば、groovyスクリプトを使用するJenkinsファイルでは、次のように呼び出すことができます。

path = "${workspace}/pic_env_vars.properties"
loadProperties(path)

疑問がある場合は私に聞いてください

2
Sumanta Mondal