Dynamic Image Transformation for Amazon CloudFront

repository·main·Indexed 23 days ago

https://github.com/aws-solutions/dynamic-image-transformation-for-amazon-cloudfront

A solution for high-speed, dynamic image resizing and manipulation using Amazon CloudFront, S3, and Sharp. It supports two primary deployment architectures: an ECS Architecture (recommended for new deployments) and a Lambda Architecture. The solution includes a Management Stack for administration via a web portal and an Image Processing Stack for high-performance image handling.

Tokens
20.1K
Snippets
41
Records
114
Agent score
73%

What's inside Dynamic Image Transformation for Amazon CloudFront

  1. Overview of Dynamic Image Transformation for Amazon CloudFront

    main
    The Dynamic Image Transformation for Amazon CloudFront solution enables high-speed image processing using Sharp. It automates the deployment of a serverless architecture that uses Amazon CloudFront for global delivery and Amazon S3 for storage. This allows for dynamic image manipulation, such as resizing images on-the-fly based on screen size, to optimize performance and costs.
  2. Understand the Dynamic Image Transformation (DIT) v8 Architecture

    main

    The DIT v8 solution is split into two primary functional stacks: the Management Stack and the Image Processing Stack.

    Management Stack

    Provides the administration portal for managing the solution. It consists of:

    • Frontend Layer: A CloudFront distribution, an S3 bucket for static assets, and a Cognito User Pool for admin authentication.
    • Data Access Layer (DAL): An API Gateway (using OpenAPI spec) and Lambda microservices backed by a DynamoDB single-table design for configuration storage.
    • Key Outputs: WebPortalUrl (admin portal endpoint) and APIEndpoint (backend API base URL).
    • Required Parameter: AdminEmail (used to create the initial admin user).

    Image Processing Stack

    An ECS-based high-performance stack for processing images. It consists of:

    • Network Layer: A VPC with configurable CIDR blocks, 3 public subnets, and necessary security groups.
    • Container Layer: An ECR repository for Docker images with automatic building and deployment.
    • Compute Layer: An Application Load Balancer (ALB) and an ECS Fargate service with auto-scaling. The service includes a /health-check endpoint.
    • Key Outputs: VpcId, ContainerDeploymentMode, ImageUri, and LoadBalancerDNS.
    • Key Parameters: DeploymentSize (T-shirt sizing) and OriginOverrideHeader (header to override image origin).
  3. Understand the E2E test structure and patterns

    main

    The E2E tests are built using Cypress and TypeScript, following the Page Object Model and using Test Data Factories for maintainability.

    Directory Organization

    • cypress/config/: Environment configurations (env.local.ts, env.ci.ts).
    • cypress/fixtures/seeds/: Test user data (users.json).
    • cypress/support/:
      • commands/: Auth and setup helpers.
      • pages/: Page Object implementations (e.g., MappingPage.ts).
      • factories/: Data generation (e.g., MappingFactory.ts).
      • selectors/: Reusable CSS selectors.
    • cypress/specs/: The actual test files organized by feature (mapping, transformation-policy, origins).

    Page Object Pattern

    Tests interact with the UI through classes that encapsulate selector logic:

    export class MappingPage {
      static navigateToMappings() {
        cy.get('a[href="/mappings"]').click();
      }
      // ...
    }

    Test Data Factories

    Factories are used to generate consistent, valid test data objects:

    export class MappingFactory {
      static createBasicMapping(): MappingTestData {
        return {
          name: 'Test Mapping',
          description: 'Basic mapping for testing',
          hostHeaderPattern: 'example.com',
          origin: 'Test Origin'
        };
      }
    }
  4. Compare ECS and Lambda architectures

    main

    The solution supports two primary deployment architectures:

    1. ECS Architecture: Recommended for new deployments.
    2. Lambda Architecture: A serverless option using Amazon API Gateway REST API.

    Note: The S3 Object Lambda Architecture is DEPRECATED and should not be used for new deployments. It will no longer be open to new customers starting November 7, 2025. Use the ECS Architecture instead.

  5. How the Management Lambda architecture works

    main

    The Management Lambda follows a layered architecture pattern to separate concerns between API handling, business logic, and data persistence:

    1. API Gateway: Receives the HTTP request.
    2. Lambda Handler: The entry point (index.ts) which uses Middy middleware for normalization, CORS, security headers, and error handling, then routes the request via httpRouterHandler.
    3. Service Layer: Contains business logic and validation (e.g., PolicyService, OriginService).
    4. DAO Layer: Data Access Objects (e.g., TransformationPolicyDao) handle data transformation and DynamoDB interactions.
    5. DynamoDB: The persistence layer using a single-table design.
  6. Understand the V8 Custom Resource purpose and architecture

    main

    The V8 Custom Resource is a minimal implementation designed for the DIT v8 ECS architecture. It is responsible for two specific deployment-time actions:

    1. UUID Generation: Creates a unique identifier for the deployment during the CREATE phase.
    2. Metrics Collection: Sends anonymous usage metrics to an AWS endpoint during CREATE, UPDATE, or DELETE phases (if AnonymousData is set to Yes).

    Architecture Flow

    CloudFormation Stack
      └─> Custom Resource Lambda
          ├─> CREATE_UUID (on CREATE only)
          └─> SEND_METRIC (on CREATE/UPDATE/DELETE if AnonymousData=Yes)
  7. Deploy the DIT v8 Management Stack

    main

    Before deploying, ensure a Docker engine is installed locally to build the ECR image.

    1. Log in to the ECR public registry:
    aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
    1. Deploy the management stack using CDK. You must provide the AdminEmail parameter. Note that deployment typically takes approximately 15 minutes.
    overrideWarningsEnabled=false npx cdk deploy v8-Stack --parameters AdminEmail="myEmail"
    # Management stack (deployment time ~15 mins)
    overrideWarningsEnabled=false npx cdk deploy v8-Stack --parameters AdminEmail="myEmail"
  8. Run End-to-End (E2E) Tests

    main

    E2E tests validate the local deployment. These should be run after the Management and Image Processing stacks have been successfully deployed.

    Prerequisite: AWS credentials must be configured in your local environment.

    Set the STACK_REGION, STACK_NAME, and TEST_TYPE environment variables before running the test command:

    STACK_REGION={myRegion} STACK_NAME={myStack} TEST_TYPE=e2e npx jest e2e.test.ts
  9. Run Unit and End-to-End Tests

    main

    Unit Tests

    Run unit tests using npm test.

    # Run all unit tests
    npm test
    
    # Run specific test file
    npm test -- transformation-policy-dao.test.ts

    End-to-End (E2E) Tests

    E2E tests require a deployed stack and local AWS credentials with permissions for DynamoDB, Cognito, and CloudFormation. You must provide CURRENT_STACK_REGION and CURRENT_STACK_NAME environment variables.

    # Run all E2E tests
    CURRENT_STACK_REGION={myRegion} CURRENT_STACK_NAME={myStackName} npm run test:e2e
    
    # Run specific E2E test suite
    CURRENT_STACK_REGION=us-east-1 CURRENT_STACK_NAME=my-stack npm run test:e2e -- policies.test.ts
    
    # Run negative/authorization tests only
    CURRENT_STACK_REGION=us-east-1 CURRENT_STACK_NAME=my-stack npm run test:e2e -- negative.test.ts