An AWS CloudFront distribution that acts as a reverse proxy for LaunchDarkly client SDK and events APIs. For when network calls need to come from a specific URL instead of LaunchDarkly.
⚠️ Disclaimer: This is not an officially supported solution by LaunchDarkly.
Note: All streaming endpoints use no-cache policies for real-time updates.
- AWS CLI configured with appropriate permissions
- AWS SSO login (if using SSO)
# Check if you're logged in
aws sts get-caller-identity
# If you get "Token has expired and refresh failed", re-login:
aws sso login --profile YOUR-PROFILEDeploy the CloudFront reverse proxy directly from the AWS Console with pre-configured settings.
| Region | Launch Stack | Console Link |
|---|---|---|
| US East (N. Virginia) | ![]() |
Text Link |
| US East (Ohio) | ![]() |
Text Link |
| US West (Oregon) | ![]() |
Text Link |
| EU West (Ireland) | ![]() |
Text Link |
You can deploy to any AWS region by changing region=us-east-1 in the URL to your preferred region (e.g., region=ap-southeast-1).
Template URL: https://ld-cloudfront-proxy-templates-09-25-25.s3.amazonaws.com/cloudfront.yaml
The template is automatically updated via GitHub Actions when changes are merged to main for infrastructure/cloudfront.yaml
When using a custom domain (UseCustomDomain=true), ensure the following prerequisites are met:
The custom domain must have a public Route 53 hosted zone in the same AWS account, and Route 53 must be authoritative for the domain (the domain's NS records at the registrar must point to Route 53 nameservers).
What happens automatically:
- The template looks up the hosted zone for your domain (e.g.,
example.comforflags.example.com) - ACM creates an SSL certificate with DNS validation
- ACM automatically creates DNS validation CNAME records in Route 53
- CloudFormation waits for certificate validation to complete
- CloudFront distribution is created with the validated certificate
- DNS A record is created pointing to the CloudFront distribution
Why DNS delegation matters:
- ACM creates validation CNAME records in your Route 53 hosted zone
- For validation to succeed, public DNS queries must resolve to Route 53 (not CloudFlare, GoDaddy, etc.)
- If the domain is delegated elsewhere, ACM cannot see its own validation records and the certificate remains in
PENDING_VALIDATIONindefinitely
Verify Route 53 is authoritative for your domain:
# Check public DNS nameservers for your domain
dig +short NS yourdomain.com
# Get your Route 53 nameservers
aws route53 get-hosted-zone --id YOUR_HOSTED_ZONE_ID \
--query "DelegationSet.NameServers" --output table
# These should match!If they don't match: this will not work! Alternatively, you may update your domain registrar's NS records to point to the Route 53 nameservers shown in the above command. WARNING! This is a much larger change and should not be performed without understanding the full impact.
| Parameter | Default | Options | Description |
|---|---|---|---|
UseCustomDomain |
false |
true/false |
Use your own domain instead of CloudFront default |
DomainName |
"" |
Your domain | Required if UseCustomDomain=true (e.g., flags.my-company.com) - will auto-create certificate and DNS records |
PriceClass |
PriceClass_100 |
PriceClass_100/200/All |
Coverage: US/Canada/Europe/Asia (100) vs Global (All) |
EnableLogging |
false |
true/false |
Enable CloudFront access logging |
LoggingBucket |
"" |
S3 bucket name | Required if EnableLogging=true |
- PriceClass_100 (Recommended): US, Canada, Europe, Asia - Lowest cost
- PriceClass_200: Adds Middle East, Africa - Medium cost
- PriceClass_All: Global coverage - Highest cost
Note: Only one sub-domain address was tested (e.g.,
flags.mydomain.com). Behavior may be different or not work if you're trying to use multiple sub-domains such asmy.flags.mydomain.com.
Deployment time: ~15-20 minutes (CloudFront global propagation)
aws cloudformation deploy \
--template-file infrastructure/templates/cloudfront.yaml \
--stack-name ld-cloudfront-proxy \
--parameter-overrides \
UseCustomDomain=true \
DomainName=flags.my-company-domain.com \
PriceClass=PriceClass_100 \
--capabilities CAPABILITY_IAM \
--region us-east-1Your reverse proxy URL will be the DomainName specified in the above command, but you can also run the below command to get it:
aws cloudformation describe-stacks \
--stack-name ld-cloudfront-proxy \
--query 'Stacks[0].Outputs' \
--output tableThis will return your CloudFront domain (e.g., flags.my-company-domain.com)
Deployment time: ~15-20 minutes (CloudFront global propagation)
cd infrastructure
aws cloudformation deploy \
--template-file infrastructure/templates/cloudfront.yaml \
--stack-name ld-cloudfront-proxy \
--parameter-overrides \
UseCustomDomain=false \
PriceClass=PriceClass_100 \
EnableLogging=false \
--region us-east-1aws cloudformation describe-stacks \
--stack-name ld-cloudfront-proxy \
--query 'Stacks[0].Outputs' \
--output tableThis will return your CloudFront domain: d4a2b1c1d5e6f9.cloudfront.net
Once deployed, configure your LaunchDarkly SDKs to use your CloudFront proxy by specifying the options with the reverse proxy URL.
const LDProvider = await asyncWithLDProvider({
clientSideID: 'your-client-side-id',
context: {
kind: "device",
key: "unique-device-id"
},
options: {
baseUrl: 'https://flags.my-company-domain.com',
eventsUrl: 'https://flags.my-company-domain.com',
streamUrl: 'https://flags.my-company-domain.com
}
});NOTE: You may need to restart your application.
- CloudFront Distribution with 400+ global edge locations
- Cache Policies:
- Standard Cache Policy (5min default TTL, 10min max TTL) - for flag evaluations
- No-Cache Policy (0-1s TTL) - for streaming endpoints
- Origin Request Policy (forwards query strings and key headers)
- Response Headers Policy (CORS configuration for client-side SDKs)
clientsdk.launchdarkly.com- Default flag polling, goals, user evaluationsclientstream.launchdarkly.com- Real-time streaming, SSE endpointsevents.launchdarkly.com- Event tracking and analyticsapp.launchdarkly.com- SDK management and extended APIs
aws cloudformation deploy \
--template-file infrastructure/templates/remove-cloudfront.yaml \
--stack-name cleanup-ld-cloudfront \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides \
StackNameToDelete=ld-cloudfront-proxy \
DomainName=flags.my-company-domain.com \
CleanupDNS=true \
CleanupCertificate=true \
--region us-east-1Deletion time: ~15-20 minutes (CloudFront global propagation)
aws cloudformation describe-stack-events --stack-name ld-cloudfront-proxy --output table# Check current region
aws configure get region
# List AWS profiles
aws configure list-profiles
# Test connectivity
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE --output table| SDK Type | Supported | Notes |
|---|---|---|
| Client-side SDKs | ✅ Yes | JavaScript, React, iOS, Android, Flutter |
| Server-side SDKs | ❌ No | Java, .NET, Python, Go, Node.js (server-side) |
| Event Tracking | ✅ Yes | From any SDK type |
Note: Server-side SDKs use different endpoints (sdk.launchdarkly.com) not currently proxied by this template. The reverse proxy was not intended for server side use as the endpoints are not exposed to consumer bases.
Different LaunchDarkly projects within the same organization can use different configurations:
- Project A: Uses CloudFront proxy (this reverse proxy setup)
- Project B: Connects directly to LaunchDarkly
- Project C: Uses a different proxy or region
Each project configures its SDK independently using different SDK keys and base URLs.
This repository includes a GitHub Actions workflow that automatically updates the S3-hosted CloudFormation templates when changes are merged to main.
Remove your CloudFront proxy deployment and clean up all associated resources including DNS records and certificates.
| Region | Launch Cleanup Stack | Console Link |
|---|---|---|
| US East (N. Virginia) | ![]() |
Text Link |
| US East (Ohio) | ![]() |
Text Link |
| US West (Oregon) | ![]() |
Text Link |
| EU West (Ireland) | ![]() |
Text Link |
Before clicking cleanup, you'll need to provide:
- StackNameToDelete: Name of your CloudFront stack (default:
ld-cloudfront-proxy) - DomainName: Your custom domain (e.g.,
flags.your-company.com) - leave empty to skip DNS/cert cleanup - CleanupDNS: Set to
trueto remove Route 53 DNS records - CleanupCertificate: Set to
trueto remove ACM certificates
⚠️ Warning: This will permanently delete your CloudFront proxy and all associated resources. Make sure you're ready before proceeding!
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
