

# Automate the cleanup of images by using lifecycle policies in Amazon ECR
<a name="LifecyclePolicies"></a>

Amazon ECR lifecycle policies provide more control over the lifecycle management of images in a private repository. A lifecycle policy contains one or more rules, and each rule defines an action for Amazon ECR. Based on the expiration criteria in the lifecycle policy, images can be archived or expired based on the criteria specified in the lifecycle policy within 24 hours. When Amazon ECR performs an action based on a lifecycle policy, this action is captured as an event in AWS CloudTrail. For more information, see [Logging Amazon ECR actions with AWS CloudTrail](logging-using-cloudtrail.md).

## How lifecycle policies work
<a name="lifecycle-policy-howitworks"></a>

A lifecycle policy consists of one or more rules that determine which images in a repository should be expired. When considering the use of lifecycle policies, it's important to use the lifecycle policy preview to confirm which images the lifecycle policy expires before applying it to a repository. Once a lifecycle policy is applied to a repository, you should expect that images become expired within 24 hours after they meet the expiration criteria. When Amazon ECR performs an action based on a lifecycle policy, this is captured as an event in AWS CloudTrail. For more information, see [Logging Amazon ECR actions with AWS CloudTrail](logging-using-cloudtrail.md).

The following diagram shows the lifecycle policy workflow.

![\[Diagram showing the process for evaluating and applying a lifecycle policy.\]](http://docs.aws.amazon.com/AmazonECR/latest/userguide/images/lifecycle-policy.png)


1. Create one or more test rules.

1. Save the test rules and run the preview.

1. The lifecycle policy evaluator goes through all of the rules and marks the images that each rule affects.

1. The lifecycle policy evaluator then applies the rules, based on rule priority, and displays which images in the repository are set to be expired or archived. A lower rule priority number means higher priority. For example, a rule with priority 1 takes precedence over a rule with priority 2.

1. Review the results of the test, ensuring that the images that are marked to be expired or archived are what you intended.

1. Apply the test rules as the lifecycle policy for the repository.

1. Once the lifecycle policy is created, you should expect that images are expired or archived within 24 hours after they meet the expiration criteria.

### Lifecycle policy evaluation rules
<a name="lp_evaluation_rules"></a>

The lifecycle policy evaluator is responsible for parsing the plaintext JSON of the lifecycle policy, evaluating all rules, and then applying those rules based on rule priority to the images in the repository. The following explains the logic of the lifecycle policy evaluator in more detail. For examples, see [Examples of lifecycle policies in Amazon ECR](lifecycle_policy_examples.md).
+ When reference artifacts are present in a repository, Amazon ECR lifecycle policies automatically expire or archive those artifacts within 24 hours of the deletion or archival of the subject image.
+ All rules are evaluated at the same time, regardless of rule priority. After all rules are evaluated, they are then applied based on rule priority.
+ An image is expired or archived by exactly one or zero rules.
+ An image that matches the tagging requirements of a rule cannot be expired or archived by a rule with a lower priority.
+ Rules can never mark images that are marked by higher priority rules, but can still identify them as if they haven't been expired or archived.
+ The set of all rules selecting a specific storage class must contain a unique set of prefixes.
+ Only one rule selecting a specific storage class is allowed to select untagged images.
+ If an image is referenced by a manifest list, it cannot be expired or archived without the manifest list being deleted or archived first.
+ Expiration is always ordered by `pushed_at_time` or `transitioned_at_time` and always expires older images before newer ones. If an image was archived and then restored at any point in the past, the image's `last_activated_at` is used instead of `pushed_at_time`.
+ A lifecycle policy rule may specify either `tagPatternList` or `tagPrefixList`, but not both. However, a lifecycle policy may contain multiple rules where different rules use both pattern and prefix lists. An image is successfully matched if all of the tags in the `tagPatternList` or `tagPrefixList` value are matched against any of the image's tags. 
+ The `tagPatternList` or `tagPrefixList` parameters may only used if the `tagStatus` is `tagged`.
+ When using `tagPatternList`, an image is successfully matched if it matches the wildcard filter. For example, if a filter of `prod*` is applied, it would match image-tags whose name begins with `prod` such as `prod`, `prod1`, or `production-team1`. Similarly, if a filter of `*prod*` is applied, it would match image-tags whose name contains `prod` such as `repo-production` or `prod-team`.
**Important**  
There is a maximum limit of four wildcards (`*`) per string. For example, `["*test*1*2*3", "test*1*2*3*"]` is valid but `["test*1*2*3*4*5*6"]` is invalid.
+ When using `tagPrefixList`, an image is successfully matched if ***all*** of the wildcard filters in the `tagPrefixList` value are matched against any of the image's tags.
+ The `countUnit` parameter is only used if `countType` is `sinceImagePushed`, `sinceImagePulled`, or `sinceImageTransitioned`.
+ With `countType = imageCountMoreThan`, images are sorted from youngest to oldest based on `pushed_at_time` and then all images greater than the specified count are expired or archived.
+ With `countType = sinceImagePushed`, all images whose `pushed_at_time` is older than the specified number of days based on `countNumber` are expired or archived.
+ With `countType = sinceImagePulled`, all images whose `last_recorded_pulltime` is older than the specified number of days based on `countNumber` are archived. If an image was never pulled, the image's `pushed_at_time` is used instead of the `last_recorded_pulltime`. If an image was archived and then restored at any point in the past, but never pulled since the image was restored, the image's `last_activated_at` is used instead of the `last_recorded_pulltime`.
+ With `countType = sinceImageTransitioned`, all archived images whose `last_archived_at` is older than the specified number of days based on `countNumber` are expired.
+ Expiration is always ordered by `pushed_at_time` and always expires older images before newer ones.

# Creating a lifecycle policy preview in Amazon ECR
<a name="lpp_creation"></a>

You can use a lifecycle policy preview to see the impact of a lifecycle policy on an image repository before you apply it. It is considered best practice to do a preview before applying a lifecycle policy to a repository.

**Note**  
If you are using Amazon ECR replication to make copies of a repository across different Regions or accounts, note that a lifecycle policy can only take an action on repositories in the Region it was created in. Therefore, if you have replication turned on you may want to create a lifecycle policy in each Region and account you are replicating your repositories to.

**To create a lifecycle policy preview (AWS Management Console)**

1. Open the Amazon ECR console at [https://console.aws.amazon.com/ecr/repositories](https://console.aws.amazon.com/ecr/repositories).

1. From the navigation bar, choose the Region that contains the repository on which to perform a lifecycle policy preview.

1. In the navigation pane, under **Private registry**, choose **Repositories**.

1. On the **Private repositories** page, select a repository and that use the **Actions** drop down to choose **Lifecycle policies**.

1. On the lifecycle policy rules page for the repository, choose **Edit test rules**, **Create rule**.

1. Specify the following details for each test lifecycle policy rule.

   1. For **Rule priority**, type a number for the rule priority. The rule priority determines in what order the lifecycle policy rules are applied. A lower number means higher priority. For example, a rule with priority 1 takes precedence over a rule with priority 2.

   1. For **Rule description**, type a description for the lifecycle policy rule.

   1. For **Image status**, choose **Tagged (wildcard matching)**, **Tagged (prefix matching)**, **Untagged**, or **Any**.
**Important**  
If you specify multiple tags, only the images with all specified tags are selected.

   1. If you chose **Tagged (wildcard matching)** for **Image status**, then for **Specify tags for wildcard matching**, you can specify a list of image tags with a wildcard (**\$1**) on which to take action with your lifecycle policy. For example, if your images are tagged as `prod`, `prod1`, `prod2`, and so on, you would specify `prod*` to take action on all of them. If you specify multiple tags, only the images with all specified tags are selected.
**Important**  
There is a maximum limit of four wildcards (`*`) per string. For example, `["*test*1*2*3", "test*1*2*3*"]` is valid but `["test*1*2*3*4*5*6"]` is invalid.

   1. If you chose **Tagged (prefix matching)** for **Image status**, then for **Specify tags for prefix matching**, you can specify a list of image tags on which to take action with your lifecycle policy.

   1. For **Match criteria**, choose **Days since image created**, **Days since last recorded pull time**, **Days since image archived**, or **Image count** and then specify a value.

   1. For **Rule action**, choose either **Expire** or **Archive**.

   1. Choose **Save**.

1. Create additional test lifecycle policy rules by repeating steps 5–7.

1. To run the lifecycle policy preview, choose **Save and run test**.

1. Under **Image matches for test lifecycle rules**, review the impact of your lifecycle policy preview.

1. If you are satisfied with the preview results, choose **Apply as lifecycle policy** to create a lifecycle policy with the specified rules. You should expect that after applying a lifecycle policy, the affected images are expired or archived within 24 hours.

1. If you aren't satisfied with the preview results, you may delete one or more test lifecycle rules and create one or more rules to replace them and then repeat the test.

# Creating a lifecycle policy for a repository in Amazon ECR
<a name="lp_creation"></a>

 Use a lifecycle policy to create a set of rules that expire or archive unused repository images. After creating a lifecycle policy, the affected images are expired or archived within 24 hours.

**Note**  
If you are using Amazon ECR replication to make copies of a repository across different Regions or accounts, note that a lifecycle policy can only take an action on repositories in the Region it was created in. Therefore, if you have replication turned on you may want to create a lifecycle policy in each Region and account you are replicating your repositories to.

## Prerequisite
<a name="lp-creation-prerequisite"></a>

**Best practice:** Create a lifecycle policy preview to verify that the images expired or archived by your lifecycle policy rules are what you intend. For instructions, see [Creating a lifecycle policy preview in Amazon ECR](lpp_creation.md).

## To create a lifecycle policy (AWS Management Console)
<a name="lp-creation-console"></a>

1. Open the Amazon ECR console at [https://console.aws.amazon.com/ecr/repositories](https://console.aws.amazon.com/ecr/repositories).

1. From the navigation bar, choose the Region that contains the repository for which to create a lifecycle policy.

1. In the navigation pane, under **Private registry**, choose **Repositories**.

1. On the **Private repositories** page, select a repository and that use the **Actions** drop down to choose **Lifecycle policies**.

1. On the lifecycle policy rules page for the repository, choose **Create rule**.

1. Enter the following details for your lifecycle policy rule.

   1. For **Rule priority**, type a number for the rule priority. The rule priority determines in what order the lifecycle policy rules are applied. A lower rule priority number means higher priority. For example, a rule with priority 1 takes precedence over a rule with priority 2.

   1. For **Rule description**, type a description for the lifecycle policy rule.

   1. For **Image status**, choose **Tagged (wildcard matching)**, **Tagged (prefix matching)**, **Untagged**, or **Any**.
**Important**  
If you specify multiple tags, only the images with all specified tags are selected.

   1. If you chose **Tagged (wildcard matching)** for **Image status**, then for **Specify tags for wildcard matching**, you can specify a list of image tags with a wildcard (**\$1**) on which to take action with your lifecycle policy. For example, if your images are tagged as `prod`, `prod1`, `prod2`, and so on, you would specify `prod*` to take action on all of them. If you specify multiple tags, only the images with all specified tags are selected.
**Important**  
There is a maximum limit of four wildcards (`*`) per string. For example, `["*test*1*2*3", "test*1*2*3*"]` is valid but `["test*1*2*3*4*5*6"]` is invalid.

   1. If you chose **Tagged (prefix matching)**for **Image status**, then for **Specify tags for prefix matching**, you can specify a list of image tags on which to take action with your lifecycle policy.

   1. For **Match criteria**, choose **Days since image created**, **Days since last recorded pull time**, **Days since image archived**, or **Image count** and then specify a value.

   1. For **Rule action**, choose either **Expire** or **Archive**.

   1. Choose **Save**.

1. Create additional lifecycle policy rules by repeating steps 5–7.

## To create a lifecycle policy (AWS CLI)
<a name="lp-creation-cli"></a>

1. Obtain the name of the repository for which to create the lifecycle policy.

   ```
   aws ecr describe-repositories
   ```

1. Create a local file named `policy.json` with the contents of the lifecycle policy. For lifecycle policy examples, see [Examples of lifecycle policies in Amazon ECR](lifecycle_policy_examples.md).

1. Create a lifecycle policy by specifying the repository name and reference the lifecycle policy JSON file you created.

   ```
   aws ecr put-lifecycle-policy \
         --repository-name repository-name \
         --lifecycle-policy-text file://policy.json
   ```

# Examples of lifecycle policies in Amazon ECR
<a name="lifecycle_policy_examples"></a>

The following are example lifecycle policies showing the syntax.

To see more information about policy properties, see [Lifecycle policy properties in Amazon ECR](lifecycle_policy_parameters.md). For instructions about creating a lifecycle policy by using the AWS CLI, see [To create a lifecycle policy (AWS CLI)](lp_creation.md#lp-creation-cli).

## Lifecycle policy template
<a name="lifecycle_policy_syntax"></a>

The contents of your lifecycle policy are evaluated before being associated with a repository. The following is the JSON syntax template for the lifecycle policy.

```
{
        "rules": [
            {
                "rulePriority": integer,
                "description": "string",
                "selection": {
                    "tagStatus": "tagged"|"untagged"|"any",
                    "tagPatternList": list<string>,
                    "tagPrefixList": list<string>,
                    "storageClass": "standard"|"archive",
                    "countType": "imageCountMoreThan"|"sinceImagePushed"|"sinceImagePulled"|"sinceImageTransitioned",
                    "countUnit": "string",
                    "countNumber": integer
                },
                "action": {
                    "type": "expire"|"transition",
                    "targetStorageClass": "archive"
                }
            }
        ]
    }
```

## Filtering on image age
<a name="lifecycle_policy_example_age"></a>

The following example shows the lifecycle policy syntax for a policy that expires images with a tag starting with `prod` by using a `tagPatternList` of `prod*` that are also older than `14` days.

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Expire images older than 14 days",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["prod*"],
                "countType": "sinceImagePushed",
                "countUnit": "days",
                "countNumber": 14
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

## Filtering on last pulled time
<a name="lifecycle_policy_example_last_pulled"></a>

The following example shows the lifecycle policy syntax for a policy that transitions images to archive storage that haven't been pulled in `90` days.

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Archive images not pulled in 90 days",
            "selection": {
                "tagStatus": "any",
                "countType": "sinceImagePulled",
                "countUnit": "days",
                "countNumber": 90
            },
            "action": {
                "type": "transition",
                "targetStorageClass": "archive"
            }
        }
    ]
}
```

**Important**  
The `sinceImagePulled` count type must be used with the `transition` action. It cannot be used with the `expire` action. To delete images based on pull activity, first transition them to archive storage using `sinceImagePulled`, then use `sinceImageTransitioned` with an `expire` action to delete them. Images must be in archive storage for a minimum of 90 days before deletion.

## Filtering on archive transition time
<a name="lifecycle_policy_example_transitioned"></a>

The following example shows the lifecycle policy syntax for a policy that expires archived images that have been in archive storage for more than `365` days.

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Expire images archived for more than 365 days",
            "selection": {
                "tagStatus": "any",
                "storageClass": "archive",
                "countType": "sinceImageTransitioned",
                "countUnit": "days",
                "countNumber": 365
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

**Important**  
The `sinceImageTransitioned` count type must be used with the `expire` action and the `archive` storage class. Images must be in archive storage for a minimum of 90 days before deletion.

## Filtering on image count
<a name="lifecycle_policy_example_number"></a>

The following example shows the lifecycle policy syntax for a policy that keeps only one untagged image and expires all others.

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Keep only one untagged image, expire all others",
            "selection": {
                "tagStatus": "untagged",
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

## Filtering on multiple rules
<a name="lp_example_multiple"></a>

The following examples use multiple rules in a lifecycle policy. An example repository and lifecycle policy are given along with an explanation of the outcome.

### Example A
<a name="lp_example_multiple_a"></a>

Repository contents:
+ Image A, Taglist: ["beta-1", "prod-1"], Pushed: 10 days ago
+ Image B, Taglist: ["beta-2", "prod-2"], Pushed: 9 days ago
+ Image C, Taglist: ["beta-3"], Pushed: 8 days ago

Lifecycle policy text:

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Rule 1",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["prod*"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        },
        {
            "rulePriority": 2,
            "description": "Rule 2",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["beta*"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

The logic of this lifecycle policy would be:
+ Rule 1 identifies images tagged with prefix `prod`. It should mark images, starting with the oldest, until there is one or fewer images remaining that match. It marks Image A for expiration.
+ Rule 2 identifies images tagged with prefix `beta`. It should mark images, starting with the oldest, until there is one or fewer images remaining that match. It marks both Image A and Image B for expiration. However, Image A has already been seen by Rule 1 and if Image B were expired it would violate Rule 1 and thus is skipped.
+ Result: Image A is expired.

### Example B
<a name="lp_example_multiple_b"></a>

This is the same repository as the previous example but the rule priority order is changed to illustrate the outcome.

Repository contents:
+ Image A, Taglist: ["beta-1", "prod-1"], Pushed: 10 days ago
+ Image B, Taglist: ["beta-2", "prod-2"], Pushed: 9 days ago
+ Image C, Taglist: ["beta-3"], Pushed: 8 days ago

Lifecycle policy text:

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Rule 1",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["beta*"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        },
        {
            "rulePriority": 2,
            "description": "Rule 2",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["prod*"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

The logic of this lifecycle policy would be:
+ Rule 1 identifies images tagged with prefix `beta`. It should mark images, starting with the oldest, until there is one or fewer images remaining that match. It sees all three images and would mark Image A and Image B for expiration.
+ Rule 2 identifies images tagged with prefix `prod`. It should mark images, starting with the oldest, until there is one or fewer images remaining that match. It would see no images because all available images were already seen by Rule 1 and thus would mark no additional images.
+ Result: Images A and B are expired.

## Filtering on multiple tags in a single rule
<a name="lp_example_difftype"></a>

The following examples specify the lifecycle policy syntax for multiple tag patterns in a single rule. An example repository and lifecycle policy are given along with an explanation of the outcome.

### Example A
<a name="lp_example_difftype_a"></a>

When multiple tag patterns are specified on a single rule, images must match all listed tag patterns.

Repository contents:
+ Image A, Taglist: ["alpha-1"], Pushed: 12 days ago
+ Image B, Taglist: ["beta-1"], Pushed: 11 days ago
+ Image C, Taglist: ["alpha-2", "beta-2"], Pushed: 10 days ago
+ Image D, Taglist: ["alpha-3"], Pushed: 4 days ago
+ Image E, Taglist: ["beta-3"], Pushed: 3 days ago
+ Image F, Taglist: ["alpha-4", "beta-4"], Pushed: 2 days ago

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Rule 1",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["alpha*", "beta*"],
                "countType": "sinceImagePushed",
                "countNumber": 5,
                "countUnit": "days"
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

The logic of this lifecycle policy would be:
+ Rule 1 identifies images tagged with prefix `alpha` and `beta`. It sees images C and F. It should mark images that are older than five days, which would be Image C.
+ Result: Image C is expired.

### Example B
<a name="lp_example_difftype_b"></a>

The following example illustrates that tags are not exclusive.

Repository contents:
+ Image A, Taglist: ["alpha-1", "beta-1", "gamma-1"], Pushed: 10 days ago
+ Image B, Taglist: ["alpha-2", "beta-2"], Pushed: 9 days ago
+ Image C, Taglist: ["alpha-3", "beta-3", "gamma-2"], Pushed: 8 days ago

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Rule 1",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["alpha*", "beta*"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

The logic of this lifecycle policy would be:
+ Rule 1 identifies images tagged with prefix `alpha` and `beta`. It sees all images. It should mark images, starting with the oldest, until there is one or fewer images remaining that match. It marks image A and B for expiration.
+ Result: Images A and B are expired.

## Filtering on all images
<a name="lp_example_allimages"></a>

The following lifecycle policy examples specify all images with different filters. An example repository and lifecycle policy are given along with an explanation of the outcome.

### Example A
<a name="lp_example_difftype_a"></a>

The following shows the lifecycle policy syntax for a policy that applies to all rules but keeps only one image and expires all others.

Repository contents:
+ Image A, Taglist: ["alpha-1"], Pushed: 4 days ago
+ Image B, Taglist: ["beta-1"], Pushed: 3 days ago
+ Image C, Taglist: [], Pushed: 2 days ago
+ Image D, Taglist: ["alpha-2"], Pushed: 1 day ago

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Rule 1",
            "selection": {
                "tagStatus": "any",
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

The logic of this lifecycle policy would be:
+ Rule 1 identifies all images. It sees images A, B, C, and D. It should expire all images other than the newest one. It marks images A, B, and C for expiration.
+ Result: Images A, B, and C are expired.

### Example B
<a name="lp_example_difftype_b"></a>

The following example illustrates a lifecycle policy that combines all the rule types in a single policy.

Repository contents:
+ Image A, Taglist: ["alpha-1", "beta-1"], Pushed: 4 days ago
+ Image B, Taglist: [], Pushed: 3 days ago
+ Image C, Taglist: ["alpha-2"], Pushed: 2 days ago
+ Image D, Taglist: ["git hash"], Pushed: 1 day ago
+ Image E, Taglist: [], Pushed: 1 day ago

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Rule 1",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["alpha*"],
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        },
        {
            "rulePriority": 2,
            "description": "Rule 2",
            "selection": {
                "tagStatus": "untagged",
                "countType": "sinceImagePushed",
                "countUnit": "days",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        },
        {
            "rulePriority": 3,
            "description": "Rule 3",
            "selection": {
                "tagStatus": "any",
                "countType": "imageCountMoreThan",
                "countNumber": 1
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

The logic of this lifecycle policy would be:
+ Rule 1 identifies images tagged with prefix `alpha`. It identifies images A and C. It should keep the newest image and mark the rest for expiration. It marks image A for expiration.
+ Rule 2 identifies untagged images. It identifies images B and E. It should mark all images older than one day for expiration. It marks image B for expiration.
+ Rule 3 identifies all images. It identifies images A, B, C, D, and E. It should keep the newest image and mark the rest for expiration. However, it can't mark images A, B, C, or E because they were identified by higher priority rules. It marks image D for expiration. 
+ Result: Images A, B, and D are expired.

## Archive examples
<a name="lp_example_archive"></a>

The following examples show lifecycle policies that archive images instead of deleting them.

### Archiving images older than a specified number of days
<a name="lp_example_archive_age"></a>

The following example shows a lifecycle policy that archives images with tags starting with `prod` that are older than 30 days:

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Archive production images older than 30 days",
            "selection": {
                "tagStatus": "tagged",
                "tagPatternList": ["prod*"],
                "countType": "sinceImagePushed",
                "countUnit": "days",
                "countNumber": 30
            },
            "action": {
                "type": "transition",
                "targetStorageClass": "archive"
            }
        }
    ]
}
```

### Archiving images not pulled in a specified number of days
<a name="lp_example_archive_pull"></a>

The following example shows a lifecycle policy that archives images that haven't been pulled in 90 days:

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Archive images not pulled in 90 days",
            "selection": {
                "tagStatus": "any",
                "countType": "sinceImagePulled",
                "countUnit": "days",
                "countNumber": 90
            },
            "action": {
                "type": "transition",
                "targetStorageClass": "archive"
            }
        }
    ]
}
```

### Combining archive and expire rules
<a name="lp_example_archive_delete"></a>

The following example shows a lifecycle policy that archives images older than 30 days and then permanently expires images that have been archived for more than 365 days:

**Note**  
Archived images have a minimum storage duration of 90 days. You cannot configure lifecycle policies that delete images that have been in archive for less than 90 days. If you must delete images that have been archived for less than 90 days, you need to use the **batch-delete-image** API, but you will be charged for the 90-day minimum storage duration.

```
{
    "rules": [
        {
            "rulePriority": 1,
            "description": "Archive images older than 30 days",
            "selection": {
                "tagStatus": "any",
                "countType": "sinceImagePushed",
                "countUnit": "days",
                "countNumber": 30
            },
            "action": {
                "type": "transition",
                "targetStorageClass": "archive"
            }
        },
        {
            "rulePriority": 2,
            "description": "Expire images archived for more than 365 days",
            "selection": {
                "tagStatus": "any",
                "storageClass": "archive",
                "countType": "sinceImageTransitioned",
                "countUnit": "days",
                "countNumber": 365
            },
            "action": {
                "type": "expire"
            }
        }
    ]
}
```

# Lifecycle policy properties in Amazon ECR
<a name="lifecycle_policy_parameters"></a>

Lifecycle policies have the following properties. 

To see examples of lifecycle policies, see [Examples of lifecycle policies in Amazon ECR](lifecycle_policy_examples.md). For instructions about creating a lifecycle policy by using the AWS CLI, see [To create a lifecycle policy (AWS CLI)](lp_creation.md#lp-creation-cli).

## Rule priority
<a name="lp_rule_priority"></a>

`rulePriority`  
Type: integer  
Required: yes  
Sets the order in which rules are applied, lowest to highest. A lifecycle policy rule with a priority of `1` is applied first, a rule with priority of `2` is next, and so on. When you add rules to a lifecycle policy, you must give them each a unique value for `rulePriority`. Values don't need to be sequential across rules in a policy. A rule with a `tagStatus` value of `any` must have the highest value for `rulePriority` and be evaluated last.

## Description
<a name="lp_description"></a>

`description`  
Type: string  
Required: no  
(Optional) Describes the purpose of a rule within a lifecycle policy.

## Tag status
<a name="lp_tag_status"></a>

`tagStatus`  
Type: string  
Required: yes  
Determines whether the lifecycle policy rule that you are adding specifies a tag for an image. Acceptable options are `tagged`, `untagged`, or `any`. If you specify `any`, then all images have the rule evaluated against them. If you specify `tagged`, then you must also specify a `tagPrefixList` value or a `tagPatternList` value. If you specify `untagged`, then you must omit both `tagPrefixList` and `tagPatternList`.

## Tag pattern list
<a name="lp_tag_pattern_list"></a>

`tagPatternList`  
Type: list[string]  
Required: yes, if `tagStatus` is set to tagged and `tagPrefixList` isn't specified  
When creating a lifecycle policy for tagged images, it's best practice to use a `tagPatternList` to specify the tags to expire. You specify a comma-separated list of image tag patterns that may contain wildcards (`*`) on which to take action with your lifecycle policy. For example, if your images are tagged as `prod`, `prod1`, `prod2`, and so on, you would use the tag pattern list `prod*` to specify all of them. If you specify multiple tags, only the images with all specified tags are selected.  
There is a maximum limit of four wildcards (`*`) per string. For example, `["*test*1*2*3", "test*1*2*3*"]` is valid but `["test*1*2*3*4*5*6"]` is invalid.

## Tag prefix list
<a name="lp_tag_prefix_list"></a>

`tagPrefixList`  
Type: list[string]  
Required: yes, if `tagStatus` is set to tagged and `tagPatternList` isn't specified  
Only used if you specified `"tagStatus": "tagged"` and you aren't specifying a `tagPatternList`. You must specify a comma-separated list of image tag prefixes on which to take action with your lifecycle policy. For example, if your images are tagged as `prod`, `prod1`, `prod2`, and so on, you would use the tag prefix `prod` to specify all of them. If you specify multiple tags, only the images with all specified tags are selected.

## Storage class
<a name="lp_storage_class"></a>

`storageClass`  
Type: string  
Required: yes, if `countType` is `sinceImageTransitioned`  
The rule will only select images of this storage class. When using a `countType` of `imageCountMoreThan`, `sinceImagePushed`, or `sinceImagePulled`, the only supported value is `standard`. When using a count type of `sinceImageTransitioned`, this is required, and the only supported value is `archive`. If you omit this, the value of `standard` will be used.

## Count type
<a name="lp_count_type"></a>

`countType`  
Type: string  
Required: yes  
Specify a count type to apply to the images.   
If `countType` is set to `imageCountMoreThan`, you also specify `countNumber` to create a rule that sets a limit on the number of images that exist in your repository. If `countType` is set to `sinceImagePushed`, `sinceImagePulled`, or `sinceImageTransitioned`, you also specify `countUnit` and `countNumber` to specify a time limit on the images that exist in your repository.

## Count unit
<a name="lp_count_unit"></a>

`countUnit`  
Type: string  
Required: yes, only if `countType` is set to `sinceImagePushed`, `sinceImagePulled`, or `sinceImageTransitioned`  
Specify a count unit of `days` to indicate that as the unit of time, in addition to `countNumber`, which is the number of days.   
This should only be specified when `countType` is `sinceImagePushed`, `sinceImagePulled`, or `sinceImageTransitioned`; an error will occur if you specify a count unit when `countType` is any other value.

## Count number
<a name="lp_count_number"></a>

`countNumber`  
Type: integer  
Required: yes  
Specify a count number. Acceptable values are positive integers (`0` is not an accepted value).   
If the `countType` used is `imageCountMoreThan`, then the value is the maximum number of images that you want to retain in your repository. If the `countType` used is `sinceImagePushed`, then the value is the maximum age limit for your images. If the `countType` used is `sinceImagePulled`, then the value is the maximum number of days since the image was last pulled. If the `countType` used is `sinceImageTransitioned`, then the value is the maximum number of days since the image was archived.

## Action
<a name="lp_action"></a>

`type`  
Type: string  
Required: yes  
Specify an action type. The supported values are `expire` (to delete images) and `transition` (to move images to archive storage).

`targetStorageClass`  
Type: string  
Required: yes, if `type` is `transition`  
The storage class you want the lifecycle policy to transition the image to. `archive` is the only supported value.