-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
infrastructure wiring for graphiql. Note new param required before th…
…is will deploy.
- Loading branch information
Showing
4 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const hostingDomain:Record<string,string> = { | ||
"PROD-AARDVARK": "graphiql.capi.gutools.co.uk", | ||
"CODE-AARDVARK": "graphiql.capi.code.dev-gutools.co.uk", | ||
"TEST": "graphiql.capi.test.dev-gutools.co.uk" | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import {Construct} from "constructs"; | ||
import type { GuStack } from "@guardian/cdk/lib/constructs/core"; | ||
import { GuStringParameter } from "@guardian/cdk/lib/constructs/core"; | ||
import { CfnOutput, Duration } from "aws-cdk-lib"; | ||
import { Certificate } from "aws-cdk-lib/aws-certificatemanager"; | ||
import { | ||
Distribution, | ||
PriceClass, | ||
ViewerProtocolPolicy | ||
} from "aws-cdk-lib/aws-cloudfront"; | ||
import { RestApiOrigin, S3Origin } from "aws-cdk-lib/aws-cloudfront-origins"; | ||
import { Effect, PolicyStatement, ServicePrincipal } from "aws-cdk-lib/aws-iam"; | ||
import { Bucket } from "aws-cdk-lib/aws-s3"; | ||
import {hostingDomain} from "./constants"; | ||
|
||
interface GraphiqlExplorerProps { | ||
appName: string; | ||
|
||
} | ||
|
||
export class GraphiqlExplorer extends Construct { | ||
constructor(scope: GuStack, id: string, props: GraphiqlExplorerProps) { | ||
super(scope, id); | ||
|
||
//We can't create the cert here, because it must live in us-east-1 for Cloudfront to use it. | ||
const hostingCertArn = new GuStringParameter(scope, "ExplorerCertArn", { | ||
fromSSM: true, | ||
default: `/${scope.stage}/${scope.stack}/${props.appName}/GlobalCertArn`, | ||
description: `Cert to use for graphiql ${scope.stage}. This must reside in us-east-1`, | ||
}); | ||
const certificate = Certificate.fromCertificateArn(this, "CapiExplorerCert", hostingCertArn.valueAsString); | ||
|
||
const staticBucketNameParam = new GuStringParameter(scope, "StaticBucketName", { | ||
fromSSM: true, | ||
default: `/account/services/static.serving.bucket`, | ||
description: "SSM parameter giving the name of a bucket which is to be used for static hosting" | ||
}); | ||
|
||
const hostingBucket = Bucket.fromBucketName(this, "StaticBucket", staticBucketNameParam.valueAsString); | ||
|
||
const distro = new Distribution(scope, "GraphiQLDistro", { | ||
defaultRootObject: "index.html", | ||
certificate, | ||
domainNames: [hostingDomain[scope.stage]], | ||
defaultBehavior: { | ||
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS, | ||
origin: new S3Origin(hostingBucket, { | ||
originPath: `${scope.stage}/${props.appName}` | ||
}), | ||
}, | ||
enableIpv6: true, | ||
enabled: true, | ||
priceClass: PriceClass.PRICE_CLASS_100, //US & EU only | ||
/* | ||
we must tell Cloudfront to redirect 403 (forbidden/not present) exceptions from S3 into a 200 response from /index in order for react-router to work. | ||
*/ | ||
errorResponses: [ | ||
{ | ||
httpStatus: 403, | ||
responseHttpStatus: 200, | ||
responsePagePath: "/index.html", | ||
ttl: Duration.seconds(5), | ||
} | ||
] | ||
}); | ||
|
||
hostingBucket.addToResourcePolicy(new PolicyStatement({ | ||
effect: Effect.ALLOW, | ||
principals: [ | ||
new ServicePrincipal("cloudfront.amazonaws.com"), | ||
], | ||
actions: ["s3:GetObject"], | ||
resources: [`arn:aws:s3:::${hostingBucket.bucketName}/${scope.stage}/${props.appName}`], | ||
conditions: { | ||
"StringEquals": { | ||
"AWS:SourceArn": `arn:aws:cloudfront::${scope.account}:distribution/${distro.distributionId}` | ||
} | ||
} | ||
})); | ||
|
||
new CfnOutput(this, "DistroUrlOut", { | ||
value: distro.distributionDomainName, | ||
}); | ||
} | ||
} |