昨天我們成功在本機利用Ansible安裝及部署我們的專案。那麽今天,我們就利用Jenkins進行自動化操作吧!
main.tf
由於我們想把整個部署流程自動化,但每次更新Terraform的時候,有機會會把VM重新啟動。而GCP的VM重新啟動時,公用IP的位址會更新,因此當用Ansible進行連接時,要先取得新的VM的IP。因此我們需要先修改main.tf
,以輸出更新後的IP。
在main.tf
最後的部份加入以下內容。
output "instance_public_ip" {
value = "${google_compute_instance.helloworld_instance.network_interface.0.access_config.0.nat_ip}"
}
這樣我們就會在Terraform部署完成後輸出IP到instance_public_ip
這個變數中。
Jenkinsfile
為了同時在Terraform跟Ansible的Stage中同時存取到IP位址的資訊,我們要定義一個環境變數。
在agent any
的下方加入以下內容。
environment {
instancePublicIp = ""
}
這裡我們在初始化時設定一個instancePublicIp
變數。
然後我們在Terraform的Stage中,最後的部份加入以下內容。
script {
instancePublicIp = sh(returnStdout: true, script: "terraform output instance_public_ip").trim()
}
這裡是利用returnStdout
去取得Terraform的輸出並傳入到instancePublicIp
,然後下一步我們就可以在Ansible的Stage中取得該IP資訊。
如同往常一樣,我們要把Private Key存放到Jenkins的Credentials中,以便連接到VM。
到Jenkins的設定頁面,然後按下Manage Credentials
。
按下Stores scoped to Jenkins
部份,Domain
一欄下的(global)
。
在右上方按下Add Credentials
。
在下拉選單中選擇SSH Username with private key
,然後輸入以下資訊。
ID
: ansible-auth-key
Username
: 你的VM登入名稱Treat username as secret
Private Key
: 輸入你的Private Key,可以在Terminal中運行cat {Private Key Path}
取得然後按`Create。
可以看見新的Credential已經成功加入。
在Jenkinsfile
的Terraform Stage下方加入以下內容。
stage('Ansible Deployment') {
steps {
withCredentials([sshUserPrivateKey(credentialsId: 'ansible-auth-key', keyFileVariable: 'ansible_auth_key', usernameVariable: 'ansible_user')]) {
sh "ansible-playbook -i \"${instancePublicIp}\", main.yml -u \"${ansible_user}\" --private-key \"${ansible_auth_key}\""
}
}
}
withCredentails([sshUserPrivateKey(…)])
: 取得我們剛剛上傳的Private Key資料簡單來說這裡只是把我們在本機運行的指令,在Jenkins中重新運行一次,並利用變數instancePublicIp
、ansible_user
及ansible_auth_key
去傳入相關連接資訊。
然後Commit、上傳、再運行Pipeline。
如無意外,我們成功運行了Pipeline!
終於,到了第27天,我們成功把源碼自動化封裝部署到雲端了!以後每當我們修改任何程式碼以後,只需要按一下Build Now,我們就可以輕輕鬆鬆的讓Jenkins幫我們部署了。
這裡本來是想用Jenkins提供的Ansible插件去進行Ansible Playbook的運作,但不知怎麼的用插件總是執行不了,最後只有強行用Shell Script去解決。當然這個做法未必是最好,但有時候當我們進行開發時,總會有未如理想的情況。是次因為鐵人賽的關係,未有時間去把所有步驟都做得完美。但最起碼我覺得我已經努力去把整個鐵人賽能做的部份都做到最好了。