Skip to content

Commit 500895f

Browse files
authored
Merge branch 'main' into release-v1.82.0
2 parents fb37805 + b164667 commit 500895f

22 files changed

+553
-9
lines changed

docs/globals.rst

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Currently, the following resources and properties are being supported:
7474
Architectures:
7575
EphemeralStorage:
7676
RuntimeManagementConfig:
77+
LoggingConfig:
7778
7879
Api:
7980
# Properties of AWS::Serverless::Api

integration/combination/test_function_with_msk.py

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ def test_function_with_msk_trigger_using_manage_policy(self):
2828
parameters.append(self.generate_parameter("MskClusterName2", cluster_name))
2929
self._common_validations_for_MSK("combination/function_with_msk_using_managed_policy", parameters)
3030

31+
def test_function_with_msk_trigger_and_s3_onfailure_events_destinations(self):
32+
companion_stack_outputs = self.companion_stack_outputs
33+
parameters = self.get_parameters(companion_stack_outputs)
34+
cluster_name = "MskCluster3-" + generate_suffix()
35+
parameters.append(self.generate_parameter("MskClusterName3", cluster_name))
36+
self._common_validations_for_MSK(
37+
"combination/function_with_msk_trigger_and_s3_onfailure_events_destinations", parameters
38+
)
39+
3140
def _common_validations_for_MSK(self, file_name, parameters):
3241
self.create_and_verify_stack(file_name, parameters)
3342

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"LogicalResourceId": "MyMskStreamProcessor",
4+
"ResourceType": "AWS::Lambda::Function"
5+
},
6+
{
7+
"LogicalResourceId": "MyLambdaExecutionRole",
8+
"ResourceType": "AWS::IAM::Role"
9+
},
10+
{
11+
"LogicalResourceId": "MyMskCluster",
12+
"ResourceType": "AWS::MSK::Cluster"
13+
},
14+
{
15+
"LogicalResourceId": "MyMskStreamProcessorMyMskEvent",
16+
"ResourceType": "AWS::Lambda::EventSourceMapping"
17+
},
18+
{
19+
"LogicalResourceId": "PreCreatedS3Bucket",
20+
"ResourceType": "AWS::S3::Bucket"
21+
}
22+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
Parameters:
2+
PreCreatedSubnetOne:
3+
Type: String
4+
PreCreatedSubnetTwo:
5+
Type: String
6+
MskClusterName3:
7+
Type: String
8+
9+
Resources:
10+
MyLambdaExecutionRole:
11+
Type: AWS::IAM::Role
12+
Properties:
13+
AssumeRolePolicyDocument:
14+
Version: '2012-10-17'
15+
Statement:
16+
- Action: [sts:AssumeRole]
17+
Effect: Allow
18+
Principal:
19+
Service: [lambda.amazonaws.com]
20+
Policies:
21+
- PolicyName: IntegrationTestExecution
22+
PolicyDocument:
23+
Statement:
24+
- Action: [kafka:DescribeCluster, kafka:GetBootstrapBrokers, ec2:CreateNetworkInterface,
25+
ec2:DescribeNetworkInterfaces, ec2:DescribeVpcs, ec2:DeleteNetworkInterface,
26+
ec2:DescribeSubnets, ec2:DescribeSecurityGroups, logs:CreateLogGroup,
27+
logs:CreateLogStream, logs:PutLogEvents]
28+
Effect: Allow
29+
Resource: '*'
30+
ManagedPolicyArns: [arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole]
31+
Tags:
32+
- {Value: SAM, Key: lambda:createdBy}
33+
34+
MyMskCluster:
35+
Type: AWS::MSK::Cluster
36+
Properties:
37+
BrokerNodeGroupInfo:
38+
ClientSubnets:
39+
- Ref: PreCreatedSubnetOne
40+
- Ref: PreCreatedSubnetTwo
41+
InstanceType: kafka.t3.small
42+
StorageInfo:
43+
EBSStorageInfo:
44+
VolumeSize: 1
45+
ClusterName:
46+
Ref: MskClusterName3
47+
KafkaVersion: 2.4.1.1
48+
NumberOfBrokerNodes: 2
49+
50+
MyMskStreamProcessor:
51+
Type: AWS::Serverless::Function
52+
Properties:
53+
Runtime: nodejs18.x
54+
Handler: index.handler
55+
CodeUri: ${codeuri}
56+
Role:
57+
Fn::GetAtt: [MyLambdaExecutionRole, Arn]
58+
Events:
59+
MyMskEvent:
60+
Type: MSK
61+
Properties:
62+
StartingPosition: LATEST
63+
Stream:
64+
Ref: MyMskCluster
65+
Topics:
66+
- MyDummyTestTopic
67+
DestinationConfig:
68+
OnFailure:
69+
Type: S3
70+
Destination:
71+
Fn::GetAtt:
72+
- PreCreatedS3Bucket
73+
- Arn
74+
75+
PreCreatedS3Bucket:
76+
Type: AWS::S3::Bucket
77+
DeletionPolicy: Delete
78+
79+
Metadata:
80+
SamTransformTest: true

samtranslator/internal/schema_source/aws_serverless_function.py

+4
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ class MSKEventProperties(BaseModel):
414414
Stream: PassThroughProp = mskeventproperties("Stream")
415415
Topics: PassThroughProp = mskeventproperties("Topics")
416416
SourceAccessConfigurations: Optional[PassThroughProp] = mskeventproperties("SourceAccessConfigurations")
417+
DestinationConfig: Optional[PassThroughProp] # TODO: add documentation
417418

418419

419420
class MSKEvent(BaseModel):
@@ -506,6 +507,7 @@ class ScheduleV2Event(BaseModel):
506507
EphemeralStorage = Optional[PassThroughProp]
507508
SnapStart = Optional[PassThroughProp] # TODO: check the type
508509
RuntimeManagementConfig = Optional[PassThroughProp] # TODO: check the type
510+
LoggingConfig = Optional[PassThroughProp] # TODO: add documentation
509511

510512

511513
class Properties(BaseModel):
@@ -631,6 +633,7 @@ class Properties(BaseModel):
631633
Tracing: Optional[Tracing] = prop("Tracing")
632634
VersionDescription: Optional[PassThroughProp] = prop("VersionDescription")
633635
VpcConfig: Optional[VpcConfig] = prop("VpcConfig")
636+
LoggingConfig: Optional[PassThroughProp] # TODO: add documentation
634637

635638

636639
class Globals(BaseModel):
@@ -688,6 +691,7 @@ class Globals(BaseModel):
688691
)
689692
SnapStart: Optional[SnapStart] = prop("SnapStart")
690693
RuntimeManagementConfig: Optional[RuntimeManagementConfig] = prop("RuntimeManagementConfig")
694+
LoggingConfig: Optional[PassThroughProp] # TODO: add documentation
691695

692696

693697
class Resource(ResourceAttributes):

samtranslator/model/eventsources/pull.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,15 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
172172
# `Type` property is for sam to attach the right policies
173173
destination_type = on_failure.get("Type")
174174

175-
# SAM attaches the policies for SQS or SNS only if 'Type' is given
175+
# SAM attaches the policies for SQS, SNS or S3 only if 'Type' is given
176176
if destination_type:
177177
# delete this field as its used internally for SAM to determine the policy
178178
del on_failure["Type"]
179-
# the values 'SQS' and 'SNS' are allowed. No intrinsics are allowed
180-
if destination_type not in ["SQS", "SNS"]:
181-
raise InvalidEventException(self.logical_id, "The only valid values for 'Type' are 'SQS' and 'SNS'")
179+
# the values 'SQS', 'SNS', and 'S3' are allowed. No intrinsics are allowed
180+
if destination_type not in ["SQS", "SNS", "S3"]:
181+
raise InvalidEventException(
182+
self.logical_id, "The only valid values for 'Type' are 'SQS', 'SNS', and 'S3'"
183+
)
182184
if destination_type == "SQS":
183185
queue_arn = on_failure.get("Destination")
184186
destination_config_policy = IAMRolePolicies().sqs_send_message_role_policy(
@@ -189,6 +191,11 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
189191
destination_config_policy = IAMRolePolicies().sns_publish_role_policy(
190192
sns_topic_arn, self.logical_id
191193
)
194+
elif destination_type == "S3":
195+
s3_arn = on_failure.get("Destination")
196+
destination_config_policy = IAMRolePolicies().s3_send_event_payload_role_policy(
197+
s3_arn, self.logical_id
198+
)
192199

193200
lambda_eventsourcemapping.DestinationConfig = self.DestinationConfig
194201

samtranslator/model/iam.py

+13
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,19 @@ def sns_publish_role_policy(cls, topic_arn: Any, logical_id: str) -> Dict[str, A
126126
"PolicyDocument": {"Statement": [{"Action": "sns:publish", "Effect": "Allow", "Resource": topic_arn}]},
127127
}
128128

129+
@classmethod
130+
def s3_send_event_payload_role_policy(cls, s3_arn: Any, logical_id: str) -> Dict[str, Any]:
131+
s3_arn_with_wild_card = {"Fn::Join": ["/", [s3_arn, "*"]]}
132+
return {
133+
"PolicyName": logical_id + "S3Policy",
134+
"PolicyDocument": {
135+
"Statement": [
136+
{"Action": "s3:PutObject", "Effect": "Allow", "Resource": s3_arn_with_wild_card},
137+
{"Action": "s3:ListBucket", "Effect": "Allow", "Resource": s3_arn},
138+
]
139+
},
140+
}
141+
129142
@classmethod
130143
def event_bus_put_events_role_policy(cls, event_bus_arn: Any, logical_id: str) -> Dict[str, Any]:
131144
return {

samtranslator/model/lambda_.py

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class LambdaFunction(Resource):
3434
"SnapStart": GeneratedProperty(),
3535
"EphemeralStorage": GeneratedProperty(),
3636
"RuntimeManagementConfig": GeneratedProperty(),
37+
"LoggingConfig": GeneratedProperty(),
3738
}
3839

3940
Code: Dict[str, Any]
@@ -60,6 +61,7 @@ class LambdaFunction(Resource):
6061
SnapStart: Optional[Dict[str, Any]]
6162
EphemeralStorage: Optional[Dict[str, Any]]
6263
RuntimeManagementConfig: Optional[Dict[str, Any]]
64+
LoggingConfig: Optional[Dict[str, Any]]
6365

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

samtranslator/model/sam_resources.py

+3
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class SamFunction(SamResourceMacro):
179179
"SnapStart": PropertyType(False, IS_DICT),
180180
"FunctionUrlConfig": PropertyType(False, IS_DICT),
181181
"RuntimeManagementConfig": PassThroughProperty(False),
182+
"LoggingConfig": PassThroughProperty(False),
182183
}
183184

184185
FunctionName: Optional[Intrinsicable[str]]
@@ -220,6 +221,7 @@ class SamFunction(SamResourceMacro):
220221
Architectures: Optional[List[Any]]
221222
SnapStart: Optional[Dict[str, Any]]
222223
FunctionUrlConfig: Optional[Dict[str, Any]]
224+
LoggingConfig: Optional[Dict[str, Any]]
223225

224226
event_resolver = ResourceTypeResolver(
225227
samtranslator.model.eventsources,
@@ -603,6 +605,7 @@ def _construct_lambda_function(self, intrinsics_resolver: IntrinsicsResolver) ->
603605
lambda_function.CodeSigningConfigArn = self.CodeSigningConfigArn
604606

605607
lambda_function.RuntimeManagementConfig = self.RuntimeManagementConfig # type: ignore[attr-defined]
608+
lambda_function.LoggingConfig = self.LoggingConfig
606609
self._validate_package_type(lambda_function)
607610
return lambda_function
608611

samtranslator/plugins/globals/globals.py

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class Globals:
5353
"EphemeralStorage",
5454
"FunctionUrlConfig",
5555
"RuntimeManagementConfig",
56+
"LoggingConfig",
5657
],
5758
# Everything except
5859
# DefinitionBody: because its hard to reason about merge of Swagger dictionaries

samtranslator/schema/schema.json

+9
Original file line numberDiff line numberDiff line change
@@ -252166,6 +252166,9 @@
252166252166
"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\\.",
252167252167
"title": "ConsumerGroupId"
252168252168
},
252169+
"DestinationConfig": {
252170+
"$ref": "#/definitions/PassThroughProp"
252171+
},
252169252172
"FilterCriteria": {
252170252173
"allOf": [
252171252174
{
@@ -254743,6 +254746,9 @@
254743254746
"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\\.",
254744254747
"title": "Layers"
254745254748
},
254749+
"LoggingConfig": {
254750+
"$ref": "#/definitions/PassThroughProp"
254751+
},
254746254752
"MemorySize": {
254747254753
"allOf": [
254748254754
{
@@ -255089,6 +255095,9 @@
255089255095
"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\\.",
255090255096
"title": "Layers"
255091255097
},
255098+
"LoggingConfig": {
255099+
"$ref": "#/definitions/PassThroughProp"
255100+
},
255092255101
"MemorySize": {
255093255102
"allOf": [
255094255103
{

schema_source/sam.schema.json

+9
Original file line numberDiff line numberDiff line change
@@ -2380,6 +2380,9 @@
23802380
"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\\.",
23812381
"title": "ConsumerGroupId"
23822382
},
2383+
"DestinationConfig": {
2384+
"$ref": "#/definitions/PassThroughProp"
2385+
},
23832386
"FilterCriteria": {
23842387
"allOf": [
23852388
{
@@ -5391,6 +5394,9 @@
53915394
"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\\.",
53925395
"title": "Layers"
53935396
},
5397+
"LoggingConfig": {
5398+
"$ref": "#/definitions/PassThroughProp"
5399+
},
53945400
"MemorySize": {
53955401
"allOf": [
53965402
{
@@ -5914,6 +5920,9 @@
59145920
"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\\.",
59155921
"title": "Layers"
59165922
},
5923+
"LoggingConfig": {
5924+
"$ref": "#/definitions/PassThroughProp"
5925+
},
59175926
"MemorySize": {
59185927
"allOf": [
59195928
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Resources:
2+
MyMskStreamProcessor:
3+
Type: AWS::Serverless::Function
4+
Properties:
5+
Runtime: nodejs12.x
6+
Handler: index.handler
7+
CodeUri: s3://sam-demo-bucket/kafka.zip
8+
Events:
9+
MyMskEvent:
10+
Type: MSK
11+
Properties:
12+
StartingPosition: LATEST
13+
Stream: !Sub arn:${AWS::Partition}:kafka:${AWS::Region}:012345678901:cluster/mycluster/6cc0432b-8618-4f44-bccc-e1fbd8fb7c4d-2
14+
Topics:
15+
- MyDummyTestTopic
16+
ConsumerGroupId: consumergroup1
17+
DestinationConfig:
18+
OnFailure:
19+
Type: S3
20+
Destination: !Sub arn:${AWS::Partition}:s3:::my-s3-arn

tests/translator/input/globals_for_function.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ Globals:
3030
Size: 1024
3131
RuntimeManagementConfig:
3232
UpdateRuntimeOn: Auto
33+
LoggingConfig:
34+
LogGroup: myJsonStructuredLogs
35+
36+
3337

3438
Resources:
3539
MinimalFunction:

0 commit comments

Comments
 (0)