From 030f794b8b69c6fea13f0456c1166797b757da0f Mon Sep 17 00:00:00 2001 From: Renato Valenzuela Date: Tue, 2 Dec 2025 17:01:12 +0000 Subject: [PATCH 1/2] feat: add support for Durable Functions --- .cfnlintrc.yaml | 1 + .../schema_source/aws_serverless_function.py | 2 + samtranslator/model/lambda_.py | 2 + samtranslator/model/sam_resources.py | 3 + samtranslator/plugins/globals/globals.py | 2 + samtranslator/schema/schema.json | 27 +++ schema_source/cloudformation.schema.json | 21 +++ schema_source/sam.schema.json | 6 + .../input/function_with_durable_config.yaml | 10 + .../function_with_durable_config_globals.yaml | 27 +++ .../input/globals_for_function.yaml | 6 + .../aws-cn/function_with_durable_config.json | 61 ++++++ .../function_with_durable_config_globals.json | 175 ++++++++++++++++++ .../output/aws-cn/globals_for_function.json | 8 + .../function_with_durable_config.json | 61 ++++++ .../function_with_durable_config_globals.json | 175 ++++++++++++++++++ .../aws-us-gov/globals_for_function.json | 8 + .../output/function_with_durable_config.json | 61 ++++++ .../function_with_durable_config_globals.json | 175 ++++++++++++++++++ .../output/globals_for_function.json | 8 + 20 files changed, 839 insertions(+) create mode 100644 tests/translator/input/function_with_durable_config.yaml create mode 100644 tests/translator/input/function_with_durable_config_globals.yaml create mode 100644 tests/translator/output/aws-cn/function_with_durable_config.json create mode 100644 tests/translator/output/aws-cn/function_with_durable_config_globals.json create mode 100644 tests/translator/output/aws-us-gov/function_with_durable_config.json create mode 100644 tests/translator/output/aws-us-gov/function_with_durable_config_globals.json create mode 100644 tests/translator/output/function_with_durable_config.json create mode 100644 tests/translator/output/function_with_durable_config_globals.json diff --git a/.cfnlintrc.yaml b/.cfnlintrc.yaml index fee4c28be..9fd28f0cb 100644 --- a/.cfnlintrc.yaml +++ b/.cfnlintrc.yaml @@ -148,6 +148,7 @@ ignore_templates: - tests/translator/output/**/function_with_tenancy_and_api_event.json # cfnlint is not updated to recognize the TenancyConfig property - tests/translator/output/**/function_with_tenancy_and_httpapi_event.json # cfnlint is not updated to recognize the TenancyConfig property - tests/translator/output/**/function_with_tenancy_config_global.json # cfnlint is not updated to recognize the TenancyConfig property + - tests/translator/output/**/*durable_config*.json # TODO: Remove this once Durable Function is launched in CFN ignore_checks: - E2531 # Deprecated runtime; not relevant for transform tests diff --git a/samtranslator/internal/schema_source/aws_serverless_function.py b/samtranslator/internal/schema_source/aws_serverless_function.py index e40d193b4..effd7802e 100644 --- a/samtranslator/internal/schema_source/aws_serverless_function.py +++ b/samtranslator/internal/schema_source/aws_serverless_function.py @@ -662,6 +662,7 @@ class Properties(BaseModel): RecursiveLoop: Optional[PassThroughProp] # TODO: add documentation SourceKMSKeyArn: Optional[PassThroughProp] # TODO: add documentation TenancyConfig: Optional[PassThroughProp] # TODO: add documentation + DurableConfig: Optional[PassThroughProp] # TODO: add documentation class Globals(BaseModel): @@ -723,6 +724,7 @@ class Globals(BaseModel): RecursiveLoop: Optional[PassThroughProp] # TODO: add documentation SourceKMSKeyArn: Optional[PassThroughProp] # TODO: add documentation TenancyConfig: Optional[PassThroughProp] # TODO: add documentation + DurableConfig: Optional[PassThroughProp] # TODO: add documentation class Resource(ResourceAttributes): diff --git a/samtranslator/model/lambda_.py b/samtranslator/model/lambda_.py index e59127723..909eb453d 100644 --- a/samtranslator/model/lambda_.py +++ b/samtranslator/model/lambda_.py @@ -37,6 +37,7 @@ class LambdaFunction(Resource): "LoggingConfig": GeneratedProperty(), "RecursiveLoop": GeneratedProperty(), "TenancyConfig": GeneratedProperty(), + "DurableConfig": GeneratedProperty(), } Code: Dict[str, Any] @@ -66,6 +67,7 @@ class LambdaFunction(Resource): LoggingConfig: Optional[Dict[str, Any]] RecursiveLoop: Optional[str] TenancyConfig: Optional[Dict[str, Any]] + DurableConfig: Optional[Dict[str, Any]] runtime_attrs = {"name": lambda self: ref(self.logical_id), "arn": lambda self: fnGetAtt(self.logical_id, "Arn")} diff --git a/samtranslator/model/sam_resources.py b/samtranslator/model/sam_resources.py index 3cafe9634..8dd58398e 100644 --- a/samtranslator/model/sam_resources.py +++ b/samtranslator/model/sam_resources.py @@ -185,6 +185,7 @@ class SamFunction(SamResourceMacro): "RecursiveLoop": PassThroughProperty(False), "SourceKMSKeyArn": PassThroughProperty(False), "TenancyConfig": PassThroughProperty(False), + "DurableConfig": PropertyType(False, IS_DICT), } FunctionName: Optional[Intrinsicable[str]] @@ -230,6 +231,7 @@ class SamFunction(SamResourceMacro): RecursiveLoop: Optional[str] SourceKMSKeyArn: Optional[str] TenancyConfig: Optional[Dict[str, Any]] + DurableConfig: Optional[Dict[str, Any]] event_resolver = ResourceTypeResolver( samtranslator.model.eventsources, @@ -655,6 +657,7 @@ def _construct_lambda_function(self, intrinsics_resolver: IntrinsicsResolver) -> lambda_function.LoggingConfig = self.LoggingConfig lambda_function.TenancyConfig = self.TenancyConfig lambda_function.RecursiveLoop = self.RecursiveLoop + lambda_function.DurableConfig = self.DurableConfig self._validate_package_type(lambda_function) return lambda_function diff --git a/samtranslator/plugins/globals/globals.py b/samtranslator/plugins/globals/globals.py index 341c67fc5..251518eca 100644 --- a/samtranslator/plugins/globals/globals.py +++ b/samtranslator/plugins/globals/globals.py @@ -57,6 +57,7 @@ class Globals: "RecursiveLoop", "SourceKMSKeyArn", "TenancyConfig", + "DurableConfig", ], # Everything except # DefinitionBody: because its hard to reason about merge of Swagger dictionaries @@ -107,6 +108,7 @@ class Globals: "RecursiveLoop", "SourceKMSKeyArn", "TenancyConfig", + "DurableConfig", ], } diff --git a/samtranslator/schema/schema.json b/samtranslator/schema/schema.json index 3df8ee7b6..021507745 100644 --- a/samtranslator/schema/schema.json +++ b/samtranslator/schema/schema.json @@ -142798,6 +142798,11 @@ "title": "Description", "type": "string" }, + "DurableConfig": { + "$ref": "#/definitions/AWS::Lambda::Function.DurableConfig", + "markdownDescription": "Configuration for durable function execution.", + "title": "DurableConfig" + }, "Environment": { "$ref": "#/definitions/AWS::Lambda::Function.Environment", "markdownDescription": "Environment variables that are accessible from function code during execution.", @@ -142977,6 +142982,22 @@ }, "type": "object" }, + "AWS::Lambda::Function.DurableConfig": { + "additionalProperties": false, + "properties": { + "ExecutionTimeout": { + "markdownDescription": "The maximum execution timeout in seconds for durable function executions.", + "title": "ExecutionTimeout", + "type": "number" + }, + "RetentionPeriodInDays": { + "markdownDescription": "The retention period in days for durable function execution history.", + "title": "RetentionPeriodInDays", + "type": "number" + } + }, + "type": "object" + }, "AWS::Lambda::Function.Environment": { "additionalProperties": false, "properties": { @@ -278453,6 +278474,9 @@ "markdownDescription": "A description of the function\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Description`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-description) property of an `AWS::Lambda::Function` resource\\.", "title": "Description" }, + "DurableConfig": { + "$ref": "#/definitions/PassThroughProp" + }, "Environment": { "$ref": "#/definitions/AWS::Lambda::Function.Environment", "markdownDescription": "The configuration for the runtime environment\\. \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Environment`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) property of an `AWS::Lambda::Function` resource\\.", @@ -278704,6 +278728,9 @@ "title": "Description", "type": "string" }, + "DurableConfig": { + "$ref": "#/definitions/PassThroughProp" + }, "Environment": { "$ref": "#/definitions/AWS::Lambda::Function.Environment", "markdownDescription": "The configuration for the runtime environment\\. \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Environment`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) property of an `AWS::Lambda::Function` resource\\.", diff --git a/schema_source/cloudformation.schema.json b/schema_source/cloudformation.schema.json index b85da2265..9c8354f47 100644 --- a/schema_source/cloudformation.schema.json +++ b/schema_source/cloudformation.schema.json @@ -142749,6 +142749,11 @@ "title": "Description", "type": "string" }, + "DurableConfig": { + "$ref": "#/definitions/AWS::Lambda::Function.DurableConfig", + "markdownDescription": "Configuration for durable function execution.", + "title": "DurableConfig" + }, "Environment": { "$ref": "#/definitions/AWS::Lambda::Function.Environment", "markdownDescription": "Environment variables that are accessible from function code during execution.", @@ -143119,6 +143124,22 @@ }, "type": "object" }, + "AWS::Lambda::Function.DurableConfig": { + "additionalProperties": false, + "properties": { + "ExecutionTimeout": { + "markdownDescription": "The maximum execution timeout in seconds for durable function executions.", + "title": "ExecutionTimeout", + "type": "number" + }, + "RetentionPeriodInDays": { + "markdownDescription": "The retention period in days for durable function execution history.", + "title": "RetentionPeriodInDays", + "type": "number" + } + }, + "type": "object" + }, "AWS::Lambda::LayerVersion": { "additionalProperties": false, "properties": { diff --git a/schema_source/sam.schema.json b/schema_source/sam.schema.json index e366c0c3a..c6b7029ee 100644 --- a/schema_source/sam.schema.json +++ b/schema_source/sam.schema.json @@ -5476,6 +5476,9 @@ "markdownDescription": "A description of the function\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Description`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-description) property of an `AWS::Lambda::Function` resource\\.", "title": "Description" }, + "DurableConfig": { + "$ref": "#/definitions/PassThroughProp" + }, "Environment": { "__samPassThrough": { "markdownDescriptionOverride": "The configuration for the runtime environment\\. \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Environment`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) property of an `AWS::Lambda::Function` resource\\.", @@ -5853,6 +5856,9 @@ ], "title": "Description" }, + "DurableConfig": { + "$ref": "#/definitions/PassThroughProp" + }, "Environment": { "__samPassThrough": { "markdownDescriptionOverride": "The configuration for the runtime environment\\. \n*Type*: [Environment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Environment`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html) property of an `AWS::Lambda::Function` resource\\.", diff --git a/tests/translator/input/function_with_durable_config.yaml b/tests/translator/input/function_with_durable_config.yaml new file mode 100644 index 000000000..ee2b774a2 --- /dev/null +++ b/tests/translator/input/function_with_durable_config.yaml @@ -0,0 +1,10 @@ +Resources: + FunctionWithDurableConfig: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://sam-demo-bucket/hello.zip + Handler: hello.handler + Runtime: python3.9 + DurableConfig: + ExecutionTimeout: 3600 + RetentionPeriodInDays: 45 diff --git a/tests/translator/input/function_with_durable_config_globals.yaml b/tests/translator/input/function_with_durable_config_globals.yaml new file mode 100644 index 000000000..6af020c65 --- /dev/null +++ b/tests/translator/input/function_with_durable_config_globals.yaml @@ -0,0 +1,27 @@ +Globals: + Function: + Runtime: python3.11 + Handler: index.handler + DurableConfig: + ExecutionTimeout: 3600 + RetentionPeriodInDays: 30 + +Resources: + DurableFunctionWithGlobals: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://my-bucket/my-function.zip + + DurableFunctionWithOverride: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://my-bucket/my-function.zip + DurableConfig: + ExecutionTimeout: 7200 + RetentionPeriodInDays: 7 + + RegularFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://my-bucket/my-function.zip + # This function should inherit the global DurableConfig diff --git a/tests/translator/input/globals_for_function.yaml b/tests/translator/input/globals_for_function.yaml index a4cf09729..96e24eeb8 100644 --- a/tests/translator/input/globals_for_function.yaml +++ b/tests/translator/input/globals_for_function.yaml @@ -34,6 +34,9 @@ Globals: LogGroup: myJsonStructuredLogs RecursiveLoop: ALLOW SourceKMSKeyArn: arn:aws:kms:us-west-2:123456789012:key/dec86919-7219-4e8d-8871-7f1609df2c7f + DurableConfig: + ExecutionTimeout: 3600 + RetentionPeriodInDays: 30 @@ -69,3 +72,6 @@ Resources: UpdateRuntimeOn: FunctionChange RecursiveLoop: TERMINATE SourceKMSKeyArn: arn:aws:kms:us-west-2:987654321098:key/dec86919-7219-4e8d-8871-7f1609df2c7f + DurableConfig: + ExecutionTimeout: 7200 + RetentionPeriodInDays: 7 diff --git a/tests/translator/output/aws-cn/function_with_durable_config.json b/tests/translator/output/aws-cn/function_with_durable_config.json new file mode 100644 index 000000000..f4ef270d1 --- /dev/null +++ b/tests/translator/output/aws-cn/function_with_durable_config.json @@ -0,0 +1,61 @@ +{ + "Resources": { + "FunctionWithDurableConfig": { + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 45 + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithDurableConfigRole", + "Arn" + ] + }, + "Runtime": "python3.9", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "FunctionWithDurableConfigRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-cn/function_with_durable_config_globals.json b/tests/translator/output/aws-cn/function_with_durable_config_globals.json new file mode 100644 index 000000000..11faea418 --- /dev/null +++ b/tests/translator/output/aws-cn/function_with_durable_config_globals.json @@ -0,0 +1,175 @@ +{ + "Resources": { + "DurableFunctionWithGlobals": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DurableFunctionWithGlobalsRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "DurableFunctionWithGlobalsRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "DurableFunctionWithOverride": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 7200, + "RetentionPeriodInDays": 7 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DurableFunctionWithOverrideRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "DurableFunctionWithOverrideRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "RegularFunction": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "RegularFunctionRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "RegularFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-cn/globals_for_function.json b/tests/translator/output/aws-cn/globals_for_function.json index 293cf5109..bce45277b 100644 --- a/tests/translator/output/aws-cn/globals_for_function.json +++ b/tests/translator/output/aws-cn/globals_for_function.json @@ -10,6 +10,10 @@ "S3Key": "hello.zip", "SourceKMSKeyArn": "arn:aws:kms:us-west-2:987654321098:key/dec86919-7219-4e8d-8871-7f1609df2c7f" }, + "DurableConfig": { + "ExecutionTimeout": 7200, + "RetentionPeriodInDays": 7 + }, "Environment": { "Variables": { "Var1": "value1", @@ -153,6 +157,10 @@ "S3Key": "global.zip", "SourceKMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/dec86919-7219-4e8d-8871-7f1609df2c7f" }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, "Environment": { "Variables": { "Var1": "value1", diff --git a/tests/translator/output/aws-us-gov/function_with_durable_config.json b/tests/translator/output/aws-us-gov/function_with_durable_config.json new file mode 100644 index 000000000..841337ed9 --- /dev/null +++ b/tests/translator/output/aws-us-gov/function_with_durable_config.json @@ -0,0 +1,61 @@ +{ + "Resources": { + "FunctionWithDurableConfig": { + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 45 + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithDurableConfigRole", + "Arn" + ] + }, + "Runtime": "python3.9", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "FunctionWithDurableConfigRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-us-gov/function_with_durable_config_globals.json b/tests/translator/output/aws-us-gov/function_with_durable_config_globals.json new file mode 100644 index 000000000..acd1d77ad --- /dev/null +++ b/tests/translator/output/aws-us-gov/function_with_durable_config_globals.json @@ -0,0 +1,175 @@ +{ + "Resources": { + "DurableFunctionWithGlobals": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DurableFunctionWithGlobalsRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "DurableFunctionWithGlobalsRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "DurableFunctionWithOverride": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 7200, + "RetentionPeriodInDays": 7 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DurableFunctionWithOverrideRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "DurableFunctionWithOverrideRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "RegularFunction": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "RegularFunctionRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "RegularFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/aws-us-gov/globals_for_function.json b/tests/translator/output/aws-us-gov/globals_for_function.json index fceebdcdd..8b8ad102b 100644 --- a/tests/translator/output/aws-us-gov/globals_for_function.json +++ b/tests/translator/output/aws-us-gov/globals_for_function.json @@ -10,6 +10,10 @@ "S3Key": "hello.zip", "SourceKMSKeyArn": "arn:aws:kms:us-west-2:987654321098:key/dec86919-7219-4e8d-8871-7f1609df2c7f" }, + "DurableConfig": { + "ExecutionTimeout": 7200, + "RetentionPeriodInDays": 7 + }, "Environment": { "Variables": { "Var1": "value1", @@ -153,6 +157,10 @@ "S3Key": "global.zip", "SourceKMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/dec86919-7219-4e8d-8871-7f1609df2c7f" }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, "Environment": { "Variables": { "Var1": "value1", diff --git a/tests/translator/output/function_with_durable_config.json b/tests/translator/output/function_with_durable_config.json new file mode 100644 index 000000000..04bd66bc6 --- /dev/null +++ b/tests/translator/output/function_with_durable_config.json @@ -0,0 +1,61 @@ +{ + "Resources": { + "FunctionWithDurableConfig": { + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "hello.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 45 + }, + "Handler": "hello.handler", + "Role": { + "Fn::GetAtt": [ + "FunctionWithDurableConfigRole", + "Arn" + ] + }, + "Runtime": "python3.9", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "FunctionWithDurableConfigRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/function_with_durable_config_globals.json b/tests/translator/output/function_with_durable_config_globals.json new file mode 100644 index 000000000..075dfceaf --- /dev/null +++ b/tests/translator/output/function_with_durable_config_globals.json @@ -0,0 +1,175 @@ +{ + "Resources": { + "DurableFunctionWithGlobals": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DurableFunctionWithGlobalsRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "DurableFunctionWithGlobalsRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "DurableFunctionWithOverride": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 7200, + "RetentionPeriodInDays": 7 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "DurableFunctionWithOverrideRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "DurableFunctionWithOverrideRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + }, + "RegularFunction": { + "Properties": { + "Code": { + "S3Bucket": "my-bucket", + "S3Key": "my-function.zip" + }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "RegularFunctionRole", + "Arn" + ] + }, + "Runtime": "python3.11", + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::Lambda::Function" + }, + "RegularFunctionRole": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ], + "Tags": [ + { + "Key": "lambda:createdBy", + "Value": "SAM" + } + ] + }, + "Type": "AWS::IAM::Role" + } + } +} diff --git a/tests/translator/output/globals_for_function.json b/tests/translator/output/globals_for_function.json index d3749cd9a..27e1a1ebd 100644 --- a/tests/translator/output/globals_for_function.json +++ b/tests/translator/output/globals_for_function.json @@ -10,6 +10,10 @@ "S3Key": "hello.zip", "SourceKMSKeyArn": "arn:aws:kms:us-west-2:987654321098:key/dec86919-7219-4e8d-8871-7f1609df2c7f" }, + "DurableConfig": { + "ExecutionTimeout": 7200, + "RetentionPeriodInDays": 7 + }, "Environment": { "Variables": { "Var1": "value1", @@ -153,6 +157,10 @@ "S3Key": "global.zip", "SourceKMSKeyArn": "arn:aws:kms:us-west-2:123456789012:key/dec86919-7219-4e8d-8871-7f1609df2c7f" }, + "DurableConfig": { + "ExecutionTimeout": 3600, + "RetentionPeriodInDays": 30 + }, "Environment": { "Variables": { "Var1": "value1", From 33d1623558adc4e4872e78ae8ba674c1e60c4e52 Mon Sep 17 00:00:00 2001 From: aws-sam-cli-bot <46753707+aws-sam-cli-bot@users.noreply.github.com> Date: Tue, 2 Dec 2025 17:01:13 +0000 Subject: [PATCH 2/2] chore: bump version to 1.105.0 --- samtranslator/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samtranslator/__init__.py b/samtranslator/__init__.py index 1e7114c2e..c64333da5 100644 --- a/samtranslator/__init__.py +++ b/samtranslator/__init__.py @@ -1 +1 @@ -__version__ = "1.103.0" +__version__ = "1.105.0"