Door Pieter Vogelaar 21 Oktober 2018
Met het gebruik van de Jenkins Docker Pipeline plugin is het eenvoudig om Docker images te bouwen en te pushen.Bijvoorbeeld, bouwen in een Jenkinsfile:
script {
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}", "${args}")
}
En pushen:
script {
docker.withRegistry("${env.DOCKER_PRIVATE_REGISTRY_URL}",
"docker-private-registry-${env.DEPLOY_ENVIRONMENT}") {
dockerImage.push("${env.DOCKER_IMAGE_SHORT_PUSH_TAG}")
}
}
De gebruikersnaam en het wachtwoord voor de Docker registry worden geleverd door de credential ID docker-private-registry-${env.DEPLOY_ENVIRONMENT}. Amazon ECR maakt echter gebruik van tokens die slechts 12 uur geldig zijn. Het wachtwoord dat je opgeeft bij het aanmaken van de credential zal in het bovenstaande voorbeeld dus maar voor een korte periode werken.
Met het volgende script is het eenvoudig om het wachtwoord / token periodiek bij te werken. Het is getest op Jenkins versie 2.138.2.
Installeer de AWS CLI
Zorg ervoor dat je AWS-inloggegevens in $JENKINS_HOME/.aws/credentials staan en de regio in $JENKINS_HOME/.aws/config.
Voorbeeld $JENKINS_HOME/.aws/credentials bestand:
[default]
aws_access_key_id = MyAccessKey2I2JA
aws_secret_access_key = ksdfm3N2o1wnwnsbaqqadummy982
Voorbeeld $JENKINS_HOME/.aws/config bestand:
[default]
region = eu-west-1
Installeer de Groovy plugin
Installeer deze via het Jenkins update center / “Manage Plugins” pagina. De plugin-pagina is te vinden op https://plugins.jenkins.io/groovy.
Maak een freestyle job aan
Job parameters
- CREDENTIAL_ID: Dit is de ID van de gebruikersnaam/wachtwoord credential die in Jenkins is aangemaakt.
- REGION: De AWS regio.
Periodiek bouwen (Build periodically)
Bouw elke 10 uur met de instelling: H H/10 * * *.
System Groovy build stap
// Add the content of this script as inline script of a "Execute system Groovy script" build step.
// That build step also has the option to execute from a script file, but that has too much security restrictions.
// The job must have a job parameter "CREDENTIAL_ID" and "REGION".
import jenkins.model.*
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
def changePassword = { id, new_password ->
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
Jenkins.instance)
def c = creds.findResult { it.id == id ? it : null }
if (c) {
println "Found credential with ID \"${c.id}\""
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, id, c.description, c.username, new_password))
if (result) {
println "Changed password of credential \"${id}\""
} else {
println "Failed to change password of credential \"${id}\""
}
} else {
println "Could not find credential ID \"${id}\""
}
}
// Get job parameters
def credentialId = build.buildVariableResolver.resolve('CREDENTIAL_ID')
def region = build.buildVariableResolver.resolve('REGION')
println "Credential ID \"${credentialId}\""
println "Region \"${region}\""
println "Calling AWS for docker login"
def prs = "/usr/bin/aws ecr get-login --no-include-email --region ${region}".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(credentialId, password)
}
ECR repository aanmaken indien deze niet bestaat
Wanneer een Docker image naar een reguliere Docker registry wordt gepusht, wordt de repository bij de eerste push aangemaakt als deze nog niet bestaat. Bij Amazon ECR is dit niet het geval. Je moet ervoor zorgen dat de repository bestaat voordat je pusht.
Voeg in je Jenkinsfile iets als het volgende toe:
if (env.DOCKER_PRIVATE_REGISTRY_URL.contains('.ecr.')) {
// Docker registry automatically creates a repository on first time push, but Amazon ECR
// requires a separate creation step first
sh "${env.JENKINS_HOME}/custom/aws/ecr-ensure-repository.sh ${env.DOCKER_IMAGE}"
}
De inhoud van ecr-ensure-repository.sh:
#!/usr/bin/env bash
repository_name=$1
if [ -z "$repository_name" ]; then
echo 'Repository name is required as first argument'
exit 1
fi
aws ecr describe-repositories | grep repositoryName | grep "\"$repository_name\"" > /dev/null
exit_code=$?
if [ ${exit_code} -gt 0 ]; then
echo "Repository $repository_name not found, creating..."
aws ecr create-repository --repository-name ${repository_name}
fi
Vogelaar Solutions helpt organisaties met DevOps, platform engineering en web development. Neem contact op voor een vrijblijvend gesprek.