Dynamic Image Transformation for Amazon CloudFront
repository·main·Indexed 23 days ago
https://github.com/aws-solutions/dynamic-image-transformation-for-amazon-cloudfrontA 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.
What's inside Dynamic Image Transformation for Amazon CloudFront
- 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.
Understand the Dynamic Image Transformation (DIT) v8 Architecture
mainThe 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) andAPIEndpoint(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-checkendpoint. - Key Outputs:
VpcId,ContainerDeploymentMode,ImageUri, andLoadBalancerDNS. - Key Parameters:
DeploymentSize(T-shirt sizing) andOriginOverrideHeader(header to override image origin).
Understand the E2E test structure and patterns
mainThe 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' }; } }Compare ECS and Lambda architectures
mainThe solution supports two primary deployment architectures:
- ECS Architecture: Recommended for new deployments.
- 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.
How the Management Lambda architecture works
mainThe Management Lambda follows a layered architecture pattern to separate concerns between API handling, business logic, and data persistence:
- API Gateway: Receives the HTTP request.
- Lambda Handler: The entry point (
index.ts) which uses Middy middleware for normalization, CORS, security headers, and error handling, then routes the request viahttpRouterHandler. - Service Layer: Contains business logic and validation (e.g.,
PolicyService,OriginService). - DAO Layer: Data Access Objects (e.g.,
TransformationPolicyDao) handle data transformation and DynamoDB interactions. - DynamoDB: The persistence layer using a single-table design.
Understand the V8 Custom Resource purpose and architecture
mainThe V8 Custom Resource is a minimal implementation designed for the DIT v8 ECS architecture. It is responsible for two specific deployment-time actions:
- UUID Generation: Creates a unique identifier for the deployment during the
CREATEphase. - Metrics Collection: Sends anonymous usage metrics to an AWS endpoint during
CREATE,UPDATE, orDELETEphases (ifAnonymousDatais set toYes).
Architecture Flow
CloudFormation Stack └─> Custom Resource Lambda ├─> CREATE_UUID (on CREATE only) └─> SEND_METRIC (on CREATE/UPDATE/DELETE if AnonymousData=Yes)- UUID Generation: Creates a unique identifier for the deployment during the
Deploy the DIT v8 Management Stack
mainBefore deploying, ensure a Docker engine is installed locally to build the ECR image.
- 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- Deploy the management stack using CDK. You must provide the
AdminEmailparameter. 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"Run End-to-End (E2E) Tests
mainE2E 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, andTEST_TYPEenvironment variables before running the test command:STACK_REGION={myRegion} STACK_NAME={myStack} TEST_TYPE=e2e npx jest e2e.test.tsClone the repository and prepare environment
mainClone the repository and set the
MAIN_DIRECTORYenvironment variable to the current working directory to facilitate subsequent build steps.git clone https://github.com/aws-solutions/dynamic-image-transformation-for-amazon-cloudfront.git cd dynamic-image-transformation-for-amazon-cloudfront export MAIN_DIRECTORY=$PWDRun unit tests for customizations
mainAfter making changes to the source code, run the unit tests located in the deployment directory to ensure your customizations pass.
cd $MAIN_DIRECTORY/deployment chmod +x run-unit-tests.sh && ./run-unit-tests.shRun unit tests for the V8 Custom Resource
mainTo execute the unit tests for the V8 custom resource implementation, use the following command:
npm testRun Unit and End-to-End Tests
mainUnit Tests
Run unit tests using
npm test.# Run all unit tests npm test # Run specific test file npm test -- transformation-policy-dao.test.tsEnd-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_REGIONandCURRENT_STACK_NAMEenvironment 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