Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(cli): Hotswapping support for Lambda function's description and or environment variable #20787

Closed
1 of 2 tasks
huyphan opened this issue Jun 19, 2022 · 3 comments · Fixed by #21305 or #21532
Closed
1 of 2 tasks
Assignees
Labels
effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2

Comments

@huyphan
Copy link
Contributor

huyphan commented Jun 19, 2022

Describe the feature

Lambda users are hitting a situation with hotswap deployment where either (1) hotswap deployment is always skipped or (2) it is not compatible with subsequent full deployments.

Use Case

The issue happens with a setup where:

  • A Lambda function is using S3 code provider (such as lambda.Code.fromBucket)
  • The Lambda function deployment is managed with Versions and Aliases.
  • Users need to be able to deploy their stack properly, either with or without --hotswap directive.

For that setup, we suggest in our doc that users should define a lambda.Version directly:

NOTE: The currentVersion property is only supported when your AWS Lambda function uses either lambda.Code.fromAsset or lambda.Code.fromInline. Other types of code providers (such as lambda.Code.fromBucket) require that you define a lambda.Version resource directly since the CDK is unable to determine if their contents had changed.

We also say that we should apply some trick to the Function resource's properties so the Version can be updated properly

One way to ensure that the lambda.Version always points to the latest version of your lambda.Function is to set an environment variable which changes at least as often as your code does. This makes sure the function always has the latest code.

There are at least three ways of doing it with CDK, but every of them gives users error at some point in their development cycle.

Option 1: Adding a dynamic environment variable

This option is suggested in the official doc. An example code looks like this:

    const lambdaFunction = new Function(this, "TestFunction", {
      code: Code.fromBucket(
        Bucket.fromBucketName(
          this,
          "LambdaCodeBucket",
          "teststack-testbucket560b80bc-1vg8000mxtcs0"
        ),
        "lambda.zip"
      ),
      runtime: Runtime.PYTHON_3_9,
      handler: "index.handler",
      environment: {
        CodeVersionString: new Date().toISOString(),
      },
    });

Since Function's environment update is not considered hotswappable, user can never perform a hotswap deployment with this code. In my local setup where the hotswap deployment was skipped, this was the diff for this case:

Stack LambdaStack
Resources
[~] AWS::Lambda::Function TestFunction TestFunction22AD90FC
 └─ [~] Environment
     └─ [~] .Variables:
         └─ [~] .CodeVersionString:
             ├─ [-] 2022-06-18T11:14:03.458Z
             └─ [+] 2022-06-18T11:46:41.225Z

Option 2: Adding a dynamic value to the function description

If I recall correctly, one example in AWS CDK docs was using this approach, but that snippet is now deleted. But this is a commonly known trick to mutate the Lambda function's properties:

    const lambdaFunction = new Function(this, "TestFunction", {
      code: Code.fromBucket(
        Bucket.fromBucketName(
          this,
          "LambdaCodeBucket",
          "teststack-testbucket560b80bc-1vg8000mxtcs0"
        ),
        "lambda.zip"
      ),
      runtime: Runtime.PYTHON_3_9,
      handler: "index.handler",
      description: "generated at " + new Date().toISOString(),  
    });

This option has the same problem as option #1 -- hotswap deployment is always skipped because an update of a Lambda function's description is not a hotswappable change.

Option 3: Making the Version resource dynamic instead

This option was used as an example by the CDK folks in a comment on a similar topic in the past:

    const lambdaFunction = new Function(this, "TestFunction", {
      code: Code.fromBucket(
        Bucket.fromBucketName(this, "LambdaCodeBucket", "teststack-testbucket560b80bc-1vg8000mxtcs0"),
        "lambda.zip"
      ),
      runtime: Runtime.PYTHON_3_9,
      handler: "index.handler",
    });

    const version = new Version(this, `TestFunctionVersion-${new Date().toISOString()}`, {
      lambda: lambdaFunction
    });

This trick does allow hotswap deployment to work, but will cause every subsequent full deployment to fail because of conflicting function version. Example error message:

7:46:27 PM | CREATE_FAILED        | AWS::Lambda::Version  | TestFunctionVersio...094605709ZC17DD4A4
A version for this Lambda function exists ( 1 ). Modify the function to create a new version.

Proposed Solution

If we could make option 3 works, that would be ideal. However, it require users to have access to a value that changes consistently with the Lambda code (such as the hash of the Lambda code or the local build version). And that value has to be available at synthesis time. This is not feasible for many users.

So we are left with the options of making Lambda function's descriptions and/or environment variables hotswappable. That said, there may be better options that I haven't thought of yet.

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

2.28.1 (build d035432)

Environment details (OS name and version, etc.)

Darwin Kernel Version 21.5.0 . root:xnu-8020.121.3~4/RELEASE_X86_64 x86_64

@huyphan huyphan added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jun 19, 2022
@github-actions github-actions bot added the @aws-cdk/aws-lambda Related to AWS Lambda label Jun 19, 2022
@kaizencc kaizencc removed the @aws-cdk/aws-lambda Related to AWS Lambda label Jun 20, 2022
@kaizencc kaizencc assigned comcalvi and unassigned kaizencc Jun 20, 2022
@comcalvi comcalvi added effort/medium Medium work item – several days of effort p2 and removed needs-triage This issue or PR still needs to be triaged. labels Jun 20, 2022
@mergify mergify bot closed this as completed in #21305 Aug 8, 2022
mergify bot pushed a commit that referenced this issue Aug 8, 2022
…ronment variables (#21305)

This change allows Lambda function to be hotswap'ed when there's change in the function's description and/or environment variables. These changes are categorized as configuration changes and are updated by calling `updateFunctionConfiguration`. Since the existing waiter "UpdateFunctionCodeToFinish" is now used to wait for both code update and configuration update, I renamed it to "UpdateFunctionPropertiesToFinish".

resolves #20787

----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

github-actions bot commented Aug 8, 2022

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

jmortlock pushed a commit to jmortlock/aws-cdk that referenced this issue Aug 8, 2022
…ronment variables (aws#21305)

This change allows Lambda function to be hotswap'ed when there's change in the function's description and/or environment variables. These changes are categorized as configuration changes and are updated by calling `updateFunctionConfiguration`. Since the existing waiter "UpdateFunctionCodeToFinish" is now used to wait for both code update and configuration update, I renamed it to "UpdateFunctionPropertiesToFinish".

resolves aws#20787

----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@mrgrain mrgrain reopened this Aug 9, 2022
@mrgrain
Copy link
Contributor

mrgrain commented Aug 9, 2022

PR needed to be reverted due to a failure with integration tests
#21509

@mergify mergify bot closed this as completed in #21532 Aug 10, 2022
mergify bot pushed a commit that referenced this issue Aug 10, 2022
…ronment variables (#21532)

CDK users who deploy their Lambda function with S3 code provider cannot use hotswap deployment today. It's because -- in order for the function version and alias to work -- they need to use a dynamic value in either function's description or environment variable. Since neither of them is supported by hotswap, CDK always performs a full deployment. 

This change allows Lambda function to be hotswappable when there's change in the function's description and/or environment variables. These changes are categorized as configuration changes and are updated by calling `updateFunctionConfiguration`. Since the existing waiter `UpdateFunctionCodeToFinish` is now used to wait for both code update and configuration update, I renamed it to `UpdateFunctionPropertiesToFinish`.

Functional wise, this PR is identical to the now-reverted changes in #21305. The only difference is the fix for integration test (commit [#82dbd4)](82dbd41)

resolves #20787

----


#21305


### All Submissions:

* [ X ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ X ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [  ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

josephedward pushed a commit to josephedward/aws-cdk that referenced this issue Aug 30, 2022
…ronment variables (aws#21305)

This change allows Lambda function to be hotswap'ed when there's change in the function's description and/or environment variables. These changes are categorized as configuration changes and are updated by calling `updateFunctionConfiguration`. Since the existing waiter "UpdateFunctionCodeToFinish" is now used to wait for both code update and configuration update, I renamed it to "UpdateFunctionPropertiesToFinish".

resolves aws#20787

----

### All Submissions:

* [X] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
josephedward pushed a commit to josephedward/aws-cdk that referenced this issue Aug 30, 2022
…ronment variables (aws#21532)

CDK users who deploy their Lambda function with S3 code provider cannot use hotswap deployment today. It's because -- in order for the function version and alias to work -- they need to use a dynamic value in either function's description or environment variable. Since neither of them is supported by hotswap, CDK always performs a full deployment. 

This change allows Lambda function to be hotswappable when there's change in the function's description and/or environment variables. These changes are categorized as configuration changes and are updated by calling `updateFunctionConfiguration`. Since the existing waiter `UpdateFunctionCodeToFinish` is now used to wait for both code update and configuration update, I renamed it to `UpdateFunctionPropertiesToFinish`.

Functional wise, this PR is identical to the now-reverted changes in aws#21305. The only difference is the fix for integration test (commit [#82dbd4)](aws@82dbd41)

resolves aws#20787

----


aws#21305


### All Submissions:

* [ X ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ X ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [  ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2
Projects
None yet
4 participants