Set one lifecycle policy for all repositories in ECR
Asked Answered
C

7

10

I curious if there is a way to set one common lifecycle policy, that will be applied to all repositories in ECR?

Currently, as I understand there is no way to do it.

One approach that I'm thinking about is to use JSON definition of lifecycle policies and apply it to all repositories with AWS CLI (can be a bit automated). But this thing should be run every time as a new repository is created that adds complexity.

Cellobiose answered 25/4, 2018 at 9:49 Comment(2)
You can Use custom aws CLI script with lambda schedule.Bulk
Yes, I mentioned that option (just without lambda). The main question was is there any built-in support in AWS for this task?Cellobiose
S
5

There is still no default ECR Lifecycle policy template or something. So, as you mentioned, you may use aws cli way, and assign this to execute from somewhere, like Lambda, or k8s job:

  1. Get all repositories names:

    repositories=($(aws ecr describe-repositories --profile=$profile --output text --query "repositories[*].repositoryName"))
    
  2. Apply policy to each repository:

    for repository in "${repositories[@]}";
    do
    aws ecr put-lifecycle-policy --profile=$profile --repository-name $repository --lifecycle-policy-text "file://policy.json"
    done;
    
Sterilize answered 7/9, 2020 at 7:54 Comment(0)
A
2

Using 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"
      }
    }
  ]})
}

To output the repository names and URLs, use 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)"
}
Arango answered 29/11, 2021 at 10:10 Comment(0)
H
1

I did this using AWS Lambda and CloudWatch event as the trigger.

This code will apply lifecycle policy to all the existing repositories. And whenever an image is pushed to a newly created repository it will be automatically applied to that repository also.

I have used python and Serverless framework to deploy the code. You can check the complete code here: https://github.com/bharatnainani/ecr-lifecycle

Haletta answered 2/4, 2022 at 10:4 Comment(0)
V
0

you can use Terraform for that

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

}

Vookles answered 8/3, 2019 at 10:29 Comment(0)
S
0

I'm using CloudFormation mapping to define one policy and then apply it on all repositories with one line:

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"
            }
          }
        ]
      }

And for the repos it's just:

  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]
Shorten answered 22/7, 2021 at 22:7 Comment(0)
W
0

I follow this doc to set the same policy for all ECR repos

This script simply lists those repos to a file and set the policy one by one as in JSON file.

I usually set the policy based on count so that count of images is maintained

blog link

create a file policy.json <policy.json>

{
   "rules": [
       {
           "rulePriority": 1,
           "description": "Expire images more than 5",
           "selection": {
               "tagStatus": "any",
               "countType": "imageCountMoreThan",
               
               "countNumber": 5
           },
           "action": {
               "type": "expire"
           }
       }
]}

Note : This Script would list all ECR repo and set the same policy(policy.json). Here I set the image count to 5, So there would be a max of 5 ECR images in the repo.

#!/bin/bash
# An anilaugustinechalissery initiative ;)
read -p "Enter the aws profile name please: " profile
export AWS_PROFILE=$profile
echo "aws profile is "$AWS_PROFILE
aws ecr describe-repositories  --output yaml --query 
'repositories[*].repositoryName[]' | awk '{print $2}' > 
repolist.txt
echo "Repo list "
echo "========================================="
cat repolist.txt 
echo "========================================="
echo "to cancel Ctrl + z in 10s"
sleep 10s
for i in $(cat repolist.txt)
  do
     echo "Setting lifecycle policy for "$i
   aws ecr put-lifecycle-policy --repository-name $i --lifecycle-policy-text "file://policy.json"
  done
Wenona answered 13/9, 2022 at 12:36 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewKling
Y
-2

AWS DOCS : Examples of how to implement policy for tagged and untagged images using 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"
            }
        }
    ]
}
Yseult answered 10/3, 2020 at 21:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.