为 ECR 中的所有存储库设置一个生命周期策略

Posted

技术标签:

【中文标题】为 ECR 中的所有存储库设置一个生命周期策略【英文标题】:Set one lifecycle policy for all repositories in ECR 【发布时间】:2018-10-05 17:50:38 【问题描述】:

我想知道是否有一种方法可以设置一个通用的生命周期策略,该策略将应用于 ECR 中的所有存储库?

目前,据我所知,没有办法做到这一点。

我正在考虑的一种方法是使用生命周期策略的 JSON 定义并通过 AWS CLI 将其应用于所有存储库(可以有点自动化)。但是每次创建新的存储库时都应该运行这个东西,这会增加复杂性。

【问题讨论】:

您可以将自定义 aws CLI 脚本与 lambda 调度一起使用。 是的,我提到了那个选项(只是没有 lambda)。主要问题是 AWS 中是否有针对此任务的内置支持? 【参考方案1】:

仍然没有默认的 ECR 生命周期策略模板或其他东西。 因此,正如您所提到的,您可以使用 aws cli 方式,并将其指定为从某个地方执行,例如 Lambda 或 k8s 作业:

    获取所有存储库名称:

    repositories=($(aws ecr describe-repositories --profile=$profile --output text --query "repositories[*].repositoryName"))
    

    将策略应用于每个存储库:

    for repository in "$repositories[@]";
    do
    aws ecr put-lifecycle-policy --profile=$profile --repository-name $repository --lifecycle-policy-text "file://policy.json"
    done;
    

【讨论】:

【参考方案2】:

您可以为此使用 Terraform

resource "aws_ecr_lifecycle_policy" "untagged_removal_policy" 
count      = "$length(split(",",local.registries))"
depends_on = [ "aws_ecr_repository.ecr_repositories" ]
repository = "$aws_ecr_repository.ecr_repositories.*.name[count.index]"

policy = <<EOF

"rules": [
    
        "rulePriority": 1,
        "description": "Expire Docker images older than 7 days",
        "selection": 
            "tagStatus": "untagged",
            "countType": "sinceImagePushed",
            "countUnit": "days",
            "countNumber": 7
        ,
        "action": 
            "type": "expire"
        
    
]

EOF

【讨论】:

【参考方案3】:

我正在使用 CloudFormation 映射来定义一个策略,然后用一行将其应用于所有存储库:

Mappings:
 ECRPolicy:
  DevPolicy:
    RemoveUntagged: |
      
        "rules": [
          
            "rulePriority": 1,
            "description": "Expire images older than 3 days",
            "selection": 
              "tagStatus": "untagged",
              "countType": "sinceImagePushed",
              "countUnit": "days",
              "countNumber": 3
            ,
            "action": 
              "type": "expire"
            
          
        ]
      

而对于 repos,它只是:

  ECRRepository:
   Type: AWS::ECR::Repository
   Properties:
    RepositoryName: !Sub $ECRRepositoryName-dev
    RepositoryPolicyText:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Action:
            - ecr:GetAuthorizationToken
            - ecr:BatchCheckLayerAvailability
            - ecr:GetDownloadUrlForLayer
            - ecr:GetRepositoryPolicy
            - ecr:DescribeRepositories
            - ecr:ListImages
            - ecr:DescribeImages
            - ecr:BatchGetImage
          Principal:
            AWS:
              - !Sub arn:aws:iam::$DevAccount:root
          Sid: AllowCrossAccountPull
    LifecyclePolicy:
      LifecyclePolicyText: !FindInMap [ECRPolicy, DevPolicy, RemoveUntagged]

【讨论】:

【参考方案4】:

使用 Terraform for_each:

locals 
  repositories = toset(["foo", "bar", "baz"])


resource "aws_ecr_repository" "myrepository" 
  for_each = local.repositories
  name = each.value


resource "aws_ecr_lifecycle_policy" "untagged_removal_policy" 
  for_each = local.repositories
  repository = aws_ecr_repository.myrepository[each.value].name

  policy = jsonencode(
  
  "rules": [
    
      "rulePriority": 1,
      "description": "Expire untagged images after 7 days",
      "selection": 
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 7
      ,
      "action": 
        "type": "expire"
      
    
  ])

要输出存储库名称和 URL,请使用 for:

output "myrepositories" 
  value = 
    for repo in aws_ecr_repository.myrepository : repo.name => repo.repository_url
  
  description = "Object mapping from repository name (string) to repository URL (string)"

【讨论】:

【参考方案5】:

AWS DOCS:如何使用 Terraform 为标记和未标记图像实施策略的示例

https://docs.aws.amazon.com/AmazonECR/latest/userguide/lifecycle_policy_examples.html


    "rules": [
        
            "rulePriority": 1,
            "description": "Remove tagged images with prefix prod-*",
            "selection": 
                "tagStatus": "tagged",
                "tagPrefixList": ["prod"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            ,
            "action": 
                "type": "expire"
            
        ,
        
            "rulePriority": 2,
            "description": "Remove untagged images",
            "selection": 
                "tagStatus": "untagged",
                "countType": "imageCountMoreThan",
                "countNumber": 1
            ,
            "action": 
                "type": "expire"
            
        
    ]

【讨论】:

以上是关于为 ECR 中的所有存储库设置一个生命周期策略的主要内容,如果未能解决你的问题,请参考以下文章

ECR 生命周期策略异常

如何将生命周期策略添加到 AWS CDK Typescript 中的现有 S3 存储桶

Pod生命周期和重启策略

使用管道日期索引名称设置 ElasticSearch 索引生命周期策略的问题

ELK 索引生命周期管理

如何修复 GCP CommandException 中的错误:不允许跨越提供程序的“生命周期”命令