Terraform module to create AWS ECR (Elastic Container Registry) which is a fully-managed Docker container registry.
The terraform-aws-ecr module enables several common architectures for container image management.
┌──────────────┐ ┌───────────────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ Developer │────▶│ AWS ECR Registry │◀────│ CI/CD Pipeline │
│ Workstation │ │ │ │ │
│ │ └───────────────────────┘ └─────────────────┘
└──────────────┘ │ ▲
│ │
▼ │
┌─────────────────┐
│ │
│ ECS / EKS │
│ Services │
│ │
└─────────────────┘
For more detailed architecture diagrams including CI/CD integration, multi-region deployments, and security controls, see docs/diagrams.md.
This module is organized with specialized submodules for better maintainability and reusability:
Manages KMS encryption keys for ECR repositories with advanced key policies, rotation, and access control.
Manages pull-through cache rules and associated IAM resources for upstream registry integration. Supports multiple upstream registries including Docker Hub, Quay.io, GitHub Container Registry, and Amazon ECR Public.
Key Benefits of Submodule Architecture:
- Separation of Concerns - Each submodule focuses on a specific functionality
- Optional Components - Use only the features you need
- Easier Maintenance - Isolated testing and development
- Reusability - Submodules can be used independently in other projects
This module follows Semantic Versioning principles. For full details on the versioning scheme, release process, and compatibility guarantees, see the following documentation:
- VERSIONING.md - Details on the semantic versioning scheme and release process
- VERSION_COMPATIBILITY.md - Terraform and AWS provider compatibility matrix
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 directory for examples including:
- Simple - Basic ECR repository with minimal configuration
- Complete - Full-featured ECR repository with all options
- Protected - Repository with deletion protection
- With ECS Integration - ECR configured for use with ECS
- Multi-Region - Repository configured for cross-region replication (manual and automatic approaches)
- Replication - ECR repository with built-in cross-region replication support
- Advanced Tagging - Comprehensive tagging strategies with templates, validation, and normalization
- Enhanced Security - Advanced security features with scanning and compliance
- Lifecycle Policies - Image lifecycle management with predefined templates
- Pull Request Rules - Governance and approval workflows for container images
- Enhanced KMS - Advanced KMS key configuration with custom policies and access control
- Pull-Through Cache - Cached access to upstream registries (Docker Hub, Quay, GitHub, etc.)
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
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
The module provides comprehensive CloudWatch monitoring with metric alarms and SNS notifications for proactive repository management. When enabled:
- Creates CloudWatch metric alarms for key ECR metrics
- Monitors storage usage, API calls, and security findings
- Sends notifications via SNS for alarm state changes
- Provides visibility into repository usage and costs
module "ecr" {
source = "lgallard/ecr/aws"
name = "monitored-app"
enable_monitoring = true
# Configure monitoring thresholds
monitoring_threshold_storage = 10 # GB
monitoring_threshold_api_calls = 1000 # calls per minute
monitoring_threshold_security_findings = 5 # findings count
# Create SNS topic for notifications
create_sns_topic = true
sns_topic_name = "ecr-alerts"
sns_topic_subscribers = ["admin@company.com", "devops@company.com"]
}
CloudWatch Alarms Created:
- Storage Usage: Monitors repository size in GB
- API Call Volume: Monitors API operations per minute
- Image Push Count: Monitors push frequency (10 pushes per 5 minutes)
- Image Pull Count: Monitors pull frequency (100 pulls per 5 minutes)
- Security Findings: Monitors vulnerability count (requires enhanced scanning)
SNS Integration:
- Automatic SNS topic creation with configurable name
- Email subscriptions for immediate notifications
- Alarm and OK state notifications
- Support for existing SNS topics
module "ecr" {
source = "lgallard/ecr/aws"
name = "production-app"
# Enable monitoring with custom thresholds
enable_monitoring = true
monitoring_threshold_storage = 50 # 50 GB threshold
monitoring_threshold_api_calls = 2000 # 2000 calls/minute
monitoring_threshold_security_findings = 0 # Zero tolerance for vulnerabilities
# Use existing SNS topic
create_sns_topic = false
sns_topic_name = "existing-alerts-topic"
# Enable enhanced scanning for security monitoring
enable_registry_scanning = true
registry_scan_type = "ENHANCED"
enable_secret_scanning = true
}
Monitoring Outputs:
monitoring_status
- Complete monitoring configuration statussns_topic_arn
- ARN of the SNS topic (if created)cloudwatch_alarms
- Details of all created CloudWatch alarms
Cost Considerations:
- CloudWatch alarms: $0.10 per alarm per month
- SNS notifications: First 1,000 emails free, then $0.75 per 1,000
- No additional charges for metrics collection
The module now supports automatic cross-region replication for disaster recovery and multi-region deployments. When enabled, images are automatically replicated to specified regions whenever they are pushed to the primary repository.
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-application"
# Enable cross-region replication
enable_replication = true
replication_regions = ["us-west-2", "eu-west-1", "ap-southeast-1"]
tags = {
Environment = "production"
Application = "my-app"
}
}
Key Benefits:
- Disaster Recovery - Images remain available if a region becomes unavailable
- Reduced Latency - Pull images from the nearest region
- High Availability - Improved resilience for multi-region workloads
- Automatic Sync - No manual intervention required for replication
Important Notes:
- Replication is configured at the registry level (affects all repositories in the account)
- Use immutable tags (
image_tag_mutability = "IMMUTABLE"
) for consistency across regions - Additional costs apply for cross-region data transfer and storage
- Replication is one-way from the source region to destination regions
The module provides replication-related outputs:
replication_status
- Overall replication configuration statusreplication_regions
- List of destination regionsreplication_configuration_arn
- ARN of the replication configuration
For more detailed examples, see the replication example and multi-region example.
In this example the register is defined in detailed.
module "ecr" {
source = "lgallard/ecr/aws"
name = "ecr-repo-dev"
scan_on_push = true
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.
The module provides comprehensive tagging strategies to support better resource management, cost allocation, and organizational compliance. These features enable consistent, validated, and normalized tagging across all ECR resources while maintaining full backward compatibility.
- Default Tag Templates: Predefined organizational tag standards for common scenarios
- Tag Validation: Ensure required tags are present and follow naming conventions
- Tag Normalization: Consistent casing and format across all resources
- Cost Allocation: Specialized tags for financial tracking and reporting
- Compliance: Tags required for security and regulatory frameworks
- Backward Compatible: All advanced features are opt-in
The module provides four predefined templates for common organizational needs:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable basic organizational tagging
enable_default_tags = true
default_tags_template = "basic"
default_tags_environment = "production"
default_tags_owner = "platform-team"
default_tags_project = "user-service"
}
Applied tags: CreatedBy
, ManagedBy
, Environment
, Owner
, Project
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable cost allocation tagging
enable_default_tags = true
default_tags_template = "cost_allocation"
default_tags_environment = "production"
default_tags_owner = "platform-team"
default_tags_project = "user-service"
default_tags_cost_center = "engineering-cc-001"
}
Applied tags: All basic tags plus CostCenter
, BillingProject
, ResourceType
, Service
, Billable
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable compliance tagging
enable_default_tags = true
default_tags_template = "compliance"
default_tags_environment = "production"
default_tags_owner = "security-team"
default_tags_project = "payment-service"
default_tags_cost_center = "security-cc-002"
}
Applied tags: All cost allocation tags plus DataClass
, Compliance
, BackupRequired
, MonitoringLevel
, SecurityReview
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable SDLC tagging
enable_default_tags = true
default_tags_template = "sdlc"
default_tags_environment = "development"
default_tags_owner = "dev-team"
default_tags_project = "mobile-app"
}
Applied tags: Basic organizational tags plus Application
, Version
, DeploymentStage
, LifecycleStage
, MaintenanceWindow
Ensure organizational compliance by validating that required tags are present:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable tag validation
enable_tag_validation = true
required_tags = [
"Environment",
"Owner",
"Project",
"CostCenter"
]
# This will fail if any required tags are missing
default_tags_environment = "production"
default_tags_owner = "platform-team"
default_tags_project = "user-service"
default_tags_cost_center = "eng-001"
}
Ensure consistent tag formatting across all resources:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable tag normalization
enable_tag_normalization = true
tag_key_case = "PascalCase" # Options: PascalCase, camelCase, snake_case, kebab-case
normalize_tag_values = true
tags = {
"cost-center" = " engineering-001 " # Will be normalized to "CostCenter" = "engineering-001"
"data_class" = "internal" # Will be normalized to "DataClass" = "internal"
}
}
Configure custom default tags without using templates:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Enable custom default tags
enable_default_tags = true
default_tags_template = null # Use custom configuration
default_tags_environment = "staging"
default_tags_owner = "full-stack-team"
default_tags_project = "analytics-service"
default_tags_cost_center = "data-cc-003"
# Additional custom tags
tags = {
team_slack = "analytics-team"
oncall_rotation = "analytics-oncall"
}
}
Disable advanced tagging features for backward compatibility:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Disable advanced tagging features
enable_default_tags = false
enable_tag_validation = false
enable_tag_normalization = false
# Traditional manual tagging
tags = {
Environment = "production"
Owner = "legacy-team"
ManagedBy = "Terraform"
}
}
- Start with Templates: Use predefined templates that match your organizational needs
- Enable Validation: Enforce required tags for compliance and consistency
- Normalize Consistently: Choose a casing strategy and apply it across all resources
- Plan for Cost Allocation: Include cost center and billing project tags early
- Consider Compliance: Include data classification and security review tags for regulated environments
- Monitor Tag Drift: Use the validation and normalization features to maintain consistency
For comprehensive examples demonstrating different tagging strategies, see examples/advanced-tagging.
The module provides enhanced lifecycle policy configuration through helper variables and predefined templates, making it easier to implement common lifecycle patterns without writing complex JSON. This feature significantly simplifies ECR image lifecycle management while maintaining full backwards compatibility.
There are three ways to configure lifecycle policies, listed in order of precedence:
- Manual JSON Policy (
lifecycle_policy
) - Highest precedence, full control - Predefined Templates (
lifecycle_policy_template
) - Medium precedence, common patterns - Helper Variables - Lowest precedence, individual settings
🚨 Important: Configuration Precedence Rules
- When
lifecycle_policy
is specified, ALL template and helper variable settings are ignored - When
lifecycle_policy_template
is specified, ALL helper variable settings are ignored - Only helper variables are used when neither
lifecycle_policy
norlifecycle_policy_template
are specified - AWS ECR Limitations: Maximum 25 rules per policy, rule priorities must be unique (1-999), up to 100 tag prefixes per rule
For complete AWS ECR lifecycle policy documentation and examples, see AWS ECR Lifecycle Policy Documentation.
Configure lifecycle policies using individual helper variables for maximum flexibility:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app"
# Keep only the latest 30 images (range: 1-10000)
lifecycle_keep_latest_n_images = 30
# Delete untagged images after 7 days (range: 1-3650)
lifecycle_expire_untagged_after_days = 7
# Delete tagged images after 90 days (range: 1-3650)
lifecycle_expire_tagged_after_days = 90
# Apply rules only to specific tag prefixes (optional)
lifecycle_tag_prefixes_to_keep = ["v", "release", "prod"]
}
lifecycle_keep_latest_n_images
: Controls how many of the most recent images to retain. When combined withlifecycle_tag_prefixes_to_keep
, only applies to images with those tag prefixes.lifecycle_expire_untagged_after_days
: Automatically deletes untagged images after the specified number of days.lifecycle_expire_tagged_after_days
: Automatically deletes tagged images after the specified number of days.lifecycle_tag_prefixes_to_keep
: When specified, limits thelifecycle_keep_latest_n_images
rule to only images with these tag prefixes. Other lifecycle rules still apply to all images.
Use predefined templates for common scenarios. Each template encapsulates best practices for specific environments:
# Development environment - optimized for frequent builds and testing
module "ecr_dev" {
source = "lgallard/ecr/aws"
name = "dev-app"
lifecycle_policy_template = "development"
}
# Production environment - balanced retention and stability
module "ecr_prod" {
source = "lgallard/ecr/aws"
name = "prod-app"
lifecycle_policy_template = "production"
}
# Cost optimization - minimal storage costs
module "ecr_cost" {
source = "lgallard/ecr/aws"
name = "test-app"
lifecycle_policy_template = "cost_optimization"
}
# Compliance - long retention for audit requirements
module "ecr_compliance" {
source = "lgallard/ecr/aws"
name = "audit-app"
lifecycle_policy_template = "compliance"
}
Template | Keep Images | Untagged Expiry | Tagged Expiry | Tag Prefixes | Use Case |
---|---|---|---|---|---|
development |
50 | 7 days | - | ["dev", "feature"] |
Development workflows with frequent builds |
production |
100 | 14 days | 90 days | ["v", "release", "prod"] |
Production environments requiring stability |
cost_optimization |
10 | 3 days | 30 days | [] (all images) |
Test environments with aggressive cost optimization |
compliance |
200 | 30 days | 365 days | ["v", "release", "audit"] |
Compliance environments requiring long retention |
The module follows a clear precedence order when multiple configuration methods are specified:
module "ecr" {
source = "lgallard/ecr/aws"
name = "custom-app"
# This manual policy takes precedence over everything else
lifecycle_policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Custom rule"
selection = {
tagStatus = "untagged"
countType = "sinceImagePushed"
countUnit = "days"
countNumber = 5
}
action = { type = "expire" }
}
]
})
# These are ignored when lifecycle_policy is specified
lifecycle_policy_template = "production"
lifecycle_keep_latest_n_images = 30
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "template-app"
# Template takes precedence over helper variables
lifecycle_policy_template = "production"
# These helper variables are ignored when template is specified
lifecycle_keep_latest_n_images = 30
lifecycle_expire_untagged_after_days = 5
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "helper-app"
# Only helper variables specified - these will be used
lifecycle_keep_latest_n_images = 30
lifecycle_expire_untagged_after_days = 5
lifecycle_expire_tagged_after_days = 60
lifecycle_tag_prefixes_to_keep = ["v", "stable"]
}
# Development with custom retention
module "ecr_dev_custom" {
source = "lgallard/ecr/aws"
name = "dev-custom-app"
lifecycle_keep_latest_n_images = 20 # Fewer than default dev template
lifecycle_expire_untagged_after_days = 3 # Faster cleanup than default
lifecycle_tag_prefixes_to_keep = ["dev", "feat", "fix"]
}
# Production with extended retention for releases
module "ecr_prod_extended" {
source = "lgallard/ecr/aws"
name = "prod-extended-app"
lifecycle_keep_latest_n_images = 150 # More than default prod template
lifecycle_expire_untagged_after_days = 21 # Longer than default
lifecycle_expire_tagged_after_days = 180 # Extended retention
lifecycle_tag_prefixes_to_keep = ["v", "release", "hotfix"]
}
# Aggressive cleanup for test environments
module "ecr_test" {
source = "lgallard/ecr/aws"
name = "test-app"
lifecycle_keep_latest_n_images = 5 # Minimal retention
lifecycle_expire_untagged_after_days = 1 # Daily cleanup
lifecycle_expire_tagged_after_days = 7 # Weekly cleanup
}
# Balanced approach for staging
module "ecr_staging" {
source = "lgallard/ecr/aws"
name = "staging-app"
lifecycle_policy_template = "development" # Use template for consistency
}
- Use
development
for: CI/CD environments, feature branch testing, development workflows - Use
production
for: Live applications, staging environments, release candidates - Use
cost_optimization
for: Temporary test environments, proof-of-concepts, experimental workloads - Use
compliance
for: Regulated environments, audit trails, long-term archival needs
- Start with a template that's closest to your needs, then use helper variables if needed
- Use tag prefixes to apply different retention rules to different image types
- Monitor storage costs and adjust retention periods based on usage patterns
- Consider compliance requirements when setting retention periods
# Strategy 1: Environment-based prefixes
lifecycle_tag_prefixes_to_keep = ["prod", "staging", "release"]
# Strategy 2: Version-based prefixes
lifecycle_tag_prefixes_to_keep = ["v", "release-"]
# Strategy 3: Branch-based prefixes
lifecycle_tag_prefixes_to_keep = ["main", "develop", "hotfix"]
# Strategy 4: Mixed strategy
lifecycle_tag_prefixes_to_keep = ["v", "release", "prod", "stable"]
The module includes built-in validation to prevent common configuration errors:
- Image count: Must be between 1 and 10,000
- Days: Must be between 1 and 3,650 (10 years)
- Tag prefixes: Maximum 100 prefixes, each up to 255 characters
- Template names: Must be one of the four predefined templates
When using helper variables or templates, the module generates policies with this structure:
- Rule 1: Expire untagged images (if
expire_untagged_after_days
specified) - Rule 2: Keep latest N images (if
keep_latest_n_images
specified) - Rule 3: Expire tagged images (if
expire_tagged_after_days
specified)
To migrate from existing manual lifecycle_policy
to the enhanced configuration:
-
Analyze Your Current Policy: Review your existing JSON lifecycle policy to understand the rules.
# Get current policy from Terraform state terraform show | grep -A 20 lifecycle_policy
-
Choose Migration Path:
- Use a template if your policy matches common patterns
- Use helper variables for custom configurations
- Keep manual policy for complex, non-standard rules
-
Template Migration Example:
# Before (manual policy) module "ecr" { source = "lgallard/ecr/aws" name = "my-app" lifecycle_policy = jsonencode({ rules = [ { rulePriority = 1 description = "Keep last 100 images" selection = { tagStatus = "any" countType = "imageCountMoreThan" countNumber = 100 } action = { type = "expire" } }, { rulePriority = 2 description = "Expire untagged after 14 days" selection = { tagStatus = "untagged" countType = "sinceImagePushed" countUnit = "days" countNumber = 14 } action = { type = "expire" } } ] }) } # After (using production template) module "ecr" { source = "lgallard/ecr/aws" name = "my-app" lifecycle_policy_template = "production" # Matches the pattern above }
-
Helper Variables Migration Example:
# Before (manual policy) lifecycle_policy = jsonencode({ rules = [ { rulePriority = 1 description = "Keep 30 images with specific prefixes" selection = { tagStatus = "tagged" tagPrefixList = ["v", "release"] countType = "imageCountMoreThan" countNumber = 30 } action = { type = "expire" } } ] }) # After (using helper variables) lifecycle_keep_latest_n_images = 30 lifecycle_tag_prefixes_to_keep = ["v", "release"]
-
Test Migration: Apply changes in a non-production environment first:
terraform plan # Review the changes carefully terraform apply # Apply when ready
-
Verify Results: Check that lifecycle policies are correctly applied:
aws ecr describe-lifecycle-policy --repository-name my-app
- Before migration: Document current retention behavior
- After migration: Verify identical behavior with new configuration
- Monitor: Watch for unexpected image deletions in the first week
For more complex migration scenarios, see the migration examples.
See the lifecycle policies example for comprehensive usage examples and the troubleshooting guide for common issues.
The module provides pull request rules functionality to implement governance and approval workflows for container images, similar to pull request approval processes for code repositories. This feature enables organizations to enforce quality control, security validation, and compliance requirements before images are deployed to production.
Pull request rules provide:
- Approval workflows: Require manual approval for production images
- Security validation: Automatic checks for vulnerabilities and compliance
- CI/CD integration: Webhook notifications for external systems
- Governance controls: Policy-based restrictions on image usage
- Audit trails: Complete tracking of image approval workflows
module "ecr" {
source = "lgallard/ecr/aws"
name = "production-app"
# Enable pull request rules
enable_pull_request_rules = true
# Configure approval requirements
pull_request_rules = [
{
name = "production-approval"
type = "approval"
enabled = true
conditions = {
tag_patterns = ["prod-*", "release-*"]
severity_threshold = "HIGH"
}
actions = {
require_approval_count = 2
notification_topic_arn = "arn:aws:sns:region:account:topic"
}
}
]
}
Require manual approval before images can be used in production:
{
name = "security-approval"
type = "approval"
enabled = true
conditions = {
tag_patterns = ["prod-*", "release-*"]
severity_threshold = "HIGH"
require_scan_completion = true
allowed_principals = ["arn:aws:iam::account:role/SecurityTeam"]
}
actions = {
require_approval_count = 2
notification_topic_arn = "arn:aws:sns:region:account:topic"
block_on_failure = true
approval_timeout_hours = 24
}
}
Automatically validate images against security criteria:
{
name = "vulnerability-check"
type = "security_scan"
enabled = true
conditions = {
severity_threshold = "MEDIUM"
require_scan_completion = true
}
actions = {
notification_topic_arn = "arn:aws:sns:region:account:topic"
block_on_failure = true
}
}
Integrate with CI/CD systems through webhooks:
{
name = "ci-validation"
type = "ci_integration"
enabled = true
conditions = {
tag_patterns = ["feature-*", "dev-*"]
}
actions = {
webhook_url = "https://ci.company.com/webhook/ecr"
block_on_failure = false
}
}
tag_patterns
: List of tag patterns that trigger the ruleseverity_threshold
: Minimum vulnerability severity (LOW
,MEDIUM
,HIGH
,CRITICAL
)require_scan_completion
: Whether to require completed security scansallowed_principals
: List of IAM principals allowed to interact with approved images
require_approval_count
: Number of approvals required (1-10)notification_topic_arn
: SNS topic for notificationswebhook_url
: Webhook URL for external integrationsblock_on_failure
: Whether to block operations on rule failureapproval_timeout_hours
: Hours to wait for approval (1-168)
- Image Push: Developer pushes image to ECR repository
- Rule Evaluation: Pull request rules evaluate the image against configured criteria
- Notification: If approval is required, notifications are sent to configured channels
- Security Scan: Automatic vulnerability scanning is performed
- Manual Review: Security team reviews scan results and compliance
- Approval: If acceptable, image is tagged with approval status
- Deployment: Approved images can be deployed to production
module "ecr_governance" {
source = "lgallard/ecr/aws"
name = "critical-application"
enable_pull_request_rules = true
pull_request_rules = [
# Production approval workflow
{
name = "production-security-approval"
type = "approval"
enabled = true
conditions = {
tag_patterns = ["prod-*", "release-*"]
severity_threshold = "HIGH"
require_scan_completion = true
allowed_principals = [
"arn:aws:iam::123456789012:role/SecurityTeam",
"arn:aws:iam::123456789012:role/ReleaseManagers"
]
}
actions = {
require_approval_count = 3
notification_topic_arn = aws_sns_topic.security_alerts.arn
block_on_failure = true
approval_timeout_hours = 48
}
},
# Automatic security validation
{
name = "security-scan-gate"
type = "security_scan"
enabled = true
conditions = {
tag_patterns = ["*"]
severity_threshold = "MEDIUM"
require_scan_completion = true
}
actions = {
notification_topic_arn = aws_sns_topic.security_alerts.arn
block_on_failure = true
}
},
# CI/CD integration
{
name = "ci-pipeline-integration"
type = "ci_integration"
enabled = true
conditions = {
tag_patterns = ["feature-*", "dev-*", "staging-*"]
}
actions = {
webhook_url = "https://ci.company.com/webhook/ecr-validation"
block_on_failure = false
}
}
]
# Enhanced security scanning
enable_registry_scanning = true
registry_scan_type = "ENHANCED"
enable_secret_scanning = true
}
After implementing pull request rules, use these commands to manage approvals:
# Check image scan results
aws ecr describe-image-scan-findings \
--repository-name production-app \
--image-id imageTag=prod-v1.0.0
# Approve image for production use
aws ecr put-image \
--repository-name production-app \
--image-tag prod-v1.0.0 \
--tag-list Key=ApprovalStatus,Value=approved
# List images with approval status
aws ecr describe-images \
--repository-name production-app \
--query 'imageDetails[*].[imageTags[0],imageTagMutability,imageScanFindingsSummary.findings]'
- Layered Approach: Use multiple rule types for comprehensive governance
- Graduated Enforcement: Strict rules for production, flexible for development
- Clear Workflows: Document approval processes and responsibilities
- Monitoring: Set up CloudWatch alarms for rule violations
- Regular Reviews: Periodically review and update rule configurations
- Testing: Test rule configurations in non-production environments first
Pull request rules integrate seamlessly with CI/CD pipelines:
# GitHub Actions example
- name: Check ECR approval status
run: |
STATUS=$(aws ecr describe-images \
--repository-name $REPO_NAME \
--image-ids imageTag=$IMAGE_TAG \
--query 'imageDetails[0].imageTags' \
--output text | grep -o 'ApprovalStatus.*approved' || echo "not-approved")
if [[ "$STATUS" != *"approved"* ]]; then
echo "Image not approved for deployment"
exit 1
fi
See the pull request rules example for a complete implementation guide.
Here are key security best practices for your ECR repositories:
-
Enable Immutable Tags: Prevent tags from being overwritten to ensure image integrity.
image_tag_mutability = "IMMUTABLE"
-
Enable Enhanced Scanning: Use AWS Inspector for comprehensive vulnerability assessment.
enable_registry_scanning = true registry_scan_type = "ENHANCED" enable_secret_scanning = true
-
Configure Pull-Through Cache: Reduce external dependencies and improve performance.
enable_pull_through_cache = true pull_through_cache_rules = [ { ecr_repository_prefix = "docker-hub" upstream_registry_url = "registry-1.docker.io" } ]
-
Enable Basic Scanning: Automatically scan images for security vulnerabilities (if not using enhanced).
scan_on_push = true
-
Implement Least Privilege Access: Use repository policies that grant only necessary permissions.
-
Enable KMS Encryption: Use AWS KMS for enhanced encryption of container images.
encryption_type = "KMS"
For advanced KMS configuration options, see the Enhanced KMS Configuration section below.
-
Configure Lifecycle Policies: Automatically clean up old or unused images.
For a comprehensive guide with detailed examples, see docs/security-best-practices.md.
Common issues and solutions when working with ECR repositories:
Issue | Solution |
---|---|
Authentication failures | Re-authenticate with aws ecr get-login-password |
Permission denied errors | Check IAM policies and repository policies |
Cannot delete repository | Check for prevent_destroy setting and set to false |
Image scan failures | Verify supported image format and AWS region |
Lifecycle policy not working | Check rule syntax and priorities |
For detailed troubleshooting steps, see docs/troubleshooting.md.
This module includes a dedicated KMS submodule that provides enhanced encryption configuration options for ECR repositories. The KMS submodule offers fine-grained control over key policies, rotation settings, and access management.
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-encrypted-repo"
encryption_type = "KMS"
# Enhanced KMS options
kms_deletion_window_in_days = 14
kms_enable_key_rotation = true
kms_key_rotation_period = 90
tags = {
Environment = "production"
}
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "production-app"
encryption_type = "KMS"
# Advanced KMS configuration
kms_deletion_window_in_days = 30
kms_enable_key_rotation = true
kms_key_rotation_period = 180
kms_multi_region = true
# Access control
kms_key_administrators = [
"arn:aws:iam::123456789012:role/KMSAdminRole"
]
kms_key_users = [
"arn:aws:iam::123456789012:role/ECRAccessRole",
"arn:aws:iam::123456789012:role/CI-CD-Role"
]
# Custom alias
kms_alias_name = "production/ecr/my-app"
# KMS-specific tags
kms_tags = {
KeyType = "ECR-Encryption"
Rotation = "180-days"
MultiRegion = "true"
}
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "custom-policy-repo"
encryption_type = "KMS"
# Custom policy statements
kms_custom_policy_statements = [
{
sid = "AllowCrossAccountAccess"
effect = "Allow"
principals = {
type = "AWS"
identifiers = ["arn:aws:iam::TRUSTED-ACCOUNT:root"]
}
actions = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
conditions = [
{
test = "StringEquals"
variable = "kms:ViaService"
values = ["ecr.us-east-1.amazonaws.com"]
}
]
}
]
}
Feature | Variable | Description |
---|---|---|
Key Management | kms_deletion_window_in_days |
Days before key deletion (7-30) |
kms_enable_key_rotation |
Enable automatic rotation | |
kms_key_rotation_period |
Rotation period in days (90-2555) | |
kms_multi_region |
Create multi-region key | |
Access Control | kms_key_administrators |
Principals with full key access |
kms_key_users |
Principals with encrypt/decrypt access | |
kms_additional_principals |
Additional principals with basic access | |
Policy Customization | kms_custom_policy_statements |
Additional policy statements |
kms_custom_policy |
Complete custom policy JSON | |
Naming & Tagging | kms_alias_name |
Custom alias name |
kms_tags |
KMS-specific tags |
- Granular Access Control: Define specific roles for key administration and usage
- Flexible Rotation: Configure custom rotation periods for compliance requirements
- Multi-Region Support: Create keys that work across multiple AWS regions
- Custom Policies: Add specific policy statements or use completely custom policies
- Enhanced Monitoring: KMS-specific tags for better cost tracking and compliance
- Cross-Account Access: Secure sharing of encrypted repositories across AWS accounts
module "production_ecr" {
source = "lgallard/ecr/aws"
name = "production-microservice"
# Production-grade KMS encryption
encryption_type = "KMS"
kms_deletion_window_in_days = 30 # Longer window for recovery
kms_enable_key_rotation = true
kms_key_rotation_period = 90 # Quarterly rotation
kms_multi_region = true # Multi-region deployment
# Role-based access control
kms_key_administrators = [
"arn:aws:iam::123456789012:role/ProductionKMSAdmins"
]
kms_key_users = [
"arn:aws:iam::123456789012:role/ProductionECRAccess",
"arn:aws:iam::123456789012:role/GitHubActions-Production"
]
# Production tagging strategy
tags = {
Environment = "production"
Application = "microservice"
Owner = "platform-team"
CostCenter = "engineering"
}
kms_tags = {
EncryptionType = "ECR-Production"
ComplianceLevel = "SOC2"
BackupRequired = "true"
}
}
For complete examples and advanced use cases, see the enhanced-kms example.
This module offers many configuration options through variables. Here are some examples of common variable configurations:
module "ecr" {
source = "lgallard/ecr/aws"
name = "my-app-repo"
tags = {
Environment = "Production"
}
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "secure-repo"
image_tag_mutability = "IMMUTABLE" # Prevent tag overwriting
scan_on_push = true # Enable basic vulnerability scanning
encryption_type = "KMS" # Use KMS encryption
prevent_destroy = true # Protect from accidental deletion
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "enhanced-secure-repo"
image_tag_mutability = "IMMUTABLE"
encryption_type = "KMS"
# Enhanced scanning with AWS Inspector
enable_registry_scanning = true
registry_scan_type = "ENHANCED"
enable_secret_scanning = true
# Registry scan filters for high/critical vulnerabilities
registry_scan_filters = [
{
name = "PACKAGE_VULNERABILITY_SEVERITY"
values = ["HIGH", "CRITICAL"]
}
]
# Pull-through cache for Docker Hub
enable_pull_through_cache = true
pull_through_cache_rules = [
{
ecr_repository_prefix = "docker-hub"
upstream_registry_url = "registry-1.docker.io"
}
]
}
module "ecr" {
source = "lgallard/ecr/aws"
name = "advanced-repo"
force_delete = false
enable_logging = true
# Set custom timeouts
timeouts = {
delete = "45m"
}
}
For detailed examples of all variables with explanations, see docs/variable-examples.md.
This module uses Terratest for automated testing of the module functionality. The tests validate that the module can correctly:
- Create an ECR repository with basic settings
- Apply repository and lifecycle policies
- Configure KMS encryption
- Set up image tag mutability
- Configure scan on push features
To run the tests locally, you'll need:
# Clone the repository
git clone https://github.com/lgallard/terraform-aws-ecr.git
cd terraform-aws-ecr
# Run the tests
cd test
go mod tidy
go test -v
For more details on tests, see the test directory README.
Name | Version |
---|---|
terraform | >= 1.3.0 |
archive | >= 2.0.0 |
aws | >= 5.0.0 |
Name | Version |
---|---|
archive | >= 2.0.0 |
aws | >= 5.0.0 |
Name | Source | Version |
---|---|---|
kms | ./modules/kms | n/a |
pull_through_cache | ./modules/pull-through-cache | n/a |
Name | Description | Type | Default | Required |
---|---|---|---|---|
create_sns_topic | Whether to create an SNS topic for CloudWatch alarm notifications. | bool |
false |
no |
default_tags_cost_center | Cost center tag value for financial tracking. Null to disable. | string |
null |
no |
default_tags_environment | Environment tag value applied to all resources. Null to disable. | string |
null |
no |
default_tags_owner | Owner tag value applied to all resources. Null to disable. | string |
null |
no |
default_tags_project | Project tag value applied to all resources. Null to disable. | string |
null |
no |
default_tags_template | Predefined default tag template. Options: basic, cost_allocation, compliance, sdlc. | string |
null |
no |
enable_default_tags | Whether to enable automatic default tags for all resources. | bool |
true |
no |
enable_logging | Whether to enable CloudWatch logging for the repository. | bool |
false |
no |
enable_monitoring | Whether to enable CloudWatch monitoring and alerting for the ECR repository. | bool |
false |
no |
enable_pull_request_rules | Whether to enable pull request rules for enhanced governance and quality control. | bool |
false |
no |
enable_pull_through_cache | Whether to create pull-through cache rules. | bool |
false |
no |
enable_registry_scanning | Whether to enable enhanced scanning for the ECR registry. | bool |
false |
no |
enable_replication | Whether to enable cross-region replication for the ECR registry. | bool |
false |
no |
enable_secret_scanning | Whether to enable secret scanning. Detects secrets in container images. | bool |
false |
no |
enable_tag_normalization | Whether to enable automatic tag normalization. | bool |
true |
no |
enable_tag_validation | Whether to enable tag validation to ensure compliance with organizational standards. | bool |
false |
no |
encryption_type | Repository encryption type. Either KMS or AES256. | string |
"AES256" |
no |
force_delete | Whether to delete the repository even if it contains images. Use with caution. | bool |
false |
no |
image_scanning_configuration | Image scanning configuration block. Set to null to use scan_on_push variable. | object({ |
null |
no |
image_tag_mutability | The tag mutability setting for the repository. Either MUTABLE, IMMUTABLE, IMMUTABLE_WITH_EXCLUSION, or MUTABLE_WITH_EXCLUSION. | string |
"MUTABLE" |
no |
kms_additional_principals | List of additional IAM principals (ARNs) to grant KMS key access. | list(string) |
[] |
no |
kms_alias_name | Custom alias name for the KMS key (without 'alias/' prefix). | string |
null |
no |
kms_custom_policy | Complete custom policy JSON for the KMS key. Use with caution. | string |
null |
no |
kms_custom_policy_statements | List of custom policy statements to add to the KMS key policy. | list(object({ |
[] |
no |
kms_deletion_window_in_days | Number of days to wait before deleting the KMS key (7-30 days). | number |
7 |
no |
kms_enable_key_rotation | Whether to enable automatic key rotation for the KMS key. | bool |
true |
no |
kms_key | ARN of existing KMS key for repository encryption. If null, a new key is created. | string |
null |
no |
kms_key_administrators | List of IAM principals (ARNs) who can administer the KMS key. | list(string) |
[] |
no |
kms_key_rotation_period | Number of days between automatic key rotations (90-2555 days). | number |
null |
no |
kms_key_users | List of IAM principals (ARNs) who can use the KMS key for crypto operations. | list(string) |
[] |
no |
kms_multi_region | Whether to create a multi-region KMS key. | bool |
false |
no |
kms_tags | Additional tags specific to KMS resources. | map(string) |
{} |
no |
lifecycle_expire_tagged_after_days | Number of days after which tagged images expire (1-3650). Use with caution. | number |
null |
no |
lifecycle_expire_untagged_after_days | Number of days after which untagged images expire (1-3650). Null to disable. | number |
null |
no |
lifecycle_keep_latest_n_images | Number of latest images to keep in the repository (1-10000). Null to disable. | number |
null |
no |
lifecycle_policy | JSON string representing the lifecycle policy. Takes precedence over helper variables. | string |
null |
no |
lifecycle_policy_template | Predefined lifecycle policy template. Options: development, production, cost_optimization, compliance. | string |
null |
no |
lifecycle_tag_prefixes_to_keep | List of tag prefixes for keep-latest rule. Empty list applies to all images. Max 100 prefixes. | list(string) |
[] |
no |
log_retention_days | Number of days to retain ECR logs in CloudWatch. | number |
30 |
no |
monitoring_threshold_api_calls | API call volume threshold per minute to trigger CloudWatch alarm. | number |
1000 |
no |
monitoring_threshold_image_pull | Image pull frequency threshold per 5-minute period to trigger CloudWatch alarm. | number |
100 |
no |
monitoring_threshold_image_push | Image push frequency threshold per 5-minute period to trigger CloudWatch alarm. | number |
10 |
no |
monitoring_threshold_security_findings | Security findings threshold to trigger CloudWatch alarm. | number |
10 |
no |
monitoring_threshold_storage | Storage usage threshold in GB to trigger CloudWatch alarm. | number |
10 |
no |
name | Name of the ECR repository. This name must be unique within the AWS account and region. | string |
n/a | yes |
normalize_tag_values | Whether to normalize tag values by trimming whitespace. | bool |
true |
no |
policy | JSON string representing the repository policy. If null, no policy is created. | string |
null |
no |
prevent_destroy | Whether to protect the repository from being destroyed via lifecycle prevent_destroy. | bool |
false |
no |
pull_request_rules | List of pull request rule configurations for enhanced governance. | list(object({ |
[] |
no |
pull_through_cache_rules | List of pull-through cache rules to create. | list(object({ |
[] |
no |
registry_scan_filters | List of scan filters for filtering scan results when querying ECR findings. | list(object({ |
[] |
no |
registry_scan_type | The type of scanning to configure for the registry. Either BASIC or ENHANCED. | string |
"ENHANCED" |
no |
replication_regions | List of AWS regions to replicate ECR images to. | list(string) |
[] |
no |
required_tags | List of tag keys that are required to be present. Empty list disables validation. | list(string) |
[] |
no |
scan_on_push | Whether images should be scanned after being pushed to the repository. | bool |
true |
no |
scan_repository_filters | List of repository filters to apply for registry scanning. Supports wildcards. | list(string) |
[ |
no |
sns_topic_name | Name of the SNS topic to create or use for alarm notifications. | string |
null |
no |
sns_topic_subscribers | List of email addresses to subscribe to the SNS topic for alarm notifications. | list(string) |
[] |
no |
tag_key_case | Enforce consistent casing for tag keys. Options: PascalCase, camelCase, snake_case, kebab-case. | string |
"PascalCase" |
no |
tags | A map of tags to assign to all resources created by this module. | map(string) |
{} |
no |
timeouts | Timeout configuration for repository operations. Example: { delete = "20m" } | object({ |
{} |
no |
Name | Description |
---|---|
applied_tags | The final set of tags applied to all resources after normalization and default tag application |
cloudwatch_alarms | List of CloudWatch alarms created for ECR monitoring |
cloudwatch_log_group_arn | The ARN of the CloudWatch Log Group used for ECR logs (if logging is enabled) |
kms_alias_arn | The ARN of the KMS alias (if created by this module). |
kms_configuration | Complete KMS configuration information. |
kms_key_arn | The ARN of the KMS key used for repository encryption. |
kms_key_id | The globally unique identifier for the KMS key (if created by this module). |
lifecycle_policy | The lifecycle policy JSON applied to the repository (if any) |
logging_role_arn | The ARN of the IAM role used for ECR logging (if logging is enabled) |
monitoring_status | Status of CloudWatch monitoring configuration |
pull_request_rules | Information about pull request rules configuration |
pull_through_cache_role_arn | The ARN of the IAM role used for pull-through cache operations (if enabled) |
pull_through_cache_rules | List of pull-through cache rules (if enabled) |
registry_id | ID of the ECR registry |
registry_scan_filters | The configured scan filters for filtering scan results (e.g., by vulnerability severity) |
registry_scanning_configuration_arn | The ARN of the ECR registry scanning configuration (if enhanced scanning is enabled) |
registry_scanning_status | Status of ECR registry scanning configuration |
replication_configuration_arn | The ARN of the ECR replication configuration (if replication is enabled) |
replication_regions | List of regions where ECR images are replicated to (if replication is enabled) |
replication_status | Status of ECR replication configuration |
repository_arn | ARN of the ECR repository |
repository_name | Name of the ECR repository |
repository_policy_exists | Whether a repository policy exists for this ECR repository |
repository_url | URL of the ECR repository |
security_status | Comprehensive security status of the ECR configuration |
sns_topic_arn | ARN of the SNS topic used for ECR monitoring alerts (if created) |
tag_compliance_status | Tag compliance and validation status |
tagging_strategy | Summary of the tagging strategy configuration |
This module includes an automated feature discovery system that runs weekly to identify new AWS ECR features, deprecations, and bug fixes from the AWS provider. The system uses Claude Code with MCP (Model Context Protocol) servers to analyze provider documentation and automatically create GitHub issues for new functionality.
- Weekly Scanning: Every Sunday at 00:00 UTC, the system scans the latest AWS provider documentation
- MCP Integration: Uses Terraform and Context7 MCP servers to access up-to-date provider docs
- Intelligent Analysis: Compares provider capabilities with current module implementation
- Automated Issues: Creates categorized GitHub issues for discovered items:
- 🚀 New Features - ECR resources/arguments not yet implemented
⚠️ Deprecations - Features being phased out requiring action- 🐛 Bug Fixes - Important provider fixes affecting the module
The discovery process follows this workflow:
┌─────────────────┐ ┌──────────────────────┐ ┌─────────────────────┐
│ │ │ │ │ │
│ Weekly Trigger │───▶│ Claude Code CLI │───▶│ GitHub Issues │
│ (GitHub Action)│ │ + MCP Servers │ │ (Auto-created) │
│ │ │ │ │ │
└─────────────────┘ └──────────────────────┘ └─────────────────────┘
│
▼
┌──────────────────────┐
│ │
│ Feature Tracking │
│ Database │
│ (.github/tracker/) │
│ │
└──────────────────────┘
You can manually trigger feature discovery:
# Standard discovery
gh workflow run feature-discovery.yml
# Dry run mode (analyze without creating issues)
gh workflow run feature-discovery.yml -f dry_run=true
# Specific provider version
gh workflow run feature-discovery.yml -f provider_version=5.82.0
# Force full scan
gh workflow run feature-discovery.yml -f force_scan=true
The system identifies and categorizes findings as:
New Features (enhancement
label):
- New ECR resources (
aws_ecr_*
) - New arguments on existing resources
- New data sources (
data.aws_ecr_*
) - New lifecycle configurations
- New security/monitoring features
Deprecations (deprecation
label):
- Arguments marked for removal
- Resources being phased out
- Configuration patterns no longer recommended
Bug Fixes (bug
label):
- Provider fixes affecting module functionality
- Performance improvements
- Security patches
Each discovery type uses a structured template:
- New Features: Implementation checklist, examples, testing requirements
- Deprecations: Migration guidance, timeline, impact assessment
- Bug Fixes: Impact analysis, testing strategy, version requirements
All discoveries are tracked in .github/feature-tracker/ecr-features.json
:
{
"metadata": {
"last_scan": "2025-01-21T00:00:00Z",
"provider_version": "5.82.0",
"scan_count": 42
},
"current_implementation": {
"resources": {
"aws_ecr_repository": {
"implemented": ["name", "image_tag_mutability", "scan_on_push"],
"pending": ["force_delete"]
}
}
},
"discovered_features": {
"new_resources": {},
"deprecations": {},
"bug_fixes": {}
}
}
The system leverages Model Context Protocol servers for real-time documentation access:
-
Terraform MCP:
@modelcontextprotocol/server-terraform@latest
- AWS provider resource documentation
- Argument specifications and examples
- Version compatibility information
-
Context7 MCP:
@upstash/context7-mcp@latest
- Provider changelogs and release notes
- Community discussions and best practices
- Historical change tracking
- Stay Current: Never miss new AWS ECR features
- Proactive Maintenance: Identify deprecations before they break
- Automated Tracking: Comprehensive feature database
- Community Value: Users benefit from latest AWS capabilities
- Reduced Manual Work: No need for manual provider monitoring
The system is designed to minimize false positives, but you can help improve accuracy:
- Review Auto-Created Issues: Validate and prioritize discoveries
- Update Tracking: Mark features as implemented when complete
- Improve Templates: Suggest enhancements to issue templates
- Report Gaps: Let us know if the system misses important features
For more details on the discovery system architecture, see .github/scripts/discovery-prompt.md
.
Name | Version |
---|---|
terraform | >= 1.3.0 |
archive | >= 2.0.0 |
aws | >= 5.0.0 |
Name | Version |
---|---|
archive | >= 2.0.0 |
aws | >= 5.0.0 |
Name | Source | Version |
---|---|---|
kms | ./modules/kms | n/a |
pull_through_cache | ./modules/pull-through-cache | n/a |
Name | Description | Type | Default | Required |
---|---|---|---|---|
create_sns_topic | Whether to create an SNS topic for CloudWatch alarm notifications. | bool |
false |
no |
default_tags_cost_center | Cost center tag value for financial tracking. Null to disable. | string |
null |
no |
default_tags_environment | Environment tag value applied to all resources. Null to disable. | string |
null |
no |
default_tags_owner | Owner tag value applied to all resources. Null to disable. | string |
null |
no |
default_tags_project | Project tag value applied to all resources. Null to disable. | string |
null |
no |
default_tags_template | Predefined default tag template. Options: basic, cost_allocation, compliance, sdlc. | string |
null |
no |
enable_default_tags | Whether to enable automatic default tags for all resources. | bool |
true |
no |
enable_logging | Whether to enable CloudWatch logging for the repository. | bool |
false |
no |
enable_monitoring | Whether to enable CloudWatch monitoring and alerting for the ECR repository. | bool |
false |
no |
enable_pull_request_rules | Whether to enable pull request rules for enhanced governance and quality control. | bool |
false |
no |
enable_pull_through_cache | Whether to create pull-through cache rules. | bool |
false |
no |
enable_registry_scanning | Whether to enable enhanced scanning for the ECR registry. | bool |
false |
no |
enable_replication | Whether to enable cross-region replication for the ECR registry. | bool |
false |
no |
enable_secret_scanning | Whether to enable secret scanning. Detects secrets in container images. | bool |
false |
no |
enable_tag_normalization | Whether to enable automatic tag normalization. | bool |
true |
no |
enable_tag_validation | Whether to enable tag validation to ensure compliance with organizational standards. | bool |
false |
no |
encryption_type | Repository encryption type. Either KMS or AES256. | string |
"AES256" |
no |
force_delete | Whether to delete the repository even if it contains images. Use with caution. | bool |
false |
no |
image_scanning_configuration | Image scanning configuration block. Set to null to use scan_on_push variable. | object({ |
null |
no |
image_tag_mutability | The tag mutability setting for the repository. Either MUTABLE, IMMUTABLE, IMMUTABLE_WITH_EXCLUSION, or MUTABLE_WITH_EXCLUSION. | string |
"MUTABLE" |
no |
kms_additional_principals | List of additional IAM principals (ARNs) to grant KMS key access. | list(string) |
[] |
no |
kms_alias_name | Custom alias name for the KMS key (without 'alias/' prefix). | string |
null |
no |
kms_custom_policy | Complete custom policy JSON for the KMS key. Use with caution. | string |
null |
no |
kms_custom_policy_statements | List of custom policy statements to add to the KMS key policy. | list(object({ |
[] |
no |
kms_deletion_window_in_days | Number of days to wait before deleting the KMS key (7-30 days). | number |
7 |
no |
kms_enable_key_rotation | Whether to enable automatic key rotation for the KMS key. | bool |
true |
no |
kms_key | ARN of existing KMS key for repository encryption. If null, a new key is created. | string |
null |
no |
kms_key_administrators | List of IAM principals (ARNs) who can administer the KMS key. | list(string) |
[] |
no |
kms_key_rotation_period | Number of days between automatic key rotations (90-2555 days). | number |
null |
no |
kms_key_users | List of IAM principals (ARNs) who can use the KMS key for crypto operations. | list(string) |
[] |
no |
kms_multi_region | Whether to create a multi-region KMS key. | bool |
false |
no |
kms_tags | Additional tags specific to KMS resources. | map(string) |
{} |
no |
lifecycle_expire_tagged_after_days | Number of days after which tagged images expire (1-3650). Use with caution. | number |
null |
no |
lifecycle_expire_untagged_after_days | Number of days after which untagged images expire (1-3650). Null to disable. | number |
null |
no |
lifecycle_keep_latest_n_images | Number of latest images to keep in the repository (1-10000). Null to disable. | number |
null |
no |
lifecycle_policy | JSON string representing the lifecycle policy. Takes precedence over helper variables. | string |
null |
no |
lifecycle_policy_template | Predefined lifecycle policy template. Options: development, production, cost_optimization, compliance. | string |
null |
no |
lifecycle_tag_prefixes_to_keep | List of tag prefixes for keep-latest rule. Empty list applies to all images. Max 100 prefixes. | list(string) |
[] |
no |
log_retention_days | Number of days to retain ECR logs in CloudWatch. | number |
30 |
no |
monitoring_threshold_api_calls | API call volume threshold per minute to trigger CloudWatch alarm. | number |
1000 |
no |
monitoring_threshold_image_pull | Image pull frequency threshold per 5-minute period to trigger CloudWatch alarm. | number |
100 |
no |
monitoring_threshold_image_push | Image push frequency threshold per 5-minute period to trigger CloudWatch alarm. | number |
10 |
no |
monitoring_threshold_security_findings | Security findings threshold to trigger CloudWatch alarm. | number |
10 |
no |
monitoring_threshold_storage | Storage usage threshold in GB to trigger CloudWatch alarm. | number |
10 |
no |
name | Name of the ECR repository. This name must be unique within the AWS account and region. | string |
n/a | yes |
normalize_tag_values | Whether to normalize tag values by trimming whitespace. | bool |
true |
no |
policy | JSON string representing the repository policy. If null, no policy is created. | string |
null |
no |
prevent_destroy | Whether to protect the repository from being destroyed via lifecycle prevent_destroy. | bool |
false |
no |
pull_request_rules | List of pull request rule configurations for enhanced governance. | list(object({ |
[] |
no |
pull_through_cache_rules | List of pull-through cache rules to create. | list(object({ |
[] |
no |
registry_scan_filters | List of scan filters for filtering scan results when querying ECR findings. | list(object({ |
[] |
no |
registry_scan_type | The type of scanning to configure for the registry. Either BASIC or ENHANCED. | string |
"ENHANCED" |
no |
replication_regions | List of AWS regions to replicate ECR images to. | list(string) |
[] |
no |
required_tags | List of tag keys that are required to be present. Empty list disables validation. | list(string) |
[] |
no |
scan_on_push | Whether images should be scanned after being pushed to the repository. | bool |
true |
no |
scan_repository_filters | List of repository filters to apply for registry scanning. Supports wildcards. | list(string) |
[ |
no |
sns_topic_name | Name of the SNS topic to create or use for alarm notifications. | string |
null |
no |
sns_topic_subscribers | List of email addresses to subscribe to the SNS topic for alarm notifications. | list(string) |
[] |
no |
tag_key_case | Enforce consistent casing for tag keys. Options: PascalCase, camelCase, snake_case, kebab-case. | string |
"PascalCase" |
no |
tags | A map of tags to assign to all resources created by this module. | map(string) |
{} |
no |
timeouts | Timeout configuration for repository operations. Example: { delete = "20m" } | object({ |
{} |
no |
Name | Description |
---|---|
applied_tags | The final set of tags applied to all resources after normalization and default tag application |
cloudwatch_alarms | List of CloudWatch alarms created for ECR monitoring |
cloudwatch_log_group_arn | The ARN of the CloudWatch Log Group used for ECR logs (if logging is enabled) |
kms_alias_arn | The ARN of the KMS alias (if created by this module). |
kms_configuration | Complete KMS configuration information. |
kms_key_arn | The ARN of the KMS key used for repository encryption. |
kms_key_id | The globally unique identifier for the KMS key (if created by this module). |
lifecycle_policy | The lifecycle policy JSON applied to the repository (if any) |
logging_role_arn | The ARN of the IAM role used for ECR logging (if logging is enabled) |
monitoring_status | Status of CloudWatch monitoring configuration |
pull_request_rules | Information about pull request rules configuration |
pull_through_cache_role_arn | The ARN of the IAM role used for pull-through cache operations (if enabled) |
pull_through_cache_rules | List of pull-through cache rules (if enabled) |
registry_id | ID of the ECR registry |
registry_scan_filters | The configured scan filters for filtering scan results (e.g., by vulnerability severity) |
registry_scanning_configuration_arn | The ARN of the ECR registry scanning configuration (if enhanced scanning is enabled) |
registry_scanning_status | Status of ECR registry scanning configuration |
replication_configuration_arn | The ARN of the ECR replication configuration (if replication is enabled) |
replication_regions | List of regions where ECR images are replicated to (if replication is enabled) |
replication_status | Status of ECR replication configuration |
repository_arn | ARN of the ECR repository |
repository_name | Name of the ECR repository |
repository_policy_exists | Whether a repository policy exists for this ECR repository |
repository_url | URL of the ECR repository |
security_status | Comprehensive security status of the ECR configuration |
sns_topic_arn | ARN of the SNS topic used for ECR monitoring alerts (if created) |
tag_compliance_status | Tag compliance and validation status |
tagging_strategy | Summary of the tagging strategy configuration |