Is it possible to run an external build command as part of a CDK stack sequence? Intention: 1) create a rest API, 2) write rest URL to config file, 3) build and deploy a React app:
import apigateway = require('@aws-cdk/aws-apigateway');
import cdk = require('@aws-cdk/core');
import fs = require('fs')
import s3deployment = require('@aws-cdk/aws-s3-deployment');
export class MyStack extends cdk.Stack {
const restApi = new apigateway.RestApi(this, ..);
fs.writeFile('src/app-config.json',
JSON.stringify({ "api": restApi.deploymentStage.urlForPath('/myResource') }))
// TODO locally run 'npm run build', create 'build' folder incl rest api config
const websiteBucket = new s3.Bucket(this, ..)
new s3deployment.BucketDeployment(this, .. {
sources: [s3deployment.Source.asset('build')],
destinationBucket: websiteBucket
})
}
To create an AWS CDK project you can initialize it using the cdk init command. Here you specify your desired template and programming language, see the example for possible options:
At the time of writing it's very important to keep all of the aws-cdk packages the same version. If the versions of cdk packages in our package.json file are different we get nasty, hard to debug errors. If you want to learn more about version management in CDK, I've written an article-How to manage Package Versions in AWS CDK.
The AWS CDK Explorer finds apps in the project root directory and its direct subdirectories. When you perform the first several steps of the tutorial, you might notice that the last command you execute is cdk synth , which generates the tree.json file.
One method is CDK bundling. The lambda.Code.fromAsset () method takes a second optional argument, AssetOptions, which contains the bundling parameter. With this bundling parameter, we can tell the AWS CDK to perform steps prior to staging the files in the cloud assembly.
Unfortunately, it is not possible, as the necessary references are only available after deploy and therefore after you try to write the file (the file will contain cdk tokens).
I personally have solved this problem by telling cdk to output the apigateway URLs to a file and then parse it after the deploy to upload it so a S3 bucket, to do it you need:
cdk deploy -O ./cdk.out/deploy-output.json
./cdk.out/deploy-output.json
you will find a JSON object with a key for each stack that produced an output (e.g. your stack that contains an API gateway)Of course, you have the last steps in a custom script, which means that you have to wrap your cdk deploy
. I suggest to do so with a nodejs script, so that you can leverage aws-sdk to upload your file to S3 easily.
Accepting that cdk doesn't support this, I split logic into two cdk scripts, accessed API gateway URL as cdk output via the cli, then wrapped everything in a bash script.
AWS CDK:
// API gateway
const api = new apigateway.RestApi(this, 'my-api', ..)
// output url
const myResourceURL = api.deploymentStage.urlForPath('/myResource');
new cdk.CfnOutput(this, 'MyRestURL', { value: myResourceURL });
Bash:
# deploy api gw
cdk deploy --app (..)
# read url via cli with --query
export rest_url=`aws cloudformation describe-stacks --stack-name (..) --query "Stacks[0].Outputs[?OutputKey=='MyRestURL'].OutputValue" --output text`
# configure React app
echo "{ \"api\" : { \"invokeUrl\" : \"$rest_url\" } }" > src/app-config.json
# build React app with url
npm run build
# run second cdk app to deploy React built output folder
cdk deploy --app (..)
Is there a better way?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With