Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.artosai.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The ECR (Elastic Container Registry) Module manages container image repositories for the Artos platform. It creates separate repositories for environment-specific application components and shared third-party services, with configurable lifecycle policies, security scanning, encryption, and cross-account access controls.

Key Features

  • Environment Isolation: Separate repositories per environment (development, staging, production)
  • Automatic Image Cleanup: Lifecycle policies to manage storage costs
  • Security Scanning: Automatic vulnerability scanning on image push
  • Encryption: Support for AES256 and KMS encryption
  • Cross-Account Access: Enable image sharing across AWS accounts
  • Third-Party Image Management: Centralized repositories for shared dependencies

Container Images

The module creates repositories for two types of container images: Environment-Specific images that are isolated per environment, and Third-Party/Shared images that are centralized across environments.

Environment-Specific Images

These repositories are created for each environment (development, staging, production) and contain custom Artos application code.

1. Backend API (artos-postgres-eks-backend)

Repository Name: {environment}/artos-postgres-eks-backend The main application backend API server that handles HTTP requests, business logic, and database interactions. Contains:
  • FastAPI REST API server for core Artos platform logic and routes
  • Database models and migrations
  • Authentication and authorization logic
Typical Images:
development/artos-postgres-eks-backend:latest
development/artos-postgres-eks-backend:v1.2.3
staging/artos-postgres-eks-backend:v1.2.3
production/artos-postgres-eks-backend:v1.2.3

2. Celery Workers (artos-postgres-eks-celery)

Repository Name: {environment}/artos-postgres-eks-celery Asynchronous task workers for background job processing, scheduled tasks, and long-running operations. Contains:
  • Celery worker processes
  • Task definitions and handlers
  • Background job processors
  • Scheduled task runners
  • Queue consumers
Typical Images:
development/artos-postgres-eks-celery:latest
staging/artos-postgres-eks-celery:v1.2.3
production/artos-postgres-eks-celery:v1.2.3
Use Cases:
  • Document generation workflows
  • Document editing workflows

3. Frontend Application (frontend)

Repository Name: {environment}/frontend The user-facing web application frontend built with modern JavaScript frameworks. Contains:
  • frontend UI and functionality for the Artos platform
Typical Images:
development/frontend:latest
development/frontend:feature-new-ui
staging/frontend:v2.1.0
production/frontend:v2.1.0

Third-Party/Shared Images

These repositories are created once (typically in a shared or production account) and used across all environments to avoid duplication and ensure consistency.
Important: Set create_thirdparty_repos = true in only one environment (typically production or a shared services account) to avoid repository name conflicts. Other environments should reference these shared repositories.

4. Redis Cache (thirdparty/redis)

Repository Name: thirdparty/redis Redis container images used for caching, session storage, and message brokering. Purpose:
  • Application caching layer
  • Celery message broker
  • Rate limiting data store
Typical Images:
thirdparty/redis:7.2-alpine
thirdparty/redis:7.0-alpine

5. OnlyOffice Document Server (thirdparty/onlyoffice)

Repository Name: thirdparty/onlyoffice OnlyOffice Document Server for collaborative document editing and viewing. Purpose:
  • Word document editing (DOCX)
  • Real-time collaboration
Typical Images:
thirdparty/onlyoffice:7.5
thirdparty/onlyoffice:7.4

6. LiteLLM Proxy (thirdparty/litellm)

Repository Name: thirdparty/litellm LiteLLM proxy server for unified LLM (Large Language Model) API access. Purpose:
  • Unified interface for multiple LLM providers (OpenAI, Anthropic, etc.)
  • API key management and rotation
  • Request rate limiting and cost tracking
  • Load balancing across LLM endpoints
  • Caching for improved performance
Typical Images:
thirdparty/litellm:latest
thirdparty/litellm:v1.0.0

7. PropelAuth (thirdparty/propelauth)

Repository Name: thirdparty/propelauth PropelAuth authentication and user management service. Purpose:
  • User authentication and authorization
  • SSO (Single Sign-On) integration
  • Multi-factor authentication (MFA)
  • User management and organization features
  • OAuth and SAML support
Typical Images:
thirdparty/propelauth:latest
thirdparty/propelauth:v2.0.0

Image Management Policies

1. Lifecycle Policies

Lifecycle policies automatically delete older images to manage storage costs while retaining recent versions. Note: all max_image_count values are set to 0 to ensure all versions are stored in ECR. How It Works:
  • Triggered when image count exceeds max_image_count
  • Deletes oldest images first (by push timestamp)
  • Applies to both tagged and untagged images
  • Runs automatically (no manual intervention needed)
Policy Behavior:
max_image_countBehavior
null or 0No lifecycle policy (keep all images indefinitely)
1-1000Keep only the specified number of most recent images
Example Lifecycle Policy:
{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Keep last 10 images",
      "selection": {
        "tagStatus": "any",
        "countType": "imageCountMoreThan",
        "countNumber": 10
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

2. Cross-Account Access Policies

Cross-account policies enable other AWS accounts to pull images from your ECR repositories, useful for multi-account architectures or shared services. Note: default terraform has cross_account_ids set to an empty list. Cross account ids are usually added manually after the terraform is spun up. Policy Configuration:
enable_cross_account_access = true
cross_account_ids = [
  "123456789012",  # Production account
  "234567890123"   # Staging account
]
Granted Permissions:
  • ecr:GetDownloadUrlForLayer - Download image layers
  • ecr:BatchGetImage - Retrieve image metadata
  • ecr:BatchCheckLayerAvailability - Check if layers exist
Example Repository Policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossAccountPull",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:root",
          "arn:aws:iam::234567890123:root"
        ]
      },
      "Action": [
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "ecr:BatchCheckLayerAvailability"
      ]
    }
  ]
}
Use Cases:
  • Centralized Image Registry: Production account hosts all images, other accounts pull as needed
  • Multi-Region Deployments: Share images across regions via cross-account replication
  • Shared Services: Development account provides common third-party images to all environments

3. Image Scanning

Automatically scans container images for security vulnerabilities (CVEs) upon push. Configuration:
scan_on_push = true  # Enable automatic scanning (default)
Scanning Process:
  1. Image is pushed to ECR repository
  2. ECR triggers automatic vulnerability scan
  3. Results available in AWS Console or via API within minutes
  4. Findings categorized by severity: CRITICAL, HIGH, MEDIUM, LOW, INFORMATIONAL
Viewing Scan Results:
# Get scan findings for an image
aws ecr describe-image-scan-findings \
    --repository-name production/artos-postgres-eks-backend \
    --image-id imageTag=v1.2.3 \
    --region us-east-1
CI/CD Integration:
# Example GitHub Actions workflow
- name: Scan for vulnerabilities
  run: |
    aws ecr wait image-scan-complete \
      --repository-name ${{ env.REPOSITORY }} \
      --image-id imageTag=${{ env.IMAGE_TAG }}
    
    SCAN_FINDINGS=$(aws ecr describe-image-scan-findings \
      --repository-name ${{ env.REPOSITORY }} \
      --image-id imageTag=${{ env.IMAGE_TAG }} \
      --query 'imageScanFindings.findingSeverityCounts')
    
    # Fail build if critical vulnerabilities found
    if echo $SCAN_FINDINGS | grep -q "CRITICAL"; then
      echo "Critical vulnerabilities found!"
      exit 1
    fi

5. Encryption

All images are encrypted at rest using either AWS-managed or customer-managed encryption keys. Configuration Options: AES256 (Default - AWS-Managed):
encryption_type = "AES256"  # No additional configuration needed
KMS (Customer-Managed Keys):
encryption_type = "KMS"
kms_key_arn     = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"

Module Configuration

Basic Configuration

module "ecr" {
  source = "./modules/ecr"

  environment = "production"

  # Standard security settings
  scan_on_push         = true
  image_tag_mutability = "IMMUTABLE"
  encryption_type      = "AES256"

  # Keep last 10 images
  max_image_count = 10

  # Do not create third-party repos (use shared ones)
  create_thirdparty_repos = false

  tags = {
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

Production Configuration with KMS

module "ecr_production" {
  source = "./modules/ecr"

  environment = "production"

  # Production security settings
  scan_on_push         = true
  image_tag_mutability = "IMMUTABLE"  # Prevent tag overwrites
  encryption_type      = "KMS"
  kms_key_arn          = module.kms.ecr_key_arn

  # Retain more images for rollback capability
  max_image_count = 20

  # Enable cross-account access for disaster recovery
  enable_cross_account_access = true
  cross_account_ids = [
    "123456789012"  # DR account
  ]

  create_thirdparty_repos = false

  tags = {
    Environment = "production"
    Compliance  = "hipaa"
    BackupPlan  = "daily"
  }
}

Shared Services Configuration

# Create third-party repositories in a shared services account
module "ecr_shared" {
  source = "./modules/ecr"

  environment = "shared"

  # Shared repository settings
  scan_on_push         = true
  image_tag_mutability = "MUTABLE"  # Allow updates to shared images
  encryption_type      = "AES256"

  # Keep fewer images for third-party dependencies
  max_image_count = 5

  # CREATE third-party repos in shared account only
  create_thirdparty_repos = true

  # Allow all environment accounts to pull
  enable_cross_account_access = true
  cross_account_ids = [
    "111111111111",  # Development account
    "222222222222",  # Staging account
    "333333333333"   # Production account
  ]

  tags = {
    Environment = "shared"
    Purpose     = "third-party-images"
  }
}

Development Configuration

module "ecr_dev" {
  source = "./modules/ecr"

  environment = "development"

  # Relaxed settings for development
  scan_on_push         = true
  image_tag_mutability = "MUTABLE"   # Allow tag overwrites
  encryption_type      = "AES256"

  # Keep only recent images to minimize costs
  max_image_count = 3

  # Reference shared third-party repos
  create_thirdparty_repos = false

  tags = {
    Environment = "development"
    CostCenter  = "engineering"
  }
}

Repository Naming Convention

The module follows a consistent naming pattern for easy identification and organization: Environment-Specific Repositories:
{environment}/artos-postgres-eks-backend
{environment}/artos-postgres-eks-celery
{environment}/frontend
Third-Party/Shared Repositories:
thirdparty/redis
thirdparty/onlyoffice
thirdparty/litellm
thirdparty/propelauth
Examples:
development/artos-postgres-eks-backend
staging/artos-postgres-eks-celery
production/frontend
thirdparty/redis

Pushing Images to ECR

Authenticate Docker to ECR

# Get authentication token and login
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin \
  123456789012.dkr.ecr.us-east-1.amazonaws.com

Build and Push Application Images

# Build backend image
docker build -t artos-backend:v1.2.3 -f backend/Dockerfile .

# Tag for ECR
docker tag artos-backend:v1.2.3 \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/production/artos-postgres-eks-backend:v1.2.3

# Push to ECR
docker push \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/production/artos-postgres-eks-backend:v1.2.3

# Also push as 'latest'
docker tag artos-backend:v1.2.3 \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/production/artos-postgres-eks-backend:latest

docker push \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/production/artos-postgres-eks-backend:latest

Pull Third-Party Images

# Pull Redis from Docker Hub
docker pull redis:7.2-alpine

# Tag for your ECR
docker tag redis:7.2-alpine \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/thirdparty/redis:7.2-alpine

# Push to your ECR
docker push \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/thirdparty/redis:7.2-alpine

Module Maintenance: This module is compatible with Terraform 1.0+ and AWS Provider 5.x. All repositories are automatically tagged with environment and component metadata for resource tracking and cost allocation.