Search code examples
jenkinsjenkins-pipelinejenkins-groovy

How to inject the jenkins credentials actual values to the file


I am having some deployment file as part of the source code it has the two values

deploy.sh

db_public_key="pub_key"
db_private_key="pri_key"

The actual values for those variables are stored in jenkins credentials as secret text

I need to pass the actual values for those variables from jenkins credentals during run time

Jenkins pipeline

#!/usr/bin/groovy

pipeline {
    agent any
  

stages{ 

stage("source code") {
            steps {
                sh 'git clone https://xxx:xxx@bitbucket.org/xxx.git'
        }
    }       
 
stage("updating public keys") {
            steps {
                script {
                    withCredentials([string(credentialsId: 'data_public_key', variable: 'public_key')]) {
                    sh 'sed -i "s/pub_key/$public_key/g" deploy.sh'
                   }
                 }  
          }
      }   
    }       
}   

But when I do with sed command its not replacing the actual values instead it is storing as ****

How can I fetch those values from credentials and replace with actual values in the deploy.sh file in jenkins pipeline


Solution

  • Is not recommended to have sensible values directly in the script. I advice the use of environment variables.

    Override secrets with bash

    If you use a secret loaded inside of withCredentials, the value is masked with **** (jenkins feature to prevent to show secrets in the log)

    withCredentials([string(credentialsId: 'data_public_key', variable: 'public_key')]) {
      println "inside: "+public_key
    }
    

    enter image description here

    A workaround is to store it in a global variable and the use it

    def secretValue;   
    withCredentials([string(credentialsId: 'data_public_key', variable: 'public_key')]) {
      println "inside: "+public_key
      secretValue = public_key
    }
    println "outside: "+secretValue
    

    enter image description here

    Then you could use the variable as you need.

    Note: If yu want to use variables inside pipeline you need to use double quotes instead single quote. Variables inside single quotes are not evaluated.

    sh "sed -i s/pub_key/$secretValue/g deploy.sh"

    Full pipeline here

    pipeline {
        agent any
    
        stages {
            stage('write') {
                   steps {
                       script {
                           //just to simulate your deploy.sh file
                           def data = 'db_public_key="pub_key"\ndb_private_key="pri_key"'
                           writeFile(file: 'deploy.sh', text: data)
                           println "initial file content"
                           sh "cat deploy.sh"
                       }
                   }
            }
            
            stage('set variables') {
                   steps {
                       script {
                        def secretValue;   
                        withCredentials([string(credentialsId: 'data_public_key', variable: 'public_key')]) {
                          println "inside: "+public_key
                          secretValue = public_key
                        }
                        //after
                        println "outside: "+secretValue
                        sh "sed -i s/pub_key/$secretValue/g deploy.sh"
                        
                        println "final file content"
                        sh "cat deploy.sh"
                     } 
                   }
            }        
        }
    }
    

    Result

    enter image description here


    Override secrets with groovy

    Anyway if you need to write the values (sensible or not) directly you could use groovy which allows you to use all the java features to do whatever you need

    def newFileContent = fileContent.replace("pub_key","super-pub-key").replace("pri_key","super-pri-key")
    

    Full pipeline here:

    pipeline {
        agent any
    
        stages {
            stage('write') {
                   steps {
                       script {
                           //just to simulate your deploy.sh file
                           def data = 'db_public_key="pub_key"\ndb_private_key="pri_key"'
                           writeFile(file: 'deploy.sh', text: data)
                           sh "ls -l"
                           sh "cat deploy.sh"
                       }
                   }
            }
            
            stage('set variables') {
                   steps {
                       script {
                           def fileContent = readFile "deploy.sh"
                           def newFileContent = fileContent.replace("pub_key","super-pub-key").replace("pri_key","super-pri-key")
                           writeFile(file: 'deploy.sh', text: newFileContent)
                           sh "cat deploy.sh"
                       }
                   }
            }        
        }
    }
    

    Result

    enter image description here


    Recommended : env variable

    As I told you, hardcode secrets in file is a bad practice. You should use environment variables. Also env variables is a part of devops bible https://12factor.net/config

    So you script should be:

    db_public_key="$_SECRET_KEY"
    echo "value is: "$db_public_key
    

    Then you only need to inject the variable before its execution:

    env._SECRET_KEY = secretValue
    sh '$(pwd)/deploy.sh'
    

    Full pipeline here

    pipeline {
        agent any
    
        stages {
            stage('write') {
                   steps {
                       script {
                           //just to simulate your deploy.sh file
                           def data = 'db_public_key="$_SECRET_KEY"\necho "value is: "$db_public_key'
                           writeFile(file: 'deploy.sh', text: data)
                           println "initial file content"
                           sh "cat deploy.sh"
                           sh "chmod +x deploy.sh"
                       }
                   }
            }
            
            stage('set variables') {
                   steps {
                       script {
                        def secretValue;   
                        withCredentials([string(credentialsId: 'data_public_key', variable: 'public_key')]) {
                          secretValue = public_key
                        }
                        
                        env._SECRET_KEY = secretValue
                        sh '$(pwd)/deploy.sh'
                     } 
                   }
            }        
        }
    }
    

    Result

    enter image description here