@Connor McCarthyが言ったように、Amazonがより永続的なキーのためのより良いソリューションを考え出すのを待つ間、当面はJenkinsサーバーでキーを生成する必要があります。
私の解決策は、Groovy APIを使用して、12時間ごとにECRのJenkins資格情報を自動的に更新する定期的なジョブを持つことです。これはこの非常に詳細な回答に基づいていますが、いくつか異なることを行い、スクリプトを変更する必要がありました。
手順:
- Jenkinsマスターが必要なAWS APIにアクセスできることを確認してください。私のセットアップでは、JenkinsマスターはIAMロールを持つEC2で実行されている
ecr:GetAuthorizationToken
ため、サーバーロールに権限を追加する必要がありました。[ 更新 ]プッシュを正常に完了するには、次の権限も付与する必要がありますecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability, ecr:PutImage
。Amazonには、と呼ばれるこれらの機能を提供する組み込みポリシーがありますAmazonEC2ContainerRegistryPowerUser
。
- AWS CLIがマスターにインストールされていることを確認してください。私のセットアップでは、マスターがdebian dockerコンテナーで実行されているので、このシェルビルドステップをキー生成ジョブに追加しました。
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
- Jenkinsシステムの一部としてGroovyスクリプトを実行できるGroovyプラグインをインストールします。
- 認証情報画面で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」の複数の資格情報がある場合は、スクリプトに基づいて資格情報を見つけるようにスクリプトを更新する必要があります。説明フィールドか何か。
- クレデンシャルのAPIは、クレデンシャルオブジェクトを単に更新するのではなく、新しいオブジェクトで置き換え、実際のECRキーの実際のIDをスクリプトで使用する必要があります。Dockerビルドステップとキーの間のバインディングはIDによるものです。
null
ID の値を使用すると(前にリンクした回答のように)、新しいIDが作成され、Dockerビルドステップでの資格情報の設定が失われます。
これで完了です。スクリプトは12時間ごとに実行でき、ECR資格情報を更新できます。Dockerプラグインを引き続き使用できます。