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

feat: New opt-in property to update Lambda version whenever a property changes #2838

Merged
merged 23 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions integration/combination/test_function_with_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,42 @@ def test_updating_version_by_changing_property_value(self):
self.assertEqual(len(alias), 1)
hoffa marked this conversation as resolved.
Show resolved Hide resolved
self.assertEqual(len(versions), 1)

def test_updating_version_by_changing_property_value_additional_properties(self):
self.create_and_verify_stack("combination/function_with_alias_and_additional_properties_property")
alias_name = "Live"
function_name = self.get_physical_id_by_type("AWS::Lambda::Function")
version_ids = self.get_function_version_by_name(function_name)
self.assertEqual(["1"], version_ids)

alias = self.get_alias(function_name, alias_name)
self.assertEqual("1", alias["FunctionVersion"])

# Changing Handler should create a new version, and leave the existing version intact
self.set_template_resource_property("MyLambdaFunction", "Handler", "not_index.handler")
self.update_stack()

version_ids = self.get_function_version_by_name(function_name)
self.assertEqual(["1", "2"], version_ids)

alias = self.get_alias(function_name, alias_name)
self.assertEqual("2", alias["FunctionVersion"])

# Changing Description should create a new version, and leave the existing version intact
self.set_template_resource_property("MyLambdaFunction", "Description", "bar")
self.update_stack()

version_ids = self.get_function_version_by_name(function_name)
self.assertEqual(["1", "2", "3"], version_ids)

alias = self.get_alias(function_name, alias_name)
self.assertEqual("3", alias["FunctionVersion"])

# Make sure the stack has only One Version & One Alias resource
alias = self.get_stack_resources("AWS::Lambda::Alias")
versions = self.get_stack_resources("AWS::Lambda::Version")
self.assertEqual(len(alias), 1)
self.assertEqual(len(versions), 1)

def test_alias_deletion_must_retain_version(self):
self.create_and_verify_stack("combination/function_with_alias")
alias_name = "Live"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"LogicalResourceId": "MyLambdaFunction",
"ResourceType": "AWS::Lambda::Function"
},
{
"LogicalResourceId": "MyLambdaFunctionRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "MyLambdaFunctionAliasLive",
"ResourceType": "AWS::Lambda::Alias"
},
{
"LogicalResourceId": "MyLambdaFunctionVersion",
"ResourceType": "AWS::Lambda::Version"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Resources:
MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs14.x
CodeUri: ${codeuri}
AutoPublishAlias: Live
AutoPublishAliasAllProperties: true
Description: foo
Metadata:
SamTransformTest: true
8 changes: 8 additions & 0 deletions samtranslator/model/sam_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from samtranslator.intrinsics.resolver import IntrinsicsResolver
from samtranslator.metrics.method_decorator import cw_timer
from samtranslator.model import (
Property,
PassThroughProperty,
PropertyType,
Resource,
Expand Down Expand Up @@ -121,6 +122,7 @@ class SamFunction(SamResourceMacro):
# Intrinsic functions in value of Alias property are not supported, yet
"AutoPublishAlias": PropertyType(False, one_of(IS_STR)),
"AutoPublishCodeSha256": PropertyType(False, one_of(IS_STR)),
"AutoPublishAliasAllProperties": Property(False, is_type(bool)),
"VersionDescription": PropertyType(False, IS_STR),
"ProvisionedConcurrencyConfig": PropertyType(False, IS_DICT),
"FileSystemConfigs": PropertyType(False, list_of(IS_DICT)),
Expand Down Expand Up @@ -161,6 +163,7 @@ class SamFunction(SamResourceMacro):
EphemeralStorage: Optional[Dict[str, Any]]
AutoPublishAlias: Optional[Intrinsicable[str]]
AutoPublishCodeSha256: Optional[Intrinsicable[str]]
AutoPublishAliasAllProperties: Optional[bool]
VersionDescription: Optional[Intrinsicable[str]]
ProvisionedConcurrencyConfig: Optional[Dict[str, Any]]
FileSystemConfigs: Optional[Dict[str, Any]]
Expand Down Expand Up @@ -886,6 +889,11 @@ def _construct_version(
# If SnapStart is enabled we want to publish a new version, to have the corresponding snapshot
if function.SnapStart and function.SnapStart.get("ApplyOn", "None") != "None":
logical_dict.update({"SnapStart": function.SnapStart})
# We can't directly change AutoPublishAlias as that would be a breaking change, so we have to add this opt-in
# property that when set to true would change the lambda version whenever a property in the lambda function changes
if self.AutoPublishAliasAllProperties:
aaythapa marked this conversation as resolved.
Show resolved Hide resolved
aaythapa marked this conversation as resolved.
Show resolved Hide resolved
properties = function._generate_resource_dict().get("Properties", {})
logical_dict.update(properties)
aaythapa marked this conversation as resolved.
Show resolved Hide resolved
logical_id = logical_id_generator.LogicalIdGenerator(prefix, logical_dict, code_sha256).gen()

attributes = self.get_passthrough_resource_attributes()
Expand Down
4 changes: 4 additions & 0 deletions samtranslator/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -189313,6 +189313,10 @@
"markdownDescription": "The name of the Lambda alias\\. For more information about Lambda aliases, see [Lambda function aliases](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) in the *AWS Lambda Developer Guide*\\. For examples that use this property, see [Deploying serverless applications gradually](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/automating-updates-to-serverless-apps.html)\\. \nAWS SAM generates [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-version.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-version.html) and [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html) resources when this property is set\\. For information about this scenario, see [AutoPublishAlias property is specified](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources-function.html#sam-specification-generated-resources-function-autopublishalias)\\. For general information about generated AWS CloudFormation resources, see [Generated AWS CloudFormation resources](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources.html)\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
"title": "AutoPublishAlias"
},
"AutoPublishAliasAllProperties": {
"title": "Autopublishaliasallproperties",
"type": "boolean"
},
"AutoPublishCodeSha256": {
"anyOf": [
{
Expand Down
2 changes: 2 additions & 0 deletions schema_source/aws_serverless_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ class ScheduleV2Event(BaseModel):
KmsKeyArn = Optional[PassThroughProp]
Layers = Optional[PassThroughProp]
AutoPublishAlias = Optional[SamIntrinsicable[str]]
AutoPublishAliasAllProperties = Optional[bool]
RolePath = Optional[PassThroughProp]
PermissionsBoundary = Optional[PassThroughProp]
ReservedConcurrentExecutions = Optional[PassThroughProp]
Expand All @@ -463,6 +464,7 @@ class Properties(BaseModel):
Architectures: Optional[Architectures] = prop("Architectures")
AssumeRolePolicyDocument: Optional[AssumeRolePolicyDocument] = prop("AssumeRolePolicyDocument")
AutoPublishAlias: Optional[AutoPublishAlias] = prop("AutoPublishAlias")
AutoPublishAliasAllProperties: Optional[AutoPublishAliasAllProperties] # TODO: add docs
AutoPublishCodeSha256: Optional[SamIntrinsicable[str]] = prop("AutoPublishCodeSha256")
CodeSigningConfigArn: Optional[SamIntrinsicable[str]] = prop("CodeSigningConfigArn")
CodeUri: Optional[CodeUriType] = prop("CodeUri")
Expand Down
4 changes: 4 additions & 0 deletions schema_source/sam.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4692,6 +4692,10 @@
"markdownDescription": "The name of the Lambda alias\\. For more information about Lambda aliases, see [Lambda function aliases](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) in the *AWS Lambda Developer Guide*\\. For examples that use this property, see [Deploying serverless applications gradually](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/automating-updates-to-serverless-apps.html)\\. \nAWS SAM generates [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-version.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-version.html) and [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-alias.html) resources when this property is set\\. For information about this scenario, see [AutoPublishAlias property is specified](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources-function.html#sam-specification-generated-resources-function-autopublishalias)\\. For general information about generated AWS CloudFormation resources, see [Generated AWS CloudFormation resources](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources.html)\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is unique to AWS SAM and doesn't have an AWS CloudFormation equivalent\\.",
"title": "AutoPublishAlias"
},
"AutoPublishAliasAllProperties": {
"title": "Autopublishaliasallproperties",
"type": "boolean"
},
"AutoPublishCodeSha256": {
"anyOf": [
{
Expand Down