Як сказав @Connor McCarthy, чекаючи, поки Amazon придумає краще рішення для більш постійних ключів, в той же час нам потрібно буде якось генерувати ключі на сервері Jenkins.
Моє рішення - мати періодичну роботу, яка автоматично оновлює облікові дані Дженкінса для ECR кожні 12 годин за допомогою API Groovy. На цьому ґрунтується ця дуже детальна відповідь , хоча я зробив декілька речей інакше, і мені довелося змінити сценарій.
Кроки:
- Переконайтесь, що ваш майстер Дженкінса може отримати доступ до потрібного API AWS. У моїх налаштуваннях майстер Дженкінса працює на EC2 з роллю IAM, тому мені просто довелося додати дозвіл
ecr:GetAuthorizationToken
на роль сервера. [ Оновлення ] Щоб отримати якісь - або поштовхи успішно завершені, ви також повинні надати ці дозволи: ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage
. В Amazon є вбудована політика, яка пропонує ці можливості, звані AmazonEC2ContainerRegistryPowerUser
.
- Переконайтесь, що AWS CLI встановлений на майстрі. У моєму налаштуванні, коли майстер працює в контейнері докерів 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 як частина системи Дженкінса.
- На екрані облікових даних знайдіть ключ AWS ECR, натисніть «Додатково» та запишіть його «Ідентифікатор». Для цього прикладу я припускаю, що це "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.