5

Running cdk deploy after updating my Stack:

export function createTaskXXXX (stackScope: Construct, workflowContext: WorkflowContext) {
  const lambdaXXXX = new lambda.Function(stackScope, 'XXXXFunction', {
    runtime: Globals.LAMBDA_RUNTIME,
    memorySize: Globals.LAMBDA_MEMORY_MAX,
    code: lambda.Code.fromAsset(CDK_MODULE_ASSETS_PATH),
    handler: 'xxxx-handler.handler',
    timeout: Duration.minutes(Globals.LAMBDA_DURATION_2MIN),
    environment: {
      YYYY_ENV: (workflowContext.production) ? 'prod' : 'test',
      YYYY_A_LOCATION: `s3://${workflowContext.S3ImportDataBucket}/adata-workflow/split-input/`,
      YYYY_B_LOCATION: `s3://${workflowContext.S3ImportDataBucket}/bdata-workflow/split-input/`  <--- added
    }
  })
  lambdaXXXX.addToRolePolicy(new iam.PolicyStatement({
    effect: Effect.ALLOW,
    actions: ['s3:PutObject'],
    resources: [
        `arn:aws:s3:::${workflowContext.S3ImportDataBucket}/adata-workflow/split-input/*`,
        `arn:aws:s3:::${workflowContext.S3ImportDataBucket}/bdata-workflow/split-input/*` <---- added
    ]
  }))

I realize that those changes are not updated at stack.template.json:

...
        "Runtime": "nodejs12.x",
        "Environment": {
          "Variables": {
            "YYYY_ENV": "test",
            "YYYY_A_LOCATION": "s3://.../adata-workflow/split-input/"
          }
        },
        "MemorySize": 3008,
        "Timeout": 120
      }
...

I have cleaned cdk.out and tried the deploy --force, but never see any updates.

Is it deleting the stack and redeploying the only final alternative, or am I missing something? I think at least at synth should generate different results.

(I also changed to cdk 1.65.0 in my local system to match the package.json) Thanks.

EDITED: I git clone the project, and did npm install and cdk synth again and finally saw the changes, I would like not to do this every time, any light of what could be blocking the correct synth generation?

EDITED 2: After a diff between the bad old project and the new from git where synth worked, i realized that some of my project files that had .ts (for example cdk.ts my App definition) also had replicas with .js and .d.ts., such as cdk.js and cdk.d.ts. Could i have runned some command by mistake that compiled Typescript, i will continue to investigate, thanks to all answers.

5
  • 1
    Are you sure you've saved the .ts file before running cdk command? Commented Oct 14, 2021 at 20:46
  • 1
    Hi yes made sure to save it (although Intellij saves automatically), i will do a diff between both folders, the old project folder where its failing and new which i got from git, see if i can find more details, but it works on the newly git cloned. Commented Oct 14, 2021 at 21:15
  • I found out some extra files with .d.ts and .js, this could be the reason, thanks. Commented Oct 14, 2021 at 21:31
  • I can't remember if it was inline policies only or if this applies to a Function's auto-generated role too but in either case and because of the things @lynkfox said, I usually have luck resolving these kinds of errors by creating a Role, put those policies in it and give that role to the Function as the executionRole. Then, whenever you change the policies in the role, it will for sure get the updates and your lambda always uses that role with its policies. Commented Jun 23, 2022 at 18:19
  • Not directly applicable to the OP, but, if you work with both "normal" CDK projects and CDK pipelines (and here), side by side, it's easy to forget that the latter requires a git push to update, instead of a cdk deploy. Commented Jul 25, 2024 at 11:07

3 Answers 3

5

because CDK uses Cloudformation, it performs an action to determine a ChangeSet. This is to say, if it doesn't think anything has changed, it wont change that resource.

This can, of course, be very annoying as sometimes it thinks it is the same and doesn't update when there is actually a change - I find this most often with Layers and using some form of make file to generate the zips for the layers. Even tho it makes a 'new' zip whatever it uses to determine that the zip is updated recalls it as the same because of ... whatever compression/hash/ect changes are used.

You can get around this by updating the description with a datetime. Its assigned at synth (which is part of the cdk deploy) and so if you do a current now() of datetime

You can also use cdk diff to see what it thinks the changes are.

And finally... always remember to save your file before deployments as, depending on your IDE, it may not be available to the command line ;)

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, neither diff could trigger the changes, i use Intellij, but made sure to save all, and executed the command from prompt. I will try to diff between both folders. thanks.
I found out some extra files with .d.ts and .js, this could be the reason, thanks.
0

This is how I do it. Works nicely so far. Basically you can do the following:

  1. Push your lambda code as a zip file to an s3 bucket. The bucket must have versioning enabled. .

  2. The CDK code below will do the following:

    1. Create a custom resource. It basically calls s3.listObjectVersions for my lambda zip file in S3. I grab the first returned value, which seems to be the most recent object version all the time (I cannot confirm this with the documentation though). I also create a role for the custom resource.
    2. Create the lambda and specify the code as the zip file in s3 AND THE OBJECT VERSION RETURNED BY THE CUSTOM RESOURCE! That is the most important part.
    3. Create a new lambda version.

Then the lambda's code updates when you deploy the CDK stack!

const versionIdKey = 'Versions.0.VersionId';
const isLatestKey = 'Versions.0.IsLatest'
const now = new Date().toISOString();

const role = new Role(this, 'custom-resource-role', {
    assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
});
role.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess')); // you can make this more specific


// I'm not 100% sure this gives you the most recent first, but it seems to be doing that every time for me.  I can't find anything in the docs about it...
const awsSdkCall: AwsSdkCall = {
    action: "listObjectVersions",
    parameters: {
        Bucket: buildOutputBucket.bucketName, // s3 bucket with zip file containing lambda code.
        MaxKeys: 1,
        Prefix: LAMBDA_S3_KEY, // S3 key of zip file containing lambda code
    },
    physicalResourceId: PhysicalResourceId.of(buildOutputBucket.bucketName),
    region: 'us-east-1', // or whatever region
    service: "S3",
    outputPaths: [versionIdKey, isLatestKey]
};

const customResourceName = 'get-object-version'
const customResourceId = `${customResourceName}-${now}` // not sure if `now` is neccessary...

const response = new AwsCustomResource(this, customResourceId, {
    functionName: customResourceName,
    installLatestAwsSdk: true,
    onCreate: awsSdkCall,
    onUpdate: awsSdkCall,
    policy: AwsCustomResourcePolicy.fromSdkCalls({resources: AwsCustomResourcePolicy.ANY_RESOURCE}), // you can make this more specific
    resourceType: "Custom::ListObjectVersions",
    role: role 
})

const fn = new Function(this, 'my-lambda', {
    functionName: 'my-lambda',
    description: `${response.getResponseField(versionIdKey)}-${now}`,
    runtime: Runtime.NODEJS_14_X,
    memorySize: 1024,
    timeout: Duration.seconds(5),
    handler: 'index.handler',
    code: Code.fromBucket(buildOutputBucket, LAMBDA_S3_KEY, response.getResponseField(versionIdKey)),  // This is where the magic happens. You tell CDK to use a specific S3 object version when updating the lambda.
    currentVersionOptions: {
        removalPolicy: RemovalPolicy.DESTROY,
    },
});

new Version(this, `version-${now}`, { // not sure if `now` is neccessary...
    lambda: fn,
    removalPolicy: RemovalPolicy.DESTROY
})

Do note: For this to work, you have to upload your lambda zip code to S3 before each cdk deploy. This can be the same code as before, but the s3 bucket versioning will create a new version. I use code pipeline to do this as part of additional automation.

Comments

0

I have the latest cdk 2.95.1. But I still seem to be running into the problem. I cleared out my cdk.out, did a synth and then deployed, but in vain. What worked for me was to deploy the cloudformation template that I got after synthesizing. Here is the command

 cdk deploy MyStack  --template .\cdk.out\MyStack.template.json

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.