Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS CDK: run external build command in CDK sequence?

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
  }) 
}
like image 350
Brad Wehrwein Avatar asked May 10 '20 16:05

Brad Wehrwein


People also ask

How do I create an AWS CDK project?

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:

Why is it important to keep all the AWS-CDK packages the same version?

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.

How does the AWS CDK explorer find apps?

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.

What is Cdk bundling in AWS Lambda?

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.


Video Answer


2 Answers

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:

  • deploy with the output file options, for example: cdk deploy -O ./cdk.out/deploy-output.json
  • In ./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)
  • manually parse that JSON to get your apigateway url
  • create your configuration file and upload it to S3 (you can do it via aws-sdk)

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.

like image 105
Luca T Avatar answered Oct 22 '22 01:10

Luca T


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?

like image 24
Brad Wehrwein Avatar answered Oct 22 '22 02:10

Brad Wehrwein