Seperti yang dikatakan @Connor McCarthy, sambil menunggu Amazon muncul dengan solusi yang lebih baik untuk kunci yang lebih permanen, sementara itu kita perlu membuat kunci pada server Jenkins sendiri.
Solusi saya adalah memiliki pekerjaan berkala yang memperbarui kredensial Jenkins untuk ECR setiap 12 jam secara otomatis, menggunakan API Groovy. Ini didasarkan pada jawaban yang sangat terperinci ini , walaupun saya melakukan beberapa hal secara berbeda dan saya harus memodifikasi skripnya.
Langkah:
- Pastikan master Jenkins Anda dapat mengakses API AWS yang diperlukan. Dalam pengaturan saya master Jenkins berjalan pada EC2 dengan peran IAM, jadi saya hanya perlu menambahkan izin
ecr:GetAuthorizationToken
ke peran server. [ Update ] Untuk mendapatkan dorongan menyelesaikan berhasil, Anda juga akan perlu untuk memberikan izin ini: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage
. Amazon memiliki kebijakan bawaan yang menawarkan kemampuan ini, yang disebut AmazonEC2ContainerRegistryPowerUser
.
- Pastikan bahwa AWS CLI diinstal pada master. Dalam pengaturan saya, dengan master berjalan dalam wadah buruh pelabuhan debian, saya baru saja menambahkan langkah pembuatan shell ini ke pekerjaan pembuatan kunci:
dpkg -l python-pip >/dev/null 2>&1 || sudo apt-get install python-pip -y; pip list 2>/dev/null | grep -q awscli || pip install awscli
- Instal plugin Groovy yang memungkinkan Anda untuk menjalankan skrip Groovy sebagai bagian dari sistem Jenkins.
- Di layar kredensial, cari kunci AWS ECR Anda, klik "Advanced" dan catat "ID" -nya. Untuk contoh ini saya akan menganggap itu "12345".
- Buat pekerjaan baru, dengan peluncuran berkala 12 jam, dan tambahkan langkah membangun "skrip sistem Groovy" dengan skrip berikut:
import jenkins.model.*
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
def changePassword = { username, new_password ->
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
Jenkins.instance)
def c = creds.findResult { it.username == username ? it : null }
if ( c ) {
println "found credential ${c.id} for username ${c.username}"
def credentials_store = Jenkins.instance.getExtensionList(
'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
)[0].getStore()
def result = credentials_store.updateCredentials(
com.cloudbees.plugins.credentials.domains.Domain.global(),
c,
new UsernamePasswordCredentialsImpl(c.scope, "12345", c.description, c.username, new_password))
if (result) {
println "password changed for ${username}"
} else {
println "failed to change password for ${username}"
}
} else {
println "could not find credential for ${username}"
}
}
println "calling AWS for docker login"
def prs = "/usr/local/bin/aws --region us-east-1 ecr get-login".execute()
prs.waitFor()
def logintext = prs.text
if (prs.exitValue()) {
println "Got error from aws cli"
throw new Exception()
} else {
def password = logintext.split(" ")[5]
println "Updating password"
changePassword('AWS', password)
}
Tolong dicatat:
- penggunaan string kode keras
"AWS"
sebagai nama pengguna untuk kredensial ECR - ini adalah cara kerja ECR, tetapi jika Anda memiliki beberapa kredensial dengan nama pengguna "AWS", maka Anda harus memperbarui skrip untuk menemukan kredensial berdasarkan kredensial ECR. bidang deskripsi atau sesuatu.
- Anda harus menggunakan ID asli dari kunci ECR Anda yang sebenarnya dalam skrip, karena API untuk kredensial menggantikan objek kredensial dengan objek baru alih-alih hanya memperbaruinya, dan pengikatan antara langkah pembuatan Docker dan kuncinya adalah dengan ID. Jika Anda menggunakan nilai
null
untuk ID (seperti dalam jawaban yang saya tautkan sebelumnya), maka ID baru akan dibuat dan pengaturan kredensial pada langkah pembuatan buruh pelabuhan akan hilang.
Dan itu saja - skrip harus dapat berjalan setiap 12 jam dan menyegarkan kredensial ECR, dan kita dapat terus menggunakan plugin Docker.