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

Release 1.80.0 (to main) #3419

Merged
merged 4 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions docs/globals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Currently, the following resources and properties are being supported:
Architectures:
EphemeralStorage:
RuntimeManagementConfig:
LoggingConfig:
Api:
# Properties of AWS::Serverless::Api
Expand Down
9 changes: 9 additions & 0 deletions integration/combination/test_function_with_msk.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ def test_function_with_msk_trigger_using_manage_policy(self):
parameters.append(self.generate_parameter("MskClusterName2", cluster_name))
self._common_validations_for_MSK("combination/function_with_msk_using_managed_policy", parameters)

def test_function_with_msk_trigger_and_s3_onfailure_events_destinations(self):
companion_stack_outputs = self.companion_stack_outputs
parameters = self.get_parameters(companion_stack_outputs)
cluster_name = "MskCluster3-" + generate_suffix()
parameters.append(self.generate_parameter("MskClusterName3", cluster_name))
self._common_validations_for_MSK(
"combination/function_with_msk_trigger_and_s3_onfailure_events_destinations", parameters
)

def _common_validations_for_MSK(self, file_name, parameters):
self.create_and_verify_stack(file_name, parameters)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"LogicalResourceId": "MyMskStreamProcessor",
"ResourceType": "AWS::Lambda::Function"
},
{
"LogicalResourceId": "MyLambdaExecutionRole",
"ResourceType": "AWS::IAM::Role"
},
{
"LogicalResourceId": "MyMskCluster",
"ResourceType": "AWS::MSK::Cluster"
},
{
"LogicalResourceId": "MyMskStreamProcessorMyMskEvent",
"ResourceType": "AWS::Lambda::EventSourceMapping"
},
{
"LogicalResourceId": "PreCreatedS3Bucket",
"ResourceType": "AWS::S3::Bucket"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
Parameters:
PreCreatedSubnetOne:
Type: String
PreCreatedSubnetTwo:
Type: String
MskClusterName3:
Type: String

Resources:
MyLambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action: [sts:AssumeRole]
Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Policies:
- PolicyName: IntegrationTestExecution
PolicyDocument:
Statement:
- Action: [kafka:DescribeCluster, kafka:GetBootstrapBrokers, ec2:CreateNetworkInterface,
ec2:DescribeNetworkInterfaces, ec2:DescribeVpcs, ec2:DeleteNetworkInterface,
ec2:DescribeSubnets, ec2:DescribeSecurityGroups, logs:CreateLogGroup,
logs:CreateLogStream, logs:PutLogEvents]
Effect: Allow
Resource: '*'
ManagedPolicyArns: [arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
Tags:
- {Value: SAM, Key: lambda:createdBy}

MyMskCluster:
Type: AWS::MSK::Cluster
Properties:
BrokerNodeGroupInfo:
ClientSubnets:
- Ref: PreCreatedSubnetOne
- Ref: PreCreatedSubnetTwo
InstanceType: kafka.t3.small
StorageInfo:
EBSStorageInfo:
VolumeSize: 1
ClusterName:
Ref: MskClusterName3
KafkaVersion: 2.4.1.1
NumberOfBrokerNodes: 2

MyMskStreamProcessor:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs18.x
Handler: index.handler
CodeUri: ${codeuri}
Role:
Fn::GetAtt: [MyLambdaExecutionRole, Arn]
Events:
MyMskEvent:
Type: MSK
Properties:
StartingPosition: LATEST
Stream:
Ref: MyMskCluster
Topics:
- MyDummyTestTopic
DestinationConfig:
OnFailure:
Type: S3
Destination:
Fn::GetAtt:
- PreCreatedS3Bucket
- Arn

PreCreatedS3Bucket:
Type: AWS::S3::Bucket
DeletionPolicy: Delete

Metadata:
SamTransformTest: true
2 changes: 1 addition & 1 deletion samtranslator/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.79.0"
__version__ = "1.80.0"
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ class MSKEventProperties(BaseModel):
Stream: PassThroughProp = mskeventproperties("Stream")
Topics: PassThroughProp = mskeventproperties("Topics")
SourceAccessConfigurations: Optional[PassThroughProp] = mskeventproperties("SourceAccessConfigurations")
DestinationConfig: Optional[PassThroughProp] # TODO: add documentation


class MSKEvent(BaseModel):
Expand Down Expand Up @@ -506,6 +507,7 @@ class ScheduleV2Event(BaseModel):
EphemeralStorage = Optional[PassThroughProp]
SnapStart = Optional[PassThroughProp] # TODO: check the type
RuntimeManagementConfig = Optional[PassThroughProp] # TODO: check the type
LoggingConfig = Optional[PassThroughProp] # TODO: add documentation


class Properties(BaseModel):
Expand Down Expand Up @@ -631,6 +633,7 @@ class Properties(BaseModel):
Tracing: Optional[Tracing] = prop("Tracing")
VersionDescription: Optional[PassThroughProp] = prop("VersionDescription")
VpcConfig: Optional[VpcConfig] = prop("VpcConfig")
LoggingConfig: Optional[PassThroughProp] # TODO: add documentation


class Globals(BaseModel):
Expand Down Expand Up @@ -688,6 +691,7 @@ class Globals(BaseModel):
)
SnapStart: Optional[SnapStart] = prop("SnapStart")
RuntimeManagementConfig: Optional[RuntimeManagementConfig] = prop("RuntimeManagementConfig")
LoggingConfig: Optional[PassThroughProp] # TODO: add documentation


class Resource(ResourceAttributes):
Expand Down
15 changes: 11 additions & 4 deletions samtranslator/model/eventsources/pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,15 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
# `Type` property is for sam to attach the right policies
destination_type = on_failure.get("Type")

# SAM attaches the policies for SQS or SNS only if 'Type' is given
# SAM attaches the policies for SQS, SNS or S3 only if 'Type' is given
if destination_type:
# delete this field as its used internally for SAM to determine the policy
del on_failure["Type"]
# the values 'SQS' and 'SNS' are allowed. No intrinsics are allowed
if destination_type not in ["SQS", "SNS"]:
raise InvalidEventException(self.logical_id, "The only valid values for 'Type' are 'SQS' and 'SNS'")
# the values 'SQS', 'SNS', and 'S3' are allowed. No intrinsics are allowed
if destination_type not in ["SQS", "SNS", "S3"]:
raise InvalidEventException(
self.logical_id, "The only valid values for 'Type' are 'SQS', 'SNS', and 'S3'"
)
if destination_type == "SQS":
queue_arn = on_failure.get("Destination")
destination_config_policy = IAMRolePolicies().sqs_send_message_role_policy(
Expand All @@ -189,6 +191,11 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
destination_config_policy = IAMRolePolicies().sns_publish_role_policy(
sns_topic_arn, self.logical_id
)
elif destination_type == "S3":
s3_arn = on_failure.get("Destination")
destination_config_policy = IAMRolePolicies().s3_send_event_payload_role_policy(
s3_arn, self.logical_id
)

lambda_eventsourcemapping.DestinationConfig = self.DestinationConfig

Expand Down
13 changes: 13 additions & 0 deletions samtranslator/model/iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,19 @@ def sns_publish_role_policy(cls, topic_arn: Any, logical_id: str) -> Dict[str, A
"PolicyDocument": {"Statement": [{"Action": "sns:publish", "Effect": "Allow", "Resource": topic_arn}]},
}

@classmethod
def s3_send_event_payload_role_policy(cls, s3_arn: Any, logical_id: str) -> Dict[str, Any]:
s3_arn_with_wild_card = {"Fn::Join": ["/", [s3_arn, "*"]]}
return {
"PolicyName": logical_id + "S3Policy",
"PolicyDocument": {
"Statement": [
{"Action": "s3:PutObject", "Effect": "Allow", "Resource": s3_arn_with_wild_card},
{"Action": "s3:ListBucket", "Effect": "Allow", "Resource": s3_arn},
]
},
}

@classmethod
def event_bus_put_events_role_policy(cls, event_bus_arn: Any, logical_id: str) -> Dict[str, Any]:
return {
Expand Down
2 changes: 2 additions & 0 deletions samtranslator/model/lambda_.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class LambdaFunction(Resource):
"SnapStart": GeneratedProperty(),
"EphemeralStorage": GeneratedProperty(),
"RuntimeManagementConfig": GeneratedProperty(),
"LoggingConfig": GeneratedProperty(),
}

Code: Dict[str, Any]
Expand All @@ -60,6 +61,7 @@ class LambdaFunction(Resource):
SnapStart: Optional[Dict[str, Any]]
EphemeralStorage: Optional[Dict[str, Any]]
RuntimeManagementConfig: Optional[Dict[str, Any]]
LoggingConfig: Optional[Dict[str, Any]]

runtime_attrs = {"name": lambda self: ref(self.logical_id), "arn": lambda self: fnGetAtt(self.logical_id, "Arn")}

Expand Down
3 changes: 3 additions & 0 deletions samtranslator/model/sam_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class SamFunction(SamResourceMacro):
"SnapStart": PropertyType(False, IS_DICT),
"FunctionUrlConfig": PropertyType(False, IS_DICT),
"RuntimeManagementConfig": PassThroughProperty(False),
"LoggingConfig": PassThroughProperty(False),
}

FunctionName: Optional[Intrinsicable[str]]
Expand Down Expand Up @@ -220,6 +221,7 @@ class SamFunction(SamResourceMacro):
Architectures: Optional[List[Any]]
SnapStart: Optional[Dict[str, Any]]
FunctionUrlConfig: Optional[Dict[str, Any]]
LoggingConfig: Optional[Dict[str, Any]]

event_resolver = ResourceTypeResolver(
samtranslator.model.eventsources,
Expand Down Expand Up @@ -603,6 +605,7 @@ def _construct_lambda_function(self, intrinsics_resolver: IntrinsicsResolver) ->
lambda_function.CodeSigningConfigArn = self.CodeSigningConfigArn

lambda_function.RuntimeManagementConfig = self.RuntimeManagementConfig # type: ignore[attr-defined]
lambda_function.LoggingConfig = self.LoggingConfig
self._validate_package_type(lambda_function)
return lambda_function

Expand Down
1 change: 1 addition & 0 deletions samtranslator/plugins/globals/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class Globals:
"EphemeralStorage",
"FunctionUrlConfig",
"RuntimeManagementConfig",
"LoggingConfig",
],
# Everything except
# DefinitionBody: because its hard to reason about merge of Swagger dictionaries
Expand Down
12 changes: 10 additions & 2 deletions samtranslator/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -85251,8 +85251,7 @@
}
},
"required": [
"Database",
"Sql"
"Database"
],
"type": "object"
},
Expand Down Expand Up @@ -250544,6 +250543,9 @@
"markdownDescription": "A string that configures how events will be read from Kafka topics\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`AmazonManagedKafkaConfiguration`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "ConsumerGroupId"
},
"DestinationConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"FilterCriteria": {
"allOf": [
{
Expand Down Expand Up @@ -253079,6 +253081,9 @@
"markdownDescription": "The list of `LayerVersion` ARNs that this function should use\\. The order specified here is the order in which they will be imported when running the Lambda function\\. \n*Type*: List \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Layers`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-layers) property of an `AWS::Lambda::Function` resource\\.",
"title": "Layers"
},
"LoggingConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"MemorySize": {
"allOf": [
{
Expand Down Expand Up @@ -253424,6 +253429,9 @@
"markdownDescription": "The list of `LayerVersion` ARNs that this function should use\\. The order specified here is the order in which they will be imported when running the Lambda function\\. \n*Type*: List \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Layers`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-layers) property of an `AWS::Lambda::Function` resource\\.",
"title": "Layers"
},
"LoggingConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"MemorySize": {
"allOf": [
{
Expand Down
3 changes: 1 addition & 2 deletions schema_source/cloudformation.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -85209,8 +85209,7 @@
}
},
"required": [
"Database",
"Sql"
"Database"
],
"type": "object"
},
Expand Down
9 changes: 9 additions & 0 deletions schema_source/sam.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2366,6 +2366,9 @@
"markdownDescription": "A string that configures how events will be read from Kafka topics\\. \n*Type*: String \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`AmazonManagedKafkaConfiguration`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
"title": "ConsumerGroupId"
},
"DestinationConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"FilterCriteria": {
"allOf": [
{
Expand Down Expand Up @@ -5335,6 +5338,9 @@
"markdownDescription": "The list of `LayerVersion` ARNs that this function should use\\. The order specified here is the order in which they will be imported when running the Lambda function\\. \n*Type*: List \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Layers`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-layers) property of an `AWS::Lambda::Function` resource\\.",
"title": "Layers"
},
"LoggingConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"MemorySize": {
"allOf": [
{
Expand Down Expand Up @@ -5857,6 +5863,9 @@
"markdownDescription": "The list of `LayerVersion` ARNs that this function should use\\. The order specified here is the order in which they will be imported when running the Lambda function\\. \n*Type*: List \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`Layers`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-layers) property of an `AWS::Lambda::Function` resource\\.",
"title": "Layers"
},
"LoggingConfig": {
"$ref": "#/definitions/PassThroughProp"
},
"MemorySize": {
"allOf": [
{
Expand Down
20 changes: 20 additions & 0 deletions tests/translator/input/function_with_msk_s3_onfailure_dest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Resources:
MyMskStreamProcessor:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs12.x
Handler: index.handler
CodeUri: s3://sam-demo-bucket/kafka.zip
Events:
MyMskEvent:
Type: MSK
Properties:
StartingPosition: LATEST
Stream: !Sub arn:${AWS::Partition}:kafka:${AWS::Region}:012345678901:cluster/mycluster/6cc0432b-8618-4f44-bccc-e1fbd8fb7c4d-2
Topics:
- MyDummyTestTopic
ConsumerGroupId: consumergroup1
DestinationConfig:
OnFailure:
Type: S3
Destination: !Sub arn:${AWS::Partition}:s3:::my-s3-arn
4 changes: 4 additions & 0 deletions tests/translator/input/globals_for_function.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Globals:
Size: 1024
RuntimeManagementConfig:
UpdateRuntimeOn: Auto
LoggingConfig:
LogGroup: myJsonStructuredLogs



Resources:
MinimalFunction:
Expand Down
Loading