Reputation: 2755
How can I create an AWS ECR repository if it doesn't already exist?
Upvotes: 77
Views: 38168
Reputation: 1270
One liner to create a repo if it doesn't exist (or the describe command fails for any other reason):
aws ecr describe-repositories --repository-names ${REPO_NAME} || aws ecr create-repository --repository-name ${REPO_NAME}
Upvotes: 112
Reputation: 7062
Almost all the answers so far are calling the describe-repositories
and in case of error they assume that repo didn't exists.
This is wrong because there also other kind of errors that can appear (no internet connection, no permission (AccessDeniedException), wrong repo name, ...).
That means if describe-repositories
call ends up with error, then we need to check if the error was RepositoryNotFoundException
. Only in that case we should call the create-repository
.
This is how bash code for this could look like:
output=$(aws ecr describe-repositories --repository-names ${REPO_NAME} 2>&1)
if [ $? -ne 0 ]; then
if echo ${output} | grep -q RepositoryNotFoundException; then
aws ecr create-repository --repository-name ${REPO_NAME}
else
>&2 echo ${output}
fi
fi
Line by line explanation:
output=$(aws ecr describe-repositories --repository-names ${REPO_NAME} 2>&1)
-
This calls the describe-repositories
and stores the output to variable named output
.
if [ $? -ne 0 ]; then
- this line checks if last command (aws ecs describe-repositories ...
) was not successful. If exit code ($?
) was not 0 (-ne 0
) then we need to check what the error was. In case if was successful then there is nothing to do (successful means that repo exists already).
if echo ${output} | grep -q RepositoryNotFoundException; then
- in this line we're checking if error came because repo was not existent. If yes, then we need to create the repo:
aws ecr create-repository --repository-name ${REPO_NAME}
- creating the repo, we know that it didn't exists.
else
- the else case means that describe-repositories
throws error for other reason then not existent repo.
>&2 echo ${output}
- In that case we should not try to create repo but just output error on stderr (>&2
)
Upvotes: 23
Reputation: 111
To check the whether ECR repository exist or not, you can use double. First check the describe the repositories if not exists then create repository always use tags this helps in auditing.
- aws ecr describe-repositories --repository-names ${ECRImage} || aws ecr create-repository --repository-name ${ECRImage} --tags Key=Domain,Value=$Domain Key=AppEnv,Value=$AppEnv Key=ApplicationCI,Value=$ApplicationCI Key=Owner,Value=$Owner Key=Requester,Value=$Requester Key=CostCenter,Value=$CostCenter
Upvotes: 0
Reputation: 1
export ECR_REPO=`aws ecr describe-repositories --repository-names $REPO_NAME 2>/dev/null | jq .repositories[0].repositoryUri | tr -d \\\" && aws ecr create-repository --repository-name $REPO_NAME --region us-east-1 2>/dev/null | jq .repository.repositoryUri | tr -d \\\"`
This works in a buildspec.yml file for always grabbing the repo name and storing it in the ECR_REPO var. It will create the repo or fail silently if it already exists. It will grab the repo name if it does exist or fail silently if it does not.
Upvotes: 0
Reputation: 6796
AWS makes the repository only if it doesn't exist.
You can simply ignore the error & failure with
|| true
in case if same repository exists:
aws ecr create-repository --repository-name <repo_name> || true
Upvotes: 23
Reputation: 63332
In addition to conditionally creating the repo, if you also want to extract the repo URI, consider this multiline bash command:
REPO_URI=$(aws ecr describe-repositories --repository-names "${REPO_NAME}" --query "repositories[0].repositoryUri" --output text 2>/dev/null || \
aws ecr create-repository --repository-name "${REPO_NAME}" --query "repository.repositoryUri" --output text)
The repo URI can be useful for the tag
and push
operations.
Partial credit: answer by JS
Upvotes: 1
Reputation: 111
If you want this to be automated in Jenkins scripted pipeline, just use this code-snippet:
def ensureRegistry(accountId, region, repoName) {
Logger log = new Logger(this)
def accId = shell.output("aws --region ${region} ecr describe-repositories --repository-names \"${repoName}\" | jq .repositories[].registryId | tr -d '\"'")
if (accId == accountId) {
log.info("Docker repository ${repoName} exists for account ${accId}")
} else {
log.info("Docker repository ${repoName} doesn't exist for account ${accId}")
shell.status("aws --region ${region} ecr create-repository --repository-name \"${repoName}\"")
log.info("Docker repository ${repoName} was just created for account ${accId}")
}
}
shell.groovy
is:
def output(cmd) {
sh(script: cmd, returnStdout: true)
}
def status(cmd) {
sh(script: cmd, returnStatus: true)
}
Upvotes: 2
Reputation: 1725
You can do this, but you need to check if the repo exists first. I hacked this bash script together and it does what I need:
#!/bin/bash
aws ecr describe-repositories --repository-names $1 2>&1 > /dev/null
status=$?
if [[ ! "${status}" -eq 0 ]]; then
aws ecr create-repository --repository-name $1
fi
The argument would be some repo name. For this to work in CodeBuild, the job will need an IAM role that permits it to create an ECR repo. If you need to get AWS CLI credentials into your code build job, have a look at this AWS Blog post:
We're doing exactly what is described in the "Create a Build Specification" to use JQ to extract AWS credentials.
Upvotes: 6