|
1 | | -# terraform-aws-template |
| 1 | +# AWS Serverless Image Handler Terraform Module |
2 | 2 |
|
3 | | -[](https://github.com/DNXLabs/terraform-aws-template/actions) |
4 | | -[](https://github.com/DNXLabs/terraform-aws-template/blob/master/LICENSE) |
| 3 | +This Terraform module deploys a serverless image transformation solution using AWS Lambda and CloudFront, converted from the AWS CloudFormation template for Dynamic Image Transformation. |
5 | 4 |
|
6 | | -<!--- BEGIN_TF_DOCS ---> |
| 5 | +## Features |
7 | 6 |
|
8 | | -## Requirements |
| 7 | +- **Dynamic Image Transformation**: Resize, crop, rotate, and apply filters to images on-the-fly |
| 8 | +- **CloudFront CDN**: Global content delivery with edge caching |
| 9 | +- **Auto WebP**: Automatically convert images to WebP format when supported by client |
| 10 | +- **CORS Support**: Configurable cross-origin resource sharing |
| 11 | +- **Signature Validation**: Optional URL signature validation for secure image requests |
| 12 | +- **Fallback Images**: Display default images on errors instead of JSON responses |
| 13 | +- **S3 Object Lambda**: Support for processing images larger than 6MB |
| 14 | +- **CloudWatch Logging**: Configurable log retention and monitoring |
| 15 | + |
| 16 | +## Architecture |
| 17 | + |
| 18 | +The module creates: |
| 19 | +- AWS Lambda function for image processing |
| 20 | +- CloudFront distribution for content delivery |
| 21 | +- CloudFront cache and origin request policies |
| 22 | +- CloudFront function for request modification |
| 23 | +- IAM roles and policies for Lambda execution |
| 24 | +- S3 bucket for CloudFront access logs |
| 25 | +- CloudWatch log groups with configurable retention |
| 26 | + |
| 27 | +## Usage |
| 28 | + |
| 29 | +### Basic Example |
| 30 | + |
| 31 | +```hcl |
| 32 | +module "image_handler" { |
| 33 | + source = "./modules/aws-serverless-image-handler-1.0.0" |
9 | 34 |
|
10 | | -| Name | Version | |
11 | | -|------|---------| |
12 | | -| terraform | >= 0.13.0 | |
| 35 | + name = "staging-image-processor" |
| 36 | + environment_name = "staging" |
| 37 | + source_buckets = "my-images-bucket,my-other-images-bucket" |
| 38 | + |
| 39 | + cors_enabled = true |
| 40 | + cors_origin = "*" |
| 41 | + auto_webp = true |
| 42 | + |
| 43 | + tags = { |
| 44 | + Environment = "staging" |
| 45 | + Project = "MyProject" |
| 46 | + } |
| 47 | +} |
| 48 | +``` |
13 | 49 |
|
14 | | -## Providers |
| 50 | +### Complete Example with All Options |
15 | 51 |
|
16 | | -No provider. |
| 52 | +```hcl |
| 53 | +module "image_handler" { |
| 54 | + source = "./modules/aws-serverless-image-handler-1.0.0" |
17 | 55 |
|
18 | | -## Inputs |
| 56 | + name = "prod-image-processor" |
| 57 | + environment_name = "production" |
| 58 | + source_buckets = "prod-images-bucket" |
| 59 | + |
| 60 | + # CORS |
| 61 | + cors_enabled = true |
| 62 | + cors_origin = "https://example.com" |
| 63 | + |
| 64 | + # Demo UI |
| 65 | + deploy_demo_ui = false |
| 66 | + |
| 67 | + # Logging |
| 68 | + log_retention_days = 180 |
| 69 | + |
| 70 | + # Image Processing |
| 71 | + auto_webp = true |
| 72 | + |
| 73 | + # Security |
| 74 | + enable_signature = true |
| 75 | + secrets_manager_secret = "image-handler-secret" |
| 76 | + secrets_manager_key = "signature-key" |
| 77 | + |
| 78 | + # Fallback |
| 79 | + enable_default_fallback_image = true |
| 80 | + fallback_image_s3_bucket = "fallback-images-bucket" |
| 81 | + fallback_image_s3_key = "default-fallback.jpg" |
| 82 | + |
| 83 | + # CloudFront |
| 84 | + cloudfront_price_class = "PriceClass_100" # US, Europe, Israel |
| 85 | + origin_shield_region = "ap-southeast-2" |
| 86 | + |
| 87 | + # Lambda |
| 88 | + lambda_memory_size = 1536 |
| 89 | + lambda_timeout = 29 |
| 90 | + |
| 91 | + # Large Images |
| 92 | + enable_s3_object_lambda = true |
| 93 | + |
| 94 | + tags = { |
| 95 | + Environment = "production" |
| 96 | + Project = "MyProject" |
| 97 | + ManagedBy = "Terraform" |
| 98 | + } |
| 99 | +} |
| 100 | +``` |
19 | 101 |
|
20 | | -No input. |
| 102 | +<!-- BEGIN_TF_DOCS --> |
| 103 | +## Variables |
| 104 | + |
| 105 | +| Name | Description | Type | Default | Required | |
| 106 | +|------|-------------|------|---------|:--------:| |
| 107 | +| name | Name prefix for resources | `string` | n/a | yes | |
| 108 | +| environment_name | Environment name | `string` | n/a | yes | |
| 109 | +| source_buckets | Comma-separated list of S3 buckets with source images | `string` | n/a | yes | |
| 110 | +| cors_enabled | Enable CORS | `bool` | `false` | no | |
| 111 | +| cors_origin | CORS origin value | `string` | `"*"` | no | |
| 112 | +| deploy_demo_ui | Deploy demo UI | `bool` | `false` | no | |
| 113 | +| log_retention_days | CloudWatch log retention in days | `number` | `180` | no | |
| 114 | +| auto_webp | Auto-convert to WebP | `bool` | `false` | no | |
| 115 | +| enable_signature | Enable URL signature validation | `bool` | `false` | no | |
| 116 | +| secrets_manager_secret | Secrets Manager secret name | `string` | `""` | no | |
| 117 | +| secrets_manager_key | Secrets Manager secret key | `string` | `""` | no | |
| 118 | +| enable_default_fallback_image | Enable fallback image | `bool` | `false` | no | |
| 119 | +| fallback_image_s3_bucket | Fallback image S3 bucket | `string` | `""` | no | |
| 120 | +| fallback_image_s3_key | Fallback image S3 key | `string` | `""` | no | |
| 121 | +| cloudfront_price_class | CloudFront price class | `string` | `"PriceClass_All"` | no | |
| 122 | +| origin_shield_region | Origin Shield region or 'Disabled' | `string` | `"Disabled"` | no | |
| 123 | +| lambda_memory_size | Lambda memory size in MB | `number` | `1024` | no | |
| 124 | +| lambda_timeout | Lambda timeout in seconds | `number` | `29` | no | |
| 125 | +| enable_s3_object_lambda | Enable S3 Object Lambda | `bool` | `false` | no | |
| 126 | +| enable_solution_metrics | Enable anonymous usage metrics collection | `bool` | `false` | no | |
| 127 | +| tags | Additional tags | `map(string)` | `{}` | no | |
21 | 128 |
|
22 | 129 | ## Outputs |
23 | 130 |
|
24 | | -No output. |
| 131 | +| Name | Description | |
| 132 | +|------|-------------| |
| 133 | +| cloudfront_distribution_id | CloudFront distribution ID | |
| 134 | +| cloudfront_domain_name | CloudFront domain name | |
| 135 | +| api_endpoint | API endpoint URL | |
| 136 | +| lambda_function_arn | Lambda function ARN | |
| 137 | +| lambda_function_name | Lambda function name | |
| 138 | +| cloudfront_logs_bucket | S3 bucket for CloudFront logs | |
| 139 | +<!-- END_TF_DOCS --> |
| 140 | + |
| 141 | +## Image Transformation Examples |
| 142 | + |
| 143 | +Once deployed, you can transform images using URL parameters: |
| 144 | + |
| 145 | +### Basic Resize |
| 146 | +``` |
| 147 | +https://<cloudfront-domain>/image.jpg?width=300&height=200 |
| 148 | +``` |
| 149 | + |
| 150 | +### Crop and Format |
| 151 | +``` |
| 152 | +https://<cloudfront-domain>/image.jpg?width=400&height=400&fit=cover&format=webp |
| 153 | +``` |
| 154 | + |
| 155 | +### Rotate and Flip |
| 156 | +``` |
| 157 | +https://<cloudfront-domain>/image.jpg?rotate=90&flip=true |
| 158 | +``` |
25 | 159 |
|
26 | | -<!--- END_TF_DOCS ---> |
| 160 | +### Grayscale |
| 161 | +``` |
| 162 | +https://<cloudfront-domain>/image.jpg?grayscale=true |
| 163 | +``` |
27 | 164 |
|
28 | | -## Authors |
| 165 | +## Important Notes |
29 | 166 |
|
30 | | -Module managed by [DNX Solutions](https://github.com/DNXLabs). |
| 167 | +### Lambda Code Deployment |
| 168 | + |
| 169 | +**IMPORTANT**: This module uses the official AWS Solutions Lambda package for image processing. The Lambda function is automatically deployed from: |
| 170 | + |
| 171 | +- S3 Bucket: `solutions-{region}` |
| 172 | +- S3 Key: `dynamic-image-transformation-for-amazon-cloudfront/v7.0.7/...` |
| 173 | + |
| 174 | +No manual Lambda code deployment is required. The module handles this automatically. |
| 175 | + |
| 176 | +### Source Bucket Permissions |
| 177 | + |
| 178 | +Ensure the Lambda function has appropriate permissions to read from your source S3 buckets. |
| 179 | + |
| 180 | +### CloudFront Caching |
| 181 | + |
| 182 | +The module configures CloudFront to cache transformed images. The cache key includes: |
| 183 | +- Query parameters (width, height, format, etc.) |
| 184 | +- Origin header |
| 185 | +- Accept header (when auto_webp is enabled) |
| 186 | + |
| 187 | +## Requirements |
| 188 | + |
| 189 | +- Terraform >= 1.0 |
| 190 | +- AWS Provider >= 4.0 |
31 | 191 |
|
32 | 192 | ## License |
33 | 193 |
|
34 | | -Apache 2 Licensed. See [LICENSE](https://github.com/DNXLabs/terraform-aws-template/blob/master/LICENSE) for full details. |
| 194 | +This module is based on the AWS CloudFormation template for Dynamic Image Transformation. |
| 195 | + |
| 196 | +## Conversion Notes |
| 197 | + |
| 198 | +This module was converted from CloudFormation template SO0023 v7.0.7. Key differences: |
| 199 | +- Simplified architecture (removed API Gateway complexity where possible) |
| 200 | +- Uses Lambda Function URLs for simpler integration |
| 201 | +- Maintains CloudFormation feature parity for core image transformation |
| 202 | +- Configurable through Terraform variables instead of CloudFormation parameters |
0 commit comments