Last active
January 20, 2021 19:21
-
-
Save jgcmarins/f4ebf0bae9d1408a87836b36b976a0ef to your computer and use it in GitHub Desktop.
Deploy Razzle Apps to AWS Lambda using AWS CDK (https://aws.amazon.com/cdk/)
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
import * as SSM from '@aws-cdk/aws-ssm'; | |
import * as CDK from '@aws-cdk/core'; | |
export const getParam = (scope: CDK.Construct, name: string) => { | |
return SSM.StringParameter.valueForStringParameter(scope, name); | |
}; | |
export interface ConfigProps extends CDK.StackProps { | |
name: string; | |
} | |
export class ModeStack extends CDK.Stack { | |
public readonly mode: string = this.node.tryGetContext('mode') || 'development'; | |
public readonly Mode: string = | |
this.node.tryGetContext('mode').replace(/^\w/, (c: string) => c.toUpperCase()) || 'Development'; | |
constructor(scope: CDK.Construct, id: string, props?: ConfigProps) { | |
super(scope, id, props); | |
} | |
} |
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
import * as CDK from '@aws-cdk/core'; | |
import * as S3 from '@aws-cdk/aws-s3'; | |
import * as S3Deployment from '@aws-cdk/aws-s3-deployment'; | |
import * as Lambda from '@aws-cdk/aws-lambda'; | |
import * as APIGateway from '@aws-cdk/aws-apigateway'; | |
import * as SSM from '@aws-cdk/aws-ssm'; | |
import * as SecretsManager from '@aws-cdk/aws-secretsmanager'; | |
import { ConfigProps, getParam, ModeStack } from './helpers'; | |
export class RazzleStack extends ModeStack { | |
constructor(app: CDK.App, id: string, props: ConfigProps) { | |
super(app, id, props); | |
/** | |
* S3 bucket to the /public folder | |
*/ | |
const publicBucketName = `my-razzle-app-bucket-public-files-${this.mode}`; | |
const bucketPublicFiles = new S3.Bucket(this, publicBucketName, { | |
publicReadAccess: true, | |
bucketName: publicBucketName.toLowerCase(), | |
}); | |
/** | |
* Store S3 bucket name | |
*/ | |
new SSM.StringParameter(this, `MyRazzleAppBucketAssetsName${this.Mode}`, { | |
description: `My Razzle App S3 Bucket Name for Assets on ${this.Mode}`, | |
parameterName: `/${props.name}/S3/Assets/Name`, | |
stringValue: bucketPublicFiles.bucketName, | |
}); | |
/** | |
* Store S3 domainName name | |
*/ | |
new SSM.StringParameter(this, `MyRazzleAppBucketAssetsDomainName${this.Mode}`, { | |
description: `My Razzle App S3 Bucket DomainName for Assets on ${this.Mode}`, | |
parameterName: `/${props.name}/S3/Assets/DomainName`, | |
stringValue: bucketPublicFiles.bucketDomainName, | |
}); | |
/** | |
* Deploy public folder of build to `my-razzle-app-bucket-public-files-${this.mode}` bucket | |
*/ | |
new S3Deployment.BucketDeployment(this, `${publicBucketName}-deploy`, { | |
sources: [S3Deployment.Source.asset('./build/public')], | |
destinationBucket: bucketPublicFiles, | |
}); | |
/** | |
* Environment Variables for SSR Function | |
*/ | |
const environmentKeys = [ | |
'NODE_ENV', | |
'RAZZLE_GRAPHQL_URL', | |
'RAZZLE_MAPBOX_ACCESS_TOKEN', | |
'RAZZLE_GOOGLE_RECAPTCHA_SITE', | |
'RAZZLE_GA_ID', | |
]; | |
const environmentSecret = SecretsManager.Secret.fromSecretAttributes( | |
this, | |
`MyRazzleAppEnvironmentSecret${this.Mode}`, | |
{ | |
secretArn: getParam(this, `MyRazzleAppSecretsArn${this.Mode}`), | |
}, | |
); | |
let environment: { [key: string]: string } = {}; | |
for (const key of environmentKeys) { | |
environment[key] = environmentSecret.secretValueFromJson(key).toString(); | |
} | |
/** | |
* Razzle SSR Function | |
*/ | |
const myRazzleAppSsrFunction = new Lambda.Function(this, `MyRazzleAppSSRFunction${this.Mode}`, { | |
description: `Lambda Function that runs My Razzle App SSR on ${this.Mode}`, | |
code: Lambda.Code.fromAsset('./build', { | |
exclude: ['public', 'static', '*.json'], | |
}), | |
handler: 'server.handler', | |
runtime: Lambda.Runtime.NODEJS_12_X, | |
memorySize: 512, | |
timeout: CDK.Duration.seconds(5), | |
environment, | |
tracing: Lambda.Tracing.ACTIVE, | |
}); | |
/** | |
* Razzle ApiGateway | |
*/ | |
const razzleSsrApiGatewayName = `MyRazzleAppSSRApiGateway${this.Mode}`; | |
const api = new APIGateway.RestApi(this, razzleSsrApiGatewayName, { | |
description: `ApiGateway that exposes My Razzle App SSR on ${this.Mode}`, | |
binaryMediaTypes: ['*/*'], | |
endpointTypes: [APIGateway.EndpointType.REGIONAL], | |
deployOptions: { | |
stageName: this.mode, | |
}, | |
}); | |
const integration = new APIGateway.LambdaIntegration(myRazzleAppSsrFunction); | |
const root = api.root; | |
const pathApi = api.root.addResource('{proxy+}'); | |
root.addMethod('GET', integration); | |
pathApi.addMethod('ANY', integration); | |
/** | |
* Razzle ApiGateway ID | |
*/ | |
new SSM.StringParameter(this, `MyRazzleAppAPIGatewayRestId${this.Mode}`, { | |
description: `My Razzle App ApiGateway ID on ${this.Mode}`, | |
parameterName: `/${props.name}/APIGateway/ApiId`, | |
stringValue: api.restApiId, | |
}); | |
} | |
} |
where is ConfigProps, getParam, ModeStack
? code?
sorry, I forgot to add the helpers.ts
file
now it's updated
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've also answered here with the same code sample