Jenkinsfile 讀取 Jenkins 憑證(Credentials)裡的機密內容(密碼字串)

在 Jenkins 的「作業」>「組態」中可以使用「參數化建置」功能,自訂參數

雖然這裡有「密碼參數」,但是不論是手動執行一次「帶參數建置」或是利用 WebHook 之類的功能自動建置後這個參數就會消失。執行「帶參數建置」時也只會留下其他欄位可以填,並不會保留「密碼參數」的欄位。

代表密碼參數不是這樣用的,假設有機密資訊要傳入、需要被 Jenkinsfile 中的 pipeline 讀取,應該是使用 Jenkins 中的憑證(Credentials)功能才對。

建立新憑證

點選「管理 Jenkins」> Credentials

點選 Stores scoped to Jenkins 下方的 System 區塊

再點選 Global credential (unrestricted)

點選右上角的 Add Credentials 就可以建立新增憑證

這裡有許多憑證種類可以選擇,筆者這裡就示範最常使用的 Secret text ,也就是密碼。

ID 就是未來讀取時會用到的名稱,可以使用英文,也可以留空自動產生
Secret 就是密碼內容,寫入之後未來就無法再查看
Description 可以任意輸入,方便其他人或是未來的自己知道這個參數是用來幹嘛的,如果 ID 欄位留空這裡也不填那真的沒有人知道這個密碼是用來幹嘛的了

在 Jenkinsfile 中讀取憑證

下面是一個非常簡單的 Jenkinsfile ,假設在上面的步驟中建立了一個 project1_jwt_key 的 Secret text ,在 Jenkinsfile 中我們就可以使用 withCredentials 來將 project1_jwt_key 這個 credentials Id 中的資料轉換成 JWT_KEY 變數,然後就可以很方便的使用這個變數了:
    
pipeline {
    agent any
    
    environment {
    }
    
    stages {
        stage('Run')
        {
            steps {
                
                withCredentials([string(credentialsId: 'project1_jwt_key', variable: 'JWT_KEY')]) {
                
                    sh 'docker run -d --name my_container -e \"Jwt:SignKey=${JWT_KEY}\"  my_docker_image '
                    
                }
                
            }
        }
    }
}
    

上面的 withCredentials 外面有一個大括號區塊 ( '{}' ) ,要在這個區塊中才可以讀取到這個變數,那如果有很多個變數不就要很多層?其實有更簡單的方法,可以放在 withCredentials 的中括號 ( '[]' )中:
    
pipeline {
    agent any
    
    environment {
    }
    
    stages {
        stage('Run')
        {
            steps {
            
                withCredentials([
                    string(credentialsId: 'project1_jwt_key', variable: 'JWT_KEY'),
                    string(credentialsId: 'project1_api_key', variable: 'API_KEY')
                ]) {
                
                    sh 'docker run -d --name my_container -e \"Jwt:SignKey=${JWT_KEY}\" -e \"OpenAi:ApiKey=${API_KEY}\" my_docker_image '
                    
                }
                
            }
        }
    }
}
    

使用這樣的方式在「建置」的過程中會將該資料的部分內容使用 '*' 號隱藏,這才是密碼的正確儲存和使用方式!

參考資料:
Jenkins - Using a Jenkinsfile #Handling credentials
Stack Overflow - Jenkins secret text credential as variable in pipeline script

留言