Terraform module to create AWS ECR (Elastic Container Registry) which is a fully-managed Docker container registry.
You can use this module to create an ECR registry using few parameters (simple example) or define in detail every aspect of the registry (complete example).
Check the examples for the simple and the complete snippets.
This example creates an ECR registry using few parameters
module "ecr" {
source = "lgallard/ecr/aws"
name = "ecr-repo-dev"
# Tags
tags = {
Owner = "DevOps team"
Environment = "dev"
Terraform = true
}
}
In this example, the registry is defined in detail including CloudWatch logging:
module "ecr" {
source = "lgallard/ecr/aws"
name = "ecr-repo-dev"
scan_on_push = true
timeouts_delete = "60m"
image_tag_mutability = "IMMUTABLE"
encryption_type = "KMS"
# Enable CloudWatch logging
enable_logging = true
log_retention_days = 14
// ...rest of configuration...
}
The module supports sending ECR API actions and image push/pull events to CloudWatch Logs. When enabled:
- Creates a CloudWatch Log Group
/aws/ecr/{repository-name}
- Sets up necessary IAM roles and policies for ECR to write logs
- Configurable log retention period (default: 30 days)
To enable logging:
module "ecr" {
source = "lgallard/ecr/aws"
name = "ecr-repo-dev"
enable_logging = true
# Optional: customize retention period (in days)
log_retention_days = 14 # Valid values: 0,1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1827,3653
}
The module outputs logging-related ARNs:
cloudwatch_log_group_arn
- The ARN of the CloudWatch Log Grouplogging_role_arn
- The ARN of the IAM role used for logging
In this example the register is defined in detailed.
module "ecr" {
source = "lgallard/ecr/aws"
name = "ecr-repo-dev"
scan_on_push = true
timeouts_delete = "60m"
image_tag_mutability = "MUTABLE"
prevent_destroy = true # Protect repository from accidental deletion
# Note that currently only one policy may be applied to a repository.
policy = <<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "repo policy",
"Effect": "Allow",
"Principal": "*",
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:DescribeRepositories",
"ecr:GetRepositoryPolicy",
"ecr:ListImages",
"ecr:DeleteRepository",
"ecr:BatchDeleteImage",
"ecr:SetRepositoryPolicy",
"ecr:DeleteRepositoryPolicy"
]
}
]
}
EOF
# Only one lifecycle policy can be used per repository.
# To apply multiple rules, combined them in one policy JSON.
lifecycle_policy = <<EOF
{
"rules": [
{
"rulePriority": 1,
"description": "Expire untagged images older than 14 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 14
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Keep last 30 dev images",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["dev"],
"countType": "imageCountMoreThan",
"countNumber": 30
},
"action": {
"type": "expire"
}
}
]
}
EOF
# Tags
tags = {
Owner = "DevOps team"
Environment = "dev"
Terraform = true
}
}
### Deleting ECR Repositories Protected with prevent_destroy
By default, ECR repositories created by this module have `prevent_destroy = true` set in their lifecycle configuration to prevent accidental deletion. When you need to remove a repository:
1. Set the `prevent_destroy` parameter to `false` for the module:
```hcl
module "ecr" {
source = "lgallard/ecr/aws"
name = "ecr-repo-dev"
prevent_destroy = false # Allow repository to be destroyed
}
- Apply the configuration change:
terraform apply
- After successful apply, run destroy as normal:
terraform destroy
This approach allows protecting repositories by default while providing a controlled way to remove them when needed.
Name | Version |
---|---|
terraform | >= 1.0.0 |
aws | >= 4.0.0 |
Name | Version |
---|---|
aws | >= 4.0.0 |
No modules.
Name | Type |
---|---|
aws_ecr_lifecycle_policy.lifecycle_policy | resource |
aws_ecr_repository.repo | resource |
aws_ecr_repository.repo_protected | resource |
aws_ecr_repository_policy.policy | resource |
aws_kms_alias.kms_key_alias | resource |
aws_kms_key.kms_key | resource |
aws_caller_identity.current | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
encryption_type | The encryption type for the repository. Valid values are "KMS" or "AES256". | string |
"AES256" |
no |
force_delete | Whether to delete the repository even if it contains images. Setting this to true will delete all images in the repository when the repository is deleted. Use with caution as this operation cannot be undone. Defaults to false for safety. |
bool |
false |
no |
image_scanning_configuration | Configuration block that defines image scanning configuration for the repository. Set to null to use the scan_on_push variable setting. Example: { scan_on_push = true } |
object({ |
null |
no |
image_tag_mutability | The tag mutability setting for the repository. - MUTABLE: Image tags can be overwritten - IMMUTABLE: Image tags cannot be overwritten (recommended for production) Defaults to MUTABLE to maintain backwards compatibility. |
string |
"MUTABLE" |
no |
kms_key | The ARN of an existing KMS key to use for repository encryption. Only applicable when encryption_type is set to 'KMS'. If not specified when using KMS encryption, a new KMS key will be created. |
string |
null |
no |
lifecycle_policy | JSON string representing the lifecycle policy. If null (default), no lifecycle policy will be created. See: https://docs.aws.amazon.com/AmazonECR/latest/userguide/lifecycle_policy_examples.html |
string |
null |
no |
name | Name of the ECR repository. This name must be unique within the AWS account and region. | string |
n/a | yes |
policy | JSON string representing the repository policy. If null (default), no repository policy will be created. See: https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html |
string |
null |
no |
prevent_destroy | Whether to protect the repository from being destroyed. When set to true, the repository will have the lifecycle block with prevent_destroy = true. When set to false, the repository can be destroyed. This provides a way to dynamically control protection against accidental deletion. Defaults to false to allow repository deletion. |
bool |
false |
no |
scan_on_push | Indicates whether images should be scanned for vulnerabilities after being pushed to the repository. - true: Images will be automatically scanned after each push - false: Images must be scanned manually Only used if image_scanning_configuration is null. |
bool |
true |
no |
tags | A map of tags to assign to all resources created by this module. Tags are key-value pairs that help you manage, identify, organize, search for and filter resources. Example: { Environment = "Production", Owner = "Team" } |
map(string) |
{} |
no |
timeouts | Timeout configuration for repository operations. Specify as an object with a 'delete' key containing a duration string (e.g. "20m"). Example: { delete = "20m" } |
object({ |
{} |
no |
timeouts_delete | Deprecated: Use timeouts = { delete = "duration" } instead. How long to wait for a repository to be deleted. Specify as a duration string, e.g. "20m" for 20 minutes. |
string |
null |
no |
enable_logging | Whether to enable CloudWatch logging for the repository. When set to true, logs for ECR API actions and image push/pull events will be sent to CloudWatch Logs. Defaults to false to disable logging. |
bool |
false |
no |
log_retention_days | The number of days to retain logs in the CloudWatch Log Group. Valid values: 0,1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1827,3653. Defaults to 30 days. |
number |
30 |
no |
Name | Description |
---|---|
kms_key_arn | The ARN of the KMS key used for repository encryption. |
registry_id | ID of the ECR registry |
repository_arn | ARN of the ECR repository |
repository_name | Name of the ECR repository |
repository_url | URL of the ECR repository |
cloudwatch_log_group_arn | The ARN of the CloudWatch Log Group created for logging. |
logging_role_arn | The ARN of the IAM role used for logging. |