Package: deploy-time-build
Deploy-time BuildAWS CDK L3 construct that enables you to build apps during deploy time, aiming to resolve a few problems when we deploy frontend apps from CDK.UsageInstall from npm:npmideploy-time-buildBuild Node.js appsUse the following code to build Node.js apps like React frontend:import{NodejsBuild}from'deploy-time-build';declareconstapi:apigateway.RestApi;declareconstdestinationBucket:s3.IBucket;declareconstdistribution:cloudfront.IDistribution;newNodejsBuild(this,'ExampleBuild',{assets:[{path:'example-app',exclude:['dist','node_modules'],},],destinationBucket,distribution,outputSourceDirectory:'dist',buildCommands:['npm ci','npm run build'],buildEnvironment:{VITE_API_ENDPOINT:api.url,},});Note that it is possible to pass environment variableVITE_API_ENDPOINT: api.urlto the construct, which is resolved on deploy time, and injected to the build environment (a vite process in this case.)
The resulting build artifacts will be deployed todestinationBucketusing as3-deployment.BucketDeploymentconstruct.You can specify multiple input assets byassetsproperty. These assets are extracted to respective sub directories. For example, assume you specified assets like the following:assets:[{//directorycontainingsourcecodeandpackage.jsonpath:'example-app',exclude:['dist','node_modules'],commands:['npm install'],},{//directorythatisalsorequiredforthebuildpath:'module1',},],Then, the extracted directories will be located as the following:.# a temporary directory (automatically created)├──example-app# extracted example-app assets│├──src/# dist or node_modules directories are excluded even if they exist locally.│├──package.json# npm install will be executed since its specified in `commands` property.│└──package-lock.json
└──module1# extracted module1 assetsYou can also override the path where assets are extracted byextractPathproperty for each asset.Please also checkthe example directoryfor a complete example.Allowing access from the build environment to other AWS resourcesSinceNodejsBuildconstruct implementsiam.IGrantableinterface, you can usegrant*method of other constructs to allow access from the build environment.declareconstsomeBucket:s3.IBucket;declareconstbuild:NodejsBuild;someBucket.grantReadWrite(build);You can also useiam.Grantclass to allow any actions and resources.declareconstbuild:NodejsBuild;iam.Grant.addToPrincipal({grantee:build,actions:['s3:ListBucket'],resources:['*']})Build SOCI index for a container imageSeekable OCI (SOCI)is a way to help start tasks faster for Amazon ECS tasks on Fargate 1.4.0. You can build and push a SOCI index to use the feature by the following CDK code:import{SociIndexBuild}from'deploy-time-build;constasset=newDockerImageAsset(this,'Image',{directory:'example-image'});newSociIndexBuild(this,'Index',{imageTag:asset.assetHash,repository:asset.repository});//orusingautilitymethodSociIndexBuild.fromDockerImageAsset(this,'Index2',asset);//UsetheassetforECSFargatetasksimport{AssetImage}from'aws-cdk-lib/aws-ecs';constassetImage=AssetImage.fromDockerImageAsset(asset);The below image is the architecture forSociIndexBuildconstruct. We currently usesoci-wrapperto build and push SOCI indices.Motivation - why do we need theNodejsBuildconstruct?I talked about why this construct can be useful in some situations at CDK Day 2023. See the recording or slides below:Recording|SlidesConsiderationsSince this construct builds your frontend apps every time you deploy the stack and there is any change in input assets (and currently there's even no build cache in the Lambda function!), the time a deployment takes tends to be longer (e.g. a few minutes even for the simple app inexampledirectory.) This might results in worse developer experience if you want to deploy changes frequently (imaginecdk watchdeployment always re-build your frontend app).To mitigate this issue, you can separate the stack for frontend construct from other stacks especially for a dev environment. Another solution would be to set a fixed string as an asset hash, and avoid builds on every deployment.assets:[{path:'../frontend',exclude:['node_modules','dist'],commands:['npm ci'],//Setafixedstringasaassethashtopreventdeployingchanges.//Thiscanbeusefulforanenvironmentyouusetodeveloplocally.assetHash:'frontend_asset',},],DevelopmentCommands for maintainers:# run test locallyyarntsc-ptsconfig.dev.json
yarninteg-runner
yarninteg-runner--update-on-failed