Как сказал @Connor McCarthy, ожидая, пока Amazon придумает лучшее решение для более постоянных ключей, в то же время нам нужно как-то самим сгенерировать ключи на сервере Jenkins.
Мое решение состоит в том, чтобы иметь периодическую работу, которая обновляет учетные данные Jenkins для ECR каждые 12 часов автоматически, используя Groovy API. Это основано на этом очень подробном ответе , хотя я сделал несколько вещей по-другому, и мне пришлось изменить сценарий.
шаги:
- Убедитесь, что ваш мастер Jenkins может получить доступ к необходимому API AWS. В моей настройке мастер Jenkins работает на EC2 с ролью IAM, поэтому мне просто нужно было добавить разрешение
ecr:GetAuthorizationToken
для роли сервера. [ Обновление ] Чтобы получить какие - либо толчки успешно завершены, вы также должны предоставить эти разрешения: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage
. Amazon имеет встроенную политику, которая предлагает эти возможности, называется AmazonEC2ContainerRegistryPowerUser
.
- Убедитесь, что на главном компьютере установлен интерфейс командной строки AWS. В моей настройке, когда мастер работает в доке-контейнере Debian, я только что добавил этот шаг сборки оболочки в задание генерации ключа:
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
- Установите плагин Groovy, который позволяет запускать скрипт Groovy как часть системы Jenkins.
- На экране учетных данных найдите свой ключ AWS ECR, нажмите «Дополнительно» и запишите его «ID». Для этого примера я собираюсь предположить, что это «12345».
- Создайте новое задание с периодическим запуском в 12 часов и добавьте шаг сборки «системный скрипт Groovy» с помощью следующего сценария:
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)
}
Пожалуйста, обратите внимание:
- использование жестко запрограммированной строки в
"AWS"
качестве имени пользователя для учетных данных ECR - так работает ECR, но если у вас есть несколько учетных данных с именем пользователя «AWS», вам потребуется обновить сценарий, чтобы найти учетные данные на основе поле описания или что-то.
- Вы должны использовать реальный идентификатор вашего реального ключа ECR в сценарии, поскольку API для учетных данных заменяет объект учетных данных новым объектом, а не просто обновляет его, а привязка между этапом сборки Docker и ключом осуществляется с помощью идентификатора. Если вы используете значение
null
для идентификатора (как в ответе, который я связывал ранее), то будет создан новый идентификатор, и настройка учетных данных на этапе сборки докера будет потеряна.
И все - скрипт должен запускаться каждые 12 часов и обновлять учетные данные ECR, и мы можем продолжать использовать плагины Docker.