Created
June 16, 2021 15:20
-
-
Save spg/a8ad5676b401cb951eac34e73aed7437 to your computer and use it in GitHub Desktop.
Cloudfront CDK sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ======= WAF | |
// Based on this example: https://docs.aws.amazon.com/waf/latest/developerguide/waf-using-managed-rule-groups.html | |
const acl = new waf.CfnWebACL(this, "WebAcl", { | |
defaultAction: { allow: {} }, | |
scope: "REGIONAL", | |
visibilityConfig: { | |
cloudWatchMetricsEnabled: true, | |
metricName: "MyMetric", | |
sampledRequestsEnabled: true, | |
}, | |
rules: [ | |
{ | |
name: "AWS-AWSManagedRulesCommonRuleSet", | |
priority: 0, | |
overrideAction: { none: {} }, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: "MetricForAMRCRS", | |
}, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: "AWS", | |
name: "AWSManagedRulesCommonRuleSet", | |
excludedRules: [ | |
// Blocks file saves in the Botpress Code Editor | |
{ name: "EC2MetaDataSSRF_BODY" }, | |
{ name: "GenericLFI_BODY" }, | |
// Blocks the webchat via "Open Chat" | |
{ name: "GenericRFI_QUERYARGUMENTS" }, | |
// Blocks saving large questions in the QnA module | |
{ name: "SizeRestrictions_BODY" }, | |
{ name: "GenericRFI_BODY" }, | |
], | |
}, | |
}, | |
}, | |
{ | |
name: "AWS-AWSManagedRulesSQLiRuleSet", | |
priority: 1, | |
overrideAction: { none: {} }, | |
visibilityConfig: { | |
sampledRequestsEnabled: true, | |
cloudWatchMetricsEnabled: true, | |
metricName: "MetricForAMRSQLRS", | |
}, | |
statement: { | |
managedRuleGroupStatement: { | |
vendorName: "AWS", | |
name: "AWSManagedRulesSQLiRuleSet", | |
}, | |
}, | |
}, | |
], | |
}); | |
new waf.CfnWebACLAssociation(this, "AclAssociation1", { | |
webAclArn: acl.attrArn, | |
resourceArn: loadBalancer.loadBalancerArn, | |
}); | |
// CloudFront | |
const originSubdomain = "your-origin"; | |
const logBucket = new s3.Bucket(this, "CFLogBucket", { | |
lifecycleRules: [{ expiration: cdk.Duration.days(30) }], | |
removalPolicy: cdk.RemovalPolicy.DESTROY, | |
}); | |
const assetsCachePolicy = new cloudfront.CfnCachePolicy( | |
this, | |
"AssetsCachePolicy", | |
{ | |
cachePolicyConfig: { | |
minTtl: 3600, | |
defaultTtl: 3600, | |
maxTtl: 3600, | |
name: "ProjectAssets", | |
parametersInCacheKeyAndForwardedToOrigin: { | |
queryStringsConfig: { queryStringBehavior: "none" }, | |
headersConfig: { headerBehavior: "none" }, | |
cookiesConfig: { cookieBehavior: "none" }, | |
enableAcceptEncodingGzip: false, | |
enableAcceptEncodingBrotli: false, | |
}, | |
}, | |
} | |
); | |
const assetsRequestPolicy = new cloudfront.CfnOriginRequestPolicy( | |
this, | |
"AssetsRequestPolicy", | |
{ | |
originRequestPolicyConfig: { | |
name: "ProjectAssets", | |
cookiesConfig: { cookieBehavior: "all" }, | |
headersConfig: { | |
headerBehavior: "whitelist", | |
headers: ["Accept"], | |
}, | |
queryStringsConfig: { queryStringBehavior: "all" }, | |
}, | |
} | |
); | |
const cloudFrontCertificate = acm.Certificate.fromCertificateArn( | |
this, | |
"CloudFrontCertificate", | |
// Certificate must be created in another stack in us-east-1 region | |
"arn:aws:acm:us-east-1:XXXXXXXXXX:certificate/XXXXXXX-7a7a-44d0-99bc-XXXXXXXXX" | |
); | |
const dist = new cloudfront.Distribution(this, "Dist", { | |
defaultBehavior: { | |
origin: new origins.LoadBalancerV2Origin(loadBalancer), | |
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL, | |
}, | |
domainNames: [`your-subdomain.${domain}`], | |
certificate: cloudFrontCertificate, | |
logBucket, | |
priceClass: cloudfront.PriceClass.PRICE_CLASS_100, | |
}); | |
const originId = "BotpressWebServer"; | |
const cfnDist = dist.node.defaultChild as cloudfront.CfnDistribution; | |
cfnDist.addPropertyOverride( | |
"DistributionConfig.DefaultCacheBehavior.TargetOriginId", | |
originId | |
); | |
cfnDist.addPropertyOverride("DistributionConfig.Origins", [ | |
{ | |
CustomOriginConfig: { | |
OriginProtocolPolicy: "https-only", | |
}, | |
DomainName: `${originSubdomain}.${domain}`, | |
Id: originId, | |
}, | |
]); | |
cfnDist.addDeletionOverride( | |
"DistributionConfig.DefaultCacheBehavior.ForwardedValues" | |
); | |
cfnDist.addPropertyOverride("DistributionConfig.CacheBehaviors", [ | |
{ | |
AllowedMethods: ["GET", "HEAD", "OPTIONS"], | |
PathPattern: "/assets/*", | |
TargetOriginId: originId, | |
ViewerProtocolPolicy: "allow-all", | |
CachePolicyId: assetsCachePolicy.attrId, | |
OriginRequestPolicyId: assetsRequestPolicy.attrId, | |
}, | |
{ | |
AllowedMethods: ["GET", "HEAD", "OPTIONS"], | |
PathPattern: "/lite/mybot/env.js", | |
TargetOriginId: originId, | |
ViewerProtocolPolicy: "allow-all", | |
CachePolicyId: assetsCachePolicy.attrId, | |
OriginRequestPolicyId: assetsRequestPolicy.attrId, | |
}, | |
{ | |
AllowedMethods: ["GET", "HEAD", "OPTIONS"], | |
PathPattern: "/api/v1/modules", | |
TargetOriginId: originId, | |
ViewerProtocolPolicy: "allow-all", | |
CachePolicyId: assetsCachePolicy.attrId, | |
OriginRequestPolicyId: assetsRequestPolicy.attrId, | |
}, | |
{ | |
AllowedMethods: ["GET", "HEAD", "OPTIONS"], | |
PathPattern: "/lite/mybot/", | |
TargetOriginId: originId, | |
ViewerProtocolPolicy: "allow-all", | |
CachePolicyId: assetsCachePolicy.attrId, | |
OriginRequestPolicyId: assetsRequestPolicy.attrId, | |
}, | |
{ | |
AllowedMethods: ["GET", "HEAD", "OPTIONS"], | |
PathPattern: "/api/v1/bots/mybot/mod/channel-web/botInfo", | |
TargetOriginId: originId, | |
ViewerProtocolPolicy: "allow-all", | |
CachePolicyId: assetsCachePolicy.attrId, | |
OriginRequestPolicyId: assetsRequestPolicy.attrId, | |
}, | |
]); | |
cfnDist.addPropertyOverride( | |
"DistributionConfig.DefaultCacheBehavior.CachePolicyId", | |
// Managed-CachingDisabled | |
"4135ea2d-6df8-44a3-9df3-4b5a84be39ad" | |
); | |
cfnDist.addPropertyOverride( | |
"DistributionConfig.DefaultCacheBehavior.OriginRequestPolicyId", | |
// Managed-AllViewer | |
"216adef6-5c7f-47e4-b989-5492eafa07d3" | |
); | |
// Route53 | |
new route53.ARecord(this, "DistRecord", { | |
zone: hostedZone, | |
recordName: "your-subdomain", | |
target: route53.RecordTarget.fromAlias( | |
new route53Targets.CloudFrontTarget(dist) | |
), | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment