Aws-cdk: [assets] cdk synth should package assets in s3 bucket and synthesized template references those assets

Created on 9 Jul 2020  路  20Comments  路  Source: aws/aws-cdk

CFN & SAM as set a precedence in how people deploy their infrastructure in the cloud. We package the artifacts, a template is returned that references the packaged artifacts and it ready for deploy.

The CDK can follow a similar approach. This makes it easier and less complex in working with serverless applications that have many lambda functions.

Use Case

Many applications take a serverless microservice approach. Where you will have a service with many lambda functions. Currently, the way that it is handled in the cdk is complicated and brittle at the moment.

eg.

export class SomeMicroserviceStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props: SomeMicroserviceStackProps) {

    public readonly lambdaCode1: CfnParametersCode; 
    public readonly lambdaCode2: CfnParametersCode; 
    // n number of readonly properties with reference to lambda functions in microservice

    super(scope, id, props);
          // multi lambda functions
    }
}

Then we have the pipeline

export class PipelineStack extends Stack {
    constructor(scope: cdk.App, id: string, props: PipelineStackProps) {
        super(scope, id, props);

        const paymentServiceDevDeployAction = new CloudFormationCreateUpdateStackAction({

            actionName: "PaymentServiceStack_DEV_Deploy",
            templatePath: servicesBuildOutput.atPath(
            "SomeMicroserviceStack.template.json"),
            stackName: "SomeMicroserviceStack",
            adminPermissions: true,
            account,
            region,
            parameterOverrides: {
            ...props.lambdaCode1.assign(lambda1Output.s3Location),
            ...props.lambdaCode2.assign(lambda2.s3Location),
            // n number of lambdas
            // limit of 1KB
            // For every new lambda function it gets added which becomes a pain
            },
            extraInputs: [lambda1Output, lambda2, .....],
        });
    }
}

Proposed Solution


I believe its more straight forward to have the cdk package the artifact in a user defined bucket and out put to us a parsed template where the artifacts are referenced.

I am taking the concept from SAM. Where we have the command:
sam package --template-file PATH --s3-bucket TEXT

so for cdk we would have
cdk synth/package [Stack] --s3-bucket TEXT

The output from that command can be used to do a deploy directly or be used in a ci/cd workflow.

Other

  • [ ] :wave: I may be able to implement this feature request
  • [ ] :warning: This feature might incur a breaking change

This is a :rocket: Feature Request

@aws-cdassets feature-request packagtools

Most helpful comment

@eladb I like the idea of adding cdk package as well outside of synth. I'm not sure if @rix0rrr had any other ideas / thoughts

All 20 comments

We should be able to provide a way to package assets and upload them now that we鈥檝e decoupled assets from deployment into a new tool called cdk-assets.

I am not opposed to adding cdk package which will synthesize the template and run cdk-assets to bundle and publish assets to their needed location.

At any rate, this is a separate step from synth.

Copy @rix0rrr

Reassigning to @shivlaks

@eladb I like the idea of adding cdk package as well outside of synth. I'm not sure if @rix0rrr had any other ideas / thoughts

I think this is a _great_ idea.

One of the big downsides of moving away from SAM is that we've sort-of lost the ability to _easily_ use See sam local start-api, along with things like sam local invoke, which were an excellent developer experience for local API Gateway / Lambda Fn testing.

Currently it's pretty frustrating to do this same thing with the CDK, as it involves multiple, manual steps.

marking this feature as a p1 to help prioritize implementation

+1

We are building a product using CDK but we want to offer customers a 1-click deploy with CloudFormation so that they don't have to install CDK and download the cloud assembly. Currently, cdk synth generates the templates and the assets, which is 90% of the work, but we are missing that last step of uploading the assets to an S3 bucket and referencing them in the generated templates.

I tried using cdk-assets but it asks for an assets.json file which is not included in my cdk.out directory. I have tried a few feature flags to try to generate the assets.json but I've had no success.

You could try using the new style synthesizer. This should do what you want. There is a feature flag for this

You could try using the new style synthesizer. This should do what you want. There is a feature flag for this

I tried that but I get this error on cdk synth:

Cannot add assets to a Stack that uses the BootstraplessSynthesizer

I'm not using the BootstraplessSynthesizer but perhaps one of the constructs we depend on is using it.

@rix0rrr can you take a look?

@ferdingler can you make sure you have "@aws-cdk/core:newStyleStackSynthesis": true, in your cdk.json?

Your account needs to be bootstrapped again while being inside of this folder with the CDK CLI.

@hoegertn Confirmed that I have the "@aws-cdk/core:newStyleStackSynthesis": "true" flag in my cdk.json. I also just upgraded to latest CDK CLI 1.76.0 (build c207717) and upgraded all my cdk packages to 1.76.0 as well.

if I run cdk bootstrap I get this output:

'@aws-cdk/core:newStyleStackSynthesis' context set, using new-style bootstrapping
Cannot add assets to a Stack that uses the BootstraplessSynthesizer
Subprocess exited with error 1

if I run cdk synth "*" I also get this output:

Cannot add assets to a Stack that uses the BootstraplessSynthesizer
Subprocess exited with error 1

However, I just realized the cdk synth is now generating new JSON files for each stack Backend.assets.json, Frontend.assets.json, etc. I missed these JSONs before because I was so focused on looking for a file named assets.json.

The bootstrapless synthesizer is used for support stacks (stacks that try and deploy things like buckets and roles that need to be deployed in a different region than the one your application is being deployed in). CloudFront's EdgeFunction uses one, and so does the CodePipeline library.

I would expect you to get a stack trace with your error: Cannot add assets to a Stack that uses the BootstraplessSynthesizer.

Check the scopes of the objects involved in that stack trace.

@rix0rrr Running cdk synth "*" --debug doesn't give me any stack trace. However, cdk synth "*" --verbose does show the following stack trace:

Cannot add assets to a Stack that uses the BootstraplessSynthesizer
Subprocess exited with error 1
Error: Subprocess exited with error 1
    at ChildProcess.<anonymous> (/usr/local/lib/node_modules/aws-cdk/lib/api/cxapp/exec.ts:122:23)
    at ChildProcess.emit (events.js:315:20)
    at ChildProcess.EventEmitter.emit (domain.js:486:12)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)

We are indeed using Lambda@Edge in a CloudFront distribution which is deployed in a different region (us-east-1) than the rest of the stacks. Unless, of course, you deploy all the stacks in us-east-1.

@ferdingler do you perchance have some example code I could give whirl?

@rix0rrr thanks for the follow up. This is our codebase: https://github.com/awslabs/performance-dashboard-on-aws/tree/mainline/cdk . Feel free to browse it or clone it.

In the meantime, I am thinking I will remove the use of the Lambda@Edge construct to see if the BootstraplessSynthesizer error goes away.

@hoegertn @eladb After I dig into "@aws-cdk/core:newStyleStackSynthesis": true, from cdk source code, I found a new DefaultStackSynthesizer that is not enabled yet. What is your plan of fully enabling the new DefaultStackSynthesizer?
https://github.com/aws/aws-cdk/blob/e325b569bcca1f87db72f4c754d095c891dd92c3/packages/%40aws-cdk/core/lib/stack.ts#L398-L401

We should be able to provide a way to package assets and upload them now that we鈥檝e decoupled assets from deployment into a new tool called cdk-assets.

I am not opposed to adding cdk package which will synthesize the template and run cdk-assets to bundle and publish assets to their needed location.

At any rate, this is a separate step from synth.

Copy @rix0rrr

Reassigning to @shivlaks

Besides that, based on the reply above, does it mean I can contribute a new cmd cdk package with the DefaultStackSynthesizer to synthesize the template and then run cdk-assets to bundle and publish assets?

You don't need to create a cdk package command. You can just run cdk synth && cdk-assets cdk.out

@ferdingler can't reproduce?

huijbers ~/T/p/cdk(mainline)> env CDK_ENV_NAME=henk npx cdk synth
Successfully synthesized to /Users/huijbers/Temp/performance-dashboard-on-aws/cdk/cdk.out
Supply a stack id (Auth, lambda-at-edge-support-stack, Backend, Frontend, Ops) to display its template.

EDIT:

I did have to change this otherwise it wouldn't compile at all:

-    "@cloudcomponents/cdk-lambda-at-edge-pattern": "^1.2.2",
+    "@cloudcomponents/cdk-lambda-at-edge-pattern": "1.2.2",

@rix0rrr

You don't need to create a cdk package command. You can just run cdk synth && cdk-assets cdk.out

But I want to pass some parameters into DefaultStackSynthesizer. Does cdk synth already support that?

@rix0rrr haven't had a chance to test this again. I'll get to it as soon as I can and update this ticket with more info.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mirazmamun picture mirazmamun  路  3Comments

kawamoto picture kawamoto  路  3Comments

slipdexic picture slipdexic  路  3Comments

eladb picture eladb  路  3Comments

artyom-melnikov picture artyom-melnikov  路  3Comments