如果 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:
我们正在按照 "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 可用于 tag
和 push
操作。
部分功劳: 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
)
如果 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:
我们正在按照 "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 可用于 tag
和 push
操作。
部分功劳:
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
)