如果 AWS ECR 存储库不存在,则创建它

Create AWS ECR repository if it doesn't exist

如果 AWS ECR 存储库不存在,我该如何创建它?

你可以这样做,但你需要先检查回购协议是否存在。我一起破解了这个 bash 脚本,它满足了我的需要:

#!/bin/bash

aws ecr describe-repositories --repository-names  2>&1 > /dev/null
status=$?
if [[ ! "${status}" -eq 0 ]]; then
    aws ecr create-repository --repository-name 
fi

参数将是一些回购名称。要使其在 CodeBuild 中运行,该作业将需要一个允许其创建 ECR 存储库的 IAM 角色。如果您需要在代码构建作业中获取 AWS CLI 凭证,请查看此 AWS 博客 post:

https://aws.amazon.com/blogs/devops/how-to-create-an-ami-builder-with-aws-codebuild-and-hashicorp-packer/

我们正在按照 "Create a Build Specification" 中的描述使用 JQ 提取 AWS 凭据。

如果您希望在 Jenkins 脚本管道中自动执行此操作,只需使用此代码片段:

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 是:

def output(cmd) {
    sh(script: cmd, returnStdout: true)
}

def status(cmd) {
    sh(script: cmd, returnStatus: true)
}

如果 repo 不存在(或 describe 命令因任何其他原因失败),则创建一个 liner:

aws ecr describe-repositories --repository-names ${REPO_NAME} || aws ecr create-repository --repository-name ${REPO_NAME}

除了有条件地创建 repo 之外,如果您还想提取 repo URI,请考虑这个多行 bash 命令:

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)

回购 URI 可用于 tagpush 操作。


部分功劳: JS

AWS 仅在存储库不存在时创建存储库。 您可以使用
简单地忽略错误和失败 || true 如果存在相同的存储库:

aws ecr create-repository --repository-name <repo_name> || true
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 \\"`

这在 buildspec.yml 文件中起作用,用于始终获取存储库名称并将其存储在 ECR_REPO var 中。如果它已经存在,它将创建回购或静默失败。如果它确实存在,它将获取回购名称,如果不存在,它将静静地失败。

检查ECR库是否存在,可以使用double。首先检查描述存储库(如果不存在)然后创建存储库始终使用有助于审核的标签。

- 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

到目前为止,几乎所有的答案都在调用 describe-repositories,如果出现错误,他们会假设 repo 不存在。 这是错误的,因为还会出现其他类型的错误(无互联网连接、无权限(AccessDeniedException)、错误的回购名称,...)。

这意味着如果 describe-repositories 调用以错误结束,那么我们需要检查错误是否是 RepositoryNotFoundException。只有在那种情况下,我们才应该调用 create-repository.

这就是 bash 代码的样子:

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

逐行解释:

output=$(aws ecr describe-repositories --repository-names ${REPO_NAME} 2>&1) - 这将调用 describe-repositories 并将输出存储到名为 output.

的变量中

if [ $? -ne 0 ]; then - 此行检查最后一个命令 (aws ecs describe-repositories ...) 是否不成功。如果退出代码 ($?) 不是 0 (-ne 0) 那么我们需要检查错误是什么。如果成功则无事可做(成功意味着回购已经存在)。

if echo ${output} | grep -q RepositoryNotFoundException; then - 在这一行中,我们正在检查是否因为回购协议不存在而出现错误。如果是,那么我们需要创建 repo:

aws ecr create-repository --repository-name ${REPO_NAME} - 创建 repo,我们知道它不存在。

else - else 情况意味着 describe-repositories 由于其他原因抛出错误然后不存在回购。

>&2 echo ${output} - 在这种情况下,我们不应该尝试创建 repo,而只是在 stderr 上输出错误 (>&2)