mirror of
https://github.com/protomaps/PMTiles.git
synced 2026-02-04 19:01:08 +00:00
Update CloudFormation template. (#435)
* Update CloudFormation template. * Inline Lambda code into CloudFormation template. read x-distribution-name header in TileJSON response if PUBLIC_HOSTNAME is not set. * include both build-zip and build-cloudformation-stack in CI
This commit is contained in:
2
.github/workflows/actions.yml
vendored
2
.github/workflows/actions.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- run: cd js && npm install && npm run build
|
- run: cd js && npm install && npm run build
|
||||||
- run: echo "VITE_GIT_SHA=$(git rev-parse --short HEAD)" >> app/.env
|
- run: echo "VITE_GIT_SHA=$(git rev-parse --short HEAD)" >> app/.env
|
||||||
- run: cd app && npm install && ./node_modules/.bin/tsc && npm run prettier-check && ./node_modules/.bin/vite build
|
- run: cd app && npm install && ./node_modules/.bin/tsc && npm run prettier-check && ./node_modules/.bin/vite build
|
||||||
- run: cd serverless/aws && npm install && npx tsc && npm run biome-check && npm run build && cp dist/lambda_function.zip ../../app/dist
|
- run: cd serverless/aws && npm install && npx tsc && npm run biome-check && npm run build-zip && cp dist/lambda_function.zip ../../app/dist && npm run build-cloudformation-stack && cp dist/cloudformation-stack.yaml ../../app/dist
|
||||||
- run: cd serverless/cloudflare && cp wrangler.toml.example wrangler.toml && npm install && npx tsc && npm run biome-check && npm run build && cp dist/index.js ../../app/dist
|
- run: cd serverless/cloudflare && cp wrangler.toml.example wrangler.toml && npm install && npx tsc && npm run biome-check && npm run build && cp dist/index.js ../../app/dist
|
||||||
- run: cd spec/v3 && cp *.pmtiles ../../app/dist
|
- run: cd spec/v3 && cp *.pmtiles ../../app/dist
|
||||||
- run: cd js/examples && mkdir ../../app/dist/examples && cp *.html ../../app/dist/examples/
|
- run: cd js/examples && mkdir ../../app/dist/examples && cp *.html ../../app/dist/examples/
|
||||||
|
|||||||
7
serverless/aws/inline_lambda.ts
Normal file
7
serverless/aws/inline_lambda.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { yamlParse, yamlDump } from 'yaml-cfn';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
const template = yamlParse(fs.readFileSync('protomaps-template.yaml','utf-8'));
|
||||||
|
const code = fs.readFileSync('dist/index.js','utf8');
|
||||||
|
template.Resources.LambdaFunction.Properties.Code = {ZipFile:code};
|
||||||
|
fs.writeFileSync('dist/cloudformation-stack.yaml', yamlDump(template));
|
||||||
60
serverless/aws/package-lock.json
generated
60
serverless/aws/package-lock.json
generated
@@ -17,7 +17,8 @@
|
|||||||
"@types/node": "^18.11.2",
|
"@types/node": "^18.11.2",
|
||||||
"esbuild": "^0.20.0",
|
"esbuild": "^0.20.0",
|
||||||
"tsx": "^4.7.0",
|
"tsx": "^4.7.0",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4",
|
||||||
|
"yaml-cfn": "^0.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@aws-crypto/crc32": {
|
"node_modules/@aws-crypto/crc32": {
|
||||||
@@ -1991,6 +1992,13 @@
|
|||||||
"integrity": "sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==",
|
"integrity": "sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Python-2.0"
|
||||||
|
},
|
||||||
"node_modules/bowser": {
|
"node_modules/bowser": {
|
||||||
"version": "2.11.0",
|
"version": "2.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
|
||||||
@@ -2081,6 +2089,19 @@
|
|||||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"js-yaml": "bin/js-yaml.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/resolve-pkg-maps": {
|
"node_modules/resolve-pkg-maps": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||||
@@ -2545,6 +2566,19 @@
|
|||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yaml-cfn": {
|
||||||
|
"version": "0.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml-cfn/-/yaml-cfn-0.3.2.tgz",
|
||||||
|
"integrity": "sha512-MvrWhv40GKWHFGCliTGGAMwAeqIXf/bzf6WW48+xND9iMp8cTj0R8xkwM0lX/GzNN/EZKr5gP4Hx63Fn+sICoA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"js-yaml": "^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"yaml-cfn": "cli.js"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -3995,6 +4029,12 @@
|
|||||||
"integrity": "sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==",
|
"integrity": "sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"bowser": {
|
"bowser": {
|
||||||
"version": "2.11.0",
|
"version": "2.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
|
||||||
@@ -4055,6 +4095,15 @@
|
|||||||
"resolve-pkg-maps": "^1.0.0"
|
"resolve-pkg-maps": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"resolve-pkg-maps": {
|
"resolve-pkg-maps": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||||
@@ -4286,6 +4335,15 @@
|
|||||||
"version": "8.3.2",
|
"version": "8.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||||
|
},
|
||||||
|
"yaml-cfn": {
|
||||||
|
"version": "0.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml-cfn/-/yaml-cfn-0.3.2.tgz",
|
||||||
|
"integrity": "sha512-MvrWhv40GKWHFGCliTGGAMwAeqIXf/bzf6WW48+xND9iMp8cTj0R8xkwM0lX/GzNN/EZKr5gP4Hx63Fn+sICoA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"js-yaml": "^4.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,14 @@
|
|||||||
"@types/node": "^18.11.2",
|
"@types/node": "^18.11.2",
|
||||||
"esbuild": "^0.20.0",
|
"esbuild": "^0.20.0",
|
||||||
"tsx": "^4.7.0",
|
"tsx": "^4.7.0",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4",
|
||||||
|
"yaml-cfn": "^0.3.2"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tsc": "tsc --noEmit --watch",
|
"tsc": "tsc --noEmit --watch",
|
||||||
"build": "esbuild src/index.ts --target=es2020 --outfile=dist/index.mjs --format=esm --bundle --platform=node --target=node18 --external:@aws-sdk/client-s3 --external:@aws-sdk/node-http-handler --banner:js=//$(git describe --always) && cd dist && zip lambda_function.zip index.mjs",
|
"build-zip": "esbuild src/index.ts --target=es2020 --outfile=dist/index.mjs --format=esm --bundle --platform=node --target=node20 --external:@aws-sdk/client-s3 --external:@aws-sdk/node-http-handler --banner:js=//$(git describe --always) && cd dist && zip lambda_function.zip index.mjs",
|
||||||
|
"build-cloudformation-stack": "esbuild src/index.ts --target=es2020 --minify --outfile=dist/index.js --format=cjs --bundle --platform=node --target=node20 --external:@aws-sdk/client-s3 --external:@aws-sdk/node-http-handler --banner:js=//sha:$(git describe --always) && tsx inline_lambda.ts",
|
||||||
"test": "tsx ../shared/index.test.ts",
|
"test": "tsx ../shared/index.test.ts",
|
||||||
"biome": "biome check --config-path=../../js/ src --apply",
|
"biome": "biome check --config-path=../../js/ src --apply",
|
||||||
"biome-check": "biome check --config-path=../../js src"
|
"biome-check": "biome check --config-path=../../js src"
|
||||||
|
|||||||
@@ -1,36 +1,39 @@
|
|||||||
AWSTemplateFormatVersion: '2010-09-09'
|
AWSTemplateFormatVersion: '2010-09-09'
|
||||||
Description: CloudFormation template to create a protomaps infraestructure to serve tiles.
|
Description: Serve Z/X/Y tiles through CloudFront + Lambda from an existing S3 bucket.
|
||||||
Parameters:
|
Parameters:
|
||||||
BucketName:
|
BucketName:
|
||||||
Description: 'The name of the S3 bucket where you will store pmtiles files to be served (must be globally unique)'
|
Description: 'Name of an existing S3 bucket with .pmtiles tilesets. Should be in the same region as your CloudFormation stack.'
|
||||||
Type: String
|
Type: String
|
||||||
|
MinLength: 1
|
||||||
|
|
||||||
CodeBucketName:
|
AllowedOrigins:
|
||||||
Description: 'The S3 bucket name where the Lambda function code is stored (e.g., lambda-protomaps-code)'
|
Description: 'Comma-separated list of domains (e.g. example.com) allowed by browser CORS policy, or * for all origins.'
|
||||||
Type: String
|
Type: List<String>
|
||||||
|
Default: "*"
|
||||||
CodeKey:
|
|
||||||
Description: 'The S3 key for the Lambda function code (e.g., lambda_function.zip)'
|
|
||||||
Type: String
|
|
||||||
|
|
||||||
PublicHostname:
|
PublicHostname:
|
||||||
Description: 'The public custom domain name for your CloudFront distribution'
|
Description: 'Optional. Replace *.cloudfront.net in TileJSON with a custom hostname (e.g. example.com). See docs on how this value is cached.'
|
||||||
Type: String
|
Type: String
|
||||||
Default: 'None'
|
|
||||||
|
|
||||||
# ##########################################################################
|
Outputs:
|
||||||
# # S3 Bucket #
|
CloudFrontDistributionUrl:
|
||||||
# ##########################################################################
|
Description: 'URL of the CloudFront distribution'
|
||||||
|
Value: !Sub "https://${CloudFrontDistribution.DomainName}"
|
||||||
|
Export:
|
||||||
|
Name: !Sub "${AWS::StackName}-CloudFrontDistributionURL"
|
||||||
|
|
||||||
|
Conditions:
|
||||||
|
IsPublicHostnameProvided:
|
||||||
|
Fn::Not:
|
||||||
|
- Fn::Equals:
|
||||||
|
- Ref: PublicHostname
|
||||||
|
- ''
|
||||||
Resources:
|
Resources:
|
||||||
S3Bucket:
|
LogGroup:
|
||||||
Type: 'AWS::S3::Bucket'
|
Type: AWS::Logs::LogGroup
|
||||||
Properties:
|
Properties:
|
||||||
BucketName: !Ref BucketName
|
LogGroupName: !Sub "/aws/lambda/${AWS::StackName}"
|
||||||
PublicAccessBlockConfiguration:
|
RetentionInDays: 7
|
||||||
BlockPublicAcls: true
|
|
||||||
IgnorePublicAcls: true
|
|
||||||
BlockPublicPolicy: true
|
|
||||||
RestrictPublicBuckets: true
|
|
||||||
|
|
||||||
LambdaExecutionRole:
|
LambdaExecutionRole:
|
||||||
Type: 'AWS::IAM::Role'
|
Type: 'AWS::IAM::Role'
|
||||||
@@ -43,17 +46,16 @@ Resources:
|
|||||||
Service: lambda.amazonaws.com
|
Service: lambda.amazonaws.com
|
||||||
Action: sts:AssumeRole
|
Action: sts:AssumeRole
|
||||||
Policies:
|
Policies:
|
||||||
- PolicyName: LambdaBasicExecution
|
- PolicyName: !Sub "${AWS::StackName}-LambdaLoggingPolicy"
|
||||||
PolicyDocument:
|
PolicyDocument:
|
||||||
Version: '2012-10-17'
|
Version: '2012-10-17'
|
||||||
Statement:
|
Statement:
|
||||||
- Effect: Allow
|
- Effect: Allow
|
||||||
Action:
|
Action:
|
||||||
- logs:CreateLogGroup
|
|
||||||
- logs:CreateLogStream
|
- logs:CreateLogStream
|
||||||
- logs:PutLogEvents
|
- logs:PutLogEvents
|
||||||
Resource: '*'
|
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${AWS::StackName}:log-stream:*"
|
||||||
- PolicyName: S3AccessPolicy
|
- PolicyName: !Sub "${AWS::StackName}-LambdaS3AccessPolicy"
|
||||||
PolicyDocument:
|
PolicyDocument:
|
||||||
Version: '2012-10-17'
|
Version: '2012-10-17'
|
||||||
Statement:
|
Statement:
|
||||||
@@ -61,76 +63,70 @@ Resources:
|
|||||||
Action: s3:GetObject
|
Action: s3:GetObject
|
||||||
Resource: !Sub arn:aws:s3:::${BucketName}/*
|
Resource: !Sub arn:aws:s3:::${BucketName}/*
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
# Lambda Function #
|
|
||||||
##########################################################################
|
|
||||||
|
|
||||||
ProtomapsLambdaFunction:
|
LambdaFunctionUrl:
|
||||||
Type: 'AWS::Lambda::Function'
|
|
||||||
Properties:
|
|
||||||
FunctionName: protomaps
|
|
||||||
Runtime: nodejs18.x
|
|
||||||
Architectures: [arm64]
|
|
||||||
Role: !GetAtt LambdaExecutionRole.Arn
|
|
||||||
Handler: index.handler
|
|
||||||
MemorySize: 512
|
|
||||||
Environment:
|
|
||||||
Variables:
|
|
||||||
BUCKET: !Ref BucketName
|
|
||||||
PUBLIC_HOSTNAME: !Ref PublicHostname
|
|
||||||
Code:
|
|
||||||
S3Bucket: !Ref CodeBucketName
|
|
||||||
S3Key: !Ref CodeKey
|
|
||||||
|
|
||||||
ProtomapsLambdaFunctionUrl:
|
|
||||||
Type: 'AWS::Lambda::Url'
|
Type: 'AWS::Lambda::Url'
|
||||||
Properties:
|
Properties:
|
||||||
AuthType: NONE
|
AuthType: NONE
|
||||||
TargetFunctionArn: !GetAtt ProtomapsLambdaFunction.Arn
|
TargetFunctionArn: !GetAtt LambdaFunction.Arn
|
||||||
Cors:
|
|
||||||
AllowOrigins: ["*"]
|
|
||||||
InvokeMode: BUFFERED
|
InvokeMode: BUFFERED
|
||||||
|
|
||||||
ProtomapsLambdaFunctionUrlPermission:
|
LambdaFunctionUrlPermission:
|
||||||
Type: 'AWS::Lambda::Permission'
|
Type: 'AWS::Lambda::Permission'
|
||||||
Properties:
|
Properties:
|
||||||
Action: lambda:InvokeFunctionUrl
|
Action: lambda:InvokeFunctionUrl
|
||||||
FunctionName: !Ref ProtomapsLambdaFunction
|
FunctionName: !Ref LambdaFunction
|
||||||
Principal: '*'
|
Principal: '*'
|
||||||
FunctionUrlAuthType: NONE
|
FunctionUrlAuthType: NONE
|
||||||
|
|
||||||
# ##########################################################################
|
ViewerRequestCloudFrontFunction:
|
||||||
# # CloudFront::Distribution #
|
Type: AWS::CloudFront::Function
|
||||||
# ##########################################################################
|
Properties:
|
||||||
|
Name: !Sub "${AWS::StackName}-ViewerRequestCloudFrontFunction"
|
||||||
|
AutoPublish: true
|
||||||
|
FunctionCode: |
|
||||||
|
function handler(event) {
|
||||||
|
const request = event.request;
|
||||||
|
request.headers['x-distribution-domain-name'] = { value: event.context.distributionDomainName };
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
FunctionConfig:
|
||||||
|
Comment: 'Add x-distribution-domain header.'
|
||||||
|
Runtime: cloudfront-js-2.0
|
||||||
|
|
||||||
CloudFrontDistribution:
|
CloudFrontDistribution:
|
||||||
Type: 'AWS::CloudFront::Distribution'
|
Type: 'AWS::CloudFront::Distribution'
|
||||||
|
DeletionPolicy: Delete
|
||||||
Properties:
|
Properties:
|
||||||
DistributionConfig:
|
DistributionConfig:
|
||||||
Origins:
|
Origins:
|
||||||
- Id: ProtomapsLambdaOrigin
|
- Id: LambdaOrigin
|
||||||
DomainName: !Select [2, !Split ["/", !GetAtt ProtomapsLambdaFunctionUrl.FunctionUrl]]
|
DomainName: !Select [2, !Split ["/", !GetAtt LambdaFunctionUrl.FunctionUrl]]
|
||||||
CustomOriginConfig:
|
CustomOriginConfig:
|
||||||
OriginProtocolPolicy: https-only
|
OriginProtocolPolicy: https-only
|
||||||
DefaultCacheBehavior:
|
DefaultCacheBehavior:
|
||||||
TargetOriginId: ProtomapsLambdaOrigin
|
TargetOriginId: LambdaOrigin
|
||||||
ViewerProtocolPolicy: redirect-to-https
|
ViewerProtocolPolicy: redirect-to-https
|
||||||
CachePolicyId: !Ref CachePolicyId
|
CachePolicyId: !Ref CachePolicyId
|
||||||
ResponseHeadersPolicyId: !Ref ResponseHeadersPolicyId
|
ResponseHeadersPolicyId: !Ref ResponseHeadersPolicyId
|
||||||
|
OriginRequestPolicyId: b689b0a8-53d0-40ab-baf2-68738e2966ac
|
||||||
|
FunctionAssociations:
|
||||||
|
Fn::If:
|
||||||
|
- IsPublicHostnameProvided
|
||||||
|
- !Ref "AWS::NoValue"
|
||||||
|
-
|
||||||
|
- EventType: viewer-request
|
||||||
|
FunctionARN: !GetAtt ViewerRequestCloudFrontFunction.FunctionARN
|
||||||
Enabled: true
|
Enabled: true
|
||||||
HttpVersion: http2and3
|
HttpVersion: http2and3
|
||||||
Comment: "Protomaps CloudFront Distribution"
|
Comment: "CloudFront Distribution"
|
||||||
PriceClass: PriceClass_All # Change this to save cost and distribute to fewer countries. Check https://aws.amazon.com/cloudfront/pricing/
|
PriceClass: PriceClass_All # Change this to save cost and distribute to fewer countries. Check https://aws.amazon.com/cloudfront/pricing/
|
||||||
|
|
||||||
# ##########################################################################
|
|
||||||
# # CloudFront::CachePolicy #
|
|
||||||
# ##########################################################################
|
|
||||||
|
|
||||||
CachePolicyId:
|
CachePolicyId:
|
||||||
Type: 'AWS::CloudFront::CachePolicy'
|
Type: 'AWS::CloudFront::CachePolicy'
|
||||||
Properties:
|
Properties:
|
||||||
CachePolicyConfig:
|
CachePolicyConfig:
|
||||||
Name: 'CachingOptimized'
|
Name: !Sub "${AWS::StackName}-CachePolicyConfig"
|
||||||
DefaultTTL: 86400
|
DefaultTTL: 86400
|
||||||
MaxTTL: 31536000
|
MaxTTL: 31536000
|
||||||
MinTTL: 0
|
MinTTL: 0
|
||||||
@@ -146,42 +142,43 @@ Resources:
|
|||||||
|
|
||||||
ResponseHeadersPolicyId:
|
ResponseHeadersPolicyId:
|
||||||
Type: 'AWS::CloudFront::ResponseHeadersPolicy'
|
Type: 'AWS::CloudFront::ResponseHeadersPolicy'
|
||||||
|
# DeletionPolicy: Delete
|
||||||
Properties:
|
Properties:
|
||||||
ResponseHeadersPolicyConfig:
|
ResponseHeadersPolicyConfig:
|
||||||
Name: 'protomaps-cors'
|
Name: !Sub "${AWS::StackName}-ResponseHeadersPolicyConfig"
|
||||||
CorsConfig:
|
CorsConfig:
|
||||||
AccessControlAllowOrigins:
|
AccessControlAllowOrigins:
|
||||||
Items:
|
Items: !Ref AllowedOrigins
|
||||||
- 'https://example.com' # Replace with your allowed origin
|
|
||||||
AccessControlAllowHeaders:
|
AccessControlAllowHeaders:
|
||||||
Items:
|
Items:
|
||||||
- '*'
|
- '*'
|
||||||
AccessControlAllowMethods:
|
AccessControlAllowMethods:
|
||||||
Items:
|
Items:
|
||||||
- GET
|
- GET
|
||||||
- POST
|
- HEAD
|
||||||
- OPTIONS
|
- OPTIONS
|
||||||
AccessControlAllowCredentials: false # Set to true if you want to include credentials
|
AccessControlExposeHeaders:
|
||||||
|
Items:
|
||||||
|
- ETag
|
||||||
|
AccessControlAllowCredentials: false # Set to true if you want to include credentials
|
||||||
OriginOverride: true
|
OriginOverride: true
|
||||||
Comment: 'CORS policy for Protomaps'
|
Comment: 'CORS policy for Protomaps'
|
||||||
DeletionPolicy: Delete
|
|
||||||
|
|
||||||
Outputs:
|
|
||||||
BucketNameOutput:
|
|
||||||
Description: 'URL of the S3 bucket'
|
|
||||||
Value: !Sub "https://s3.console.aws.amazon.com/s3/buckets/${BucketName}"
|
|
||||||
Export:
|
|
||||||
Name: !Sub "${AWS::StackName}-S3BucketURL"
|
|
||||||
|
|
||||||
LambdaFunctionUrl:
|
|
||||||
Description: 'URL of the Lambda function'
|
|
||||||
Value: !GetAtt ProtomapsLambdaFunctionUrl.FunctionUrl
|
|
||||||
Export:
|
|
||||||
Name: !Sub "${AWS::StackName}-LambdaFunctionURL"
|
|
||||||
|
|
||||||
CloudFrontDistributionUrl:
|
|
||||||
Description: 'URL of the CloudFront distribution'
|
|
||||||
Value: !Sub "https://${CloudFrontDistribution.DomainName}"
|
|
||||||
Export:
|
|
||||||
Name: !Sub "${AWS::StackName}-CloudFrontDistributionURL"
|
|
||||||
|
|
||||||
|
LambdaFunction:
|
||||||
|
Type: 'AWS::Lambda::Function'
|
||||||
|
Properties:
|
||||||
|
FunctionName: !Sub "${AWS::StackName}-LambdaFunction"
|
||||||
|
Runtime: nodejs20.x
|
||||||
|
Architectures: [arm64]
|
||||||
|
Role: !GetAtt LambdaExecutionRole.Arn
|
||||||
|
Handler: index.handler
|
||||||
|
MemorySize: 512
|
||||||
|
LoggingConfig:
|
||||||
|
LogGroup: !Ref LogGroup
|
||||||
|
Environment:
|
||||||
|
Variables:
|
||||||
|
BUCKET: !Ref BucketName
|
||||||
|
PUBLIC_HOSTNAME: !Ref PublicHostname
|
||||||
|
Code:
|
||||||
|
S3Bucket: !Ref BucketName
|
||||||
|
S3Key: lambda_function.zip
|
||||||
|
|||||||
@@ -160,7 +160,12 @@ export const handlerRaw = async (
|
|||||||
const header = await p.getHeader();
|
const header = await p.getHeader();
|
||||||
|
|
||||||
if (!tile) {
|
if (!tile) {
|
||||||
if (!process.env.PUBLIC_HOSTNAME) {
|
if (
|
||||||
|
!(
|
||||||
|
process.env.PUBLIC_HOSTNAME ||
|
||||||
|
event.headers["x-distribution-domain-name"]
|
||||||
|
)
|
||||||
|
) {
|
||||||
return apiResp(
|
return apiResp(
|
||||||
501,
|
501,
|
||||||
"PUBLIC_HOSTNAME must be set for TileJSON",
|
"PUBLIC_HOSTNAME must be set for TileJSON",
|
||||||
@@ -173,7 +178,9 @@ export const handlerRaw = async (
|
|||||||
const t = tileJSON(
|
const t = tileJSON(
|
||||||
header,
|
header,
|
||||||
await p.getMetadata(),
|
await p.getMetadata(),
|
||||||
process.env.PUBLIC_HOSTNAME,
|
process.env.PUBLIC_HOSTNAME ||
|
||||||
|
event.headers["x-distribution-domain-name"] ||
|
||||||
|
"",
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user