目前无法强制删除 ECR 存储库。实际上,有一个 问题 请求此功能。
作为解决方法,您可以部署一个基于 Lambda 的自定义资源,在堆栈删除时清空 ECR 存储库。
当您将 Lambda 函数与自定义资源关联时,该函数会在创建、更新或删除自定义资源时被调用。AWS CloudFormation 调用 Lambda API 来调用函数并将所有请求数据(例如请求类型和资源属性)传递给函数。
这是一个最小可重现的示例:
{
"Parameters": {
"ECRRepositoryName": {
"Description": "Name of ECR repository",
"Default": "test-repository",
"Type": "String"
}
},
"Resources": {
"ECRRepository": {
"Type": "AWS::ECR::Repository",
"Properties": {
"RepositoryName": {
"Ref": "ECRRepositoryName"
}
}
},
"LambdaEmptyECRRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "ecr-access-policy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:*"
],
"Resource": "*"
}
]
}
}
]
}
},
"LambdaEmptyECR": {
"Type": "AWS::Lambda::Function",
"DependsOn": "ECRRepository",
"Properties": {
"Code": {
"ZipFile": {
"Fn::Join": [
"\n",
[
"import os",
"import cfnresponse",
"import boto3",
"",
"def lambda_handler(event, context):",
" response = {}",
" if event['RequestType'] == 'Delete':",
" region = event['ResourceProperties']['Region']",
" repository_name = event['ResourceProperties']['ECRRepositoryName']",
" client = boto3.client('ecr', region_name=region)",
" images = client.list_images(repositoryName=repository_name)",
" image_ids = [image for image in images['imageIds']]",
" try:",
" client.batch_delete_image(repositoryName=repository_name, imageIds=image_ids)",
" while client.list_images(repositoryName=repository_name)['imageIds'] != []:",
" os.sleep(1) # wait for images to be deleted",
" response['output'] = 'Successfully deleted images in ECR repository'",
" cfnresponse.send(event, context, cfnresponse.SUCCESS, response)",
" except Exception as e:",
" response['output'] = 'Error'+ e.__str__()",
" cfnresponse.send(event, context, cfnresponse.FAILED, response)",
" cfnresponse.send(event, context, cfnresponse.SUCCESS, response)"
]
]
}
},
"Handler": "index.lambda_handler",
"Role": {
"Fn::GetAtt": [
"LambdaEmptyECRRole",
"Arn"
]
},
"Runtime": "python3.8"
}
},
"EmptyECR": {
"Type": "Custom::LambdaDependency",
"DependsOn": "ECRRepository",
"Properties": {
"ServiceToken": {
"Fn::GetAtt": [
"LambdaEmptyECR",
"Arn"
]
},
"ECRRepositoryName": {
"Ref": "ECRRepositoryName"
},
"Region": {
"Ref": "AWS::Region"
}
}
}
}
}
在堆栈删除时,Lambda函数在删除ECR存储库之前被调用,并删除存储库中包含的所有映像。
有关自定义资源的更多信息:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html
尝试此示例:
- 部署 CloudFormation 模板
- 将任何图像推送到 ECR 存储库
- 删除 CloudFormation 模板