Skip to content

Commit 8878af7

Browse files
committed
feat: support observability for ESM (DDB and Kinesis and SQS)
1 parent 158c674 commit 8878af7

File tree

10 files changed

+576
-0
lines changed

10 files changed

+576
-0
lines changed

.cfnlintrc.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ ignore_templates:
136136
- tests/translator/output/**/function_with_intrinsics_resource_attribute.json # CFN now supports intrinsics in DeletionPolicy
137137
- tests/translator/output/**/function_with_snapstart.json # Snapstart intentionally not attached to a lambda version which causes lint issues
138138
- tests/translator/output/**/managed_policies_everything.json # intentionally contains wrong arns
139+
- tests/translator/output/**/function_with_metrics_config.json
139140
ignore_checks:
140141
- E2531 # Deprecated runtime; not relevant for transform tests
141142
- E2533 # Another deprecated runtime; not relevant for transform tests

samtranslator/internal/schema_source/aws_serverless_function.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ class KinesisEventProperties(BaseModel):
178178
StartingPositionTimestamp: Optional[PassThroughProp] = kinesiseventproperties("StartingPositionTimestamp")
179179
Stream: PassThroughProp = kinesiseventproperties("Stream")
180180
TumblingWindowInSeconds: Optional[PassThroughProp] = kinesiseventproperties("TumblingWindowInSeconds")
181+
MetricsConfig: Optional[PassThroughProp]
181182

182183

183184
class KinesisEvent(BaseModel):
@@ -203,6 +204,7 @@ class DynamoDBEventProperties(BaseModel):
203204
StartingPositionTimestamp: Optional[PassThroughProp] = dynamodbeventproperties("StartingPositionTimestamp")
204205
Stream: PassThroughProp = dynamodbeventproperties("Stream")
205206
TumblingWindowInSeconds: Optional[PassThroughProp] = dynamodbeventproperties("TumblingWindowInSeconds")
207+
MetricsConfig: Optional[PassThroughProp]
206208

207209

208210
class DynamoDBEvent(BaseModel):
@@ -241,6 +243,7 @@ class SQSEventProperties(BaseModel):
241243
MaximumBatchingWindowInSeconds: Optional[PassThroughProp] = sqseventproperties("MaximumBatchingWindowInSeconds")
242244
Queue: PassThroughProp = sqseventproperties("Queue")
243245
ScalingConfig: Optional[PassThroughProp] # Update docs when live
246+
MetricsConfig: Optional[PassThroughProp]
244247

245248

246249
class SQSEvent(BaseModel):

samtranslator/model/eventsources/pull.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class PullEventSource(ResourceMacro, metaclass=ABCMeta):
5555
"KmsKeyArn": PassThroughProperty(False),
5656
"ConsumerGroupId": PropertyType(False, IS_STR),
5757
"ScalingConfig": PropertyType(False, IS_DICT),
58+
"MetricsConfig": PropertyType(False, IS_DICT),
5859
}
5960

6061
BatchSize: Optional[Intrinsicable[int]]
@@ -78,6 +79,7 @@ class PullEventSource(ResourceMacro, metaclass=ABCMeta):
7879
KmsKeyArn: Optional[Intrinsicable[str]]
7980
ConsumerGroupId: Optional[Intrinsicable[str]]
8081
ScalingConfig: Optional[Dict[str, Any]]
82+
MetricsConfig: Optional[Dict[str, Any]]
8183

8284
@abstractmethod
8385
def get_policy_arn(self) -> Optional[str]:
@@ -145,6 +147,7 @@ def to_cloudformation(self, **kwargs): # type: ignore[no-untyped-def] # noqa: P
145147
lambda_eventsourcemapping.FilterCriteria = self.FilterCriteria
146148
lambda_eventsourcemapping.KmsKeyArn = self.KmsKeyArn
147149
lambda_eventsourcemapping.ScalingConfig = self.ScalingConfig
150+
lambda_eventsourcemapping.MetricsConfig = self.MetricsConfig
148151
self._validate_filter_criteria()
149152

150153
if self.KafkaBootstrapServers:

samtranslator/model/lambda_.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class LambdaEventSourceMapping(Resource):
122122
"AmazonManagedKafkaEventSourceConfig": GeneratedProperty(),
123123
"SelfManagedKafkaEventSourceConfig": GeneratedProperty(),
124124
"ScalingConfig": GeneratedProperty(),
125+
"MetricsConfig": GeneratedProperty(),
125126
}
126127

127128
runtime_attrs = {"name": lambda self: ref(self.logical_id)}

samtranslator/schema/schema.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274755,6 +274755,9 @@
274755274755
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
274756274756
"title": "MaximumRetryAttempts"
274757274757
},
274758+
"MetricsConfig": {
274759+
"$ref": "#/definitions/PassThroughProp"
274760+
},
274758274761
"ParallelizationFactor": {
274759274762
"allOf": [
274760274763
{
@@ -275502,6 +275505,9 @@
275502275505
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
275503275506
"title": "MaximumRetryAttempts"
275504275507
},
275508+
"MetricsConfig": {
275509+
"$ref": "#/definitions/PassThroughProp"
275510+
},
275505275511
"ParallelizationFactor": {
275506275512
"allOf": [
275507275513
{
@@ -276775,6 +276781,9 @@
276775276781
"markdownDescription": "The maximum amount of time, in seconds, to gather records before invoking the function\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumBatchingWindowInSeconds`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumbatchingwindowinseconds) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
276776276782
"title": "MaximumBatchingWindowInSeconds"
276777276783
},
276784+
"MetricsConfig": {
276785+
"$ref": "#/definitions/PassThroughProp"
276786+
},
276778276787
"Queue": {
276779276788
"allOf": [
276780276789
{

schema_source/sam.schema.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,9 @@
10041004
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
10051005
"title": "MaximumRetryAttempts"
10061006
},
1007+
"MetricsConfig": {
1008+
"$ref": "#/definitions/PassThroughProp"
1009+
},
10071010
"ParallelizationFactor": {
10081011
"allOf": [
10091012
{
@@ -1769,6 +1772,9 @@
17691772
"markdownDescription": "The maximum number of times to retry when the function returns an error\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumRetryAttempts`](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
17701773
"title": "MaximumRetryAttempts"
17711774
},
1775+
"MetricsConfig": {
1776+
"$ref": "#/definitions/PassThroughProp"
1777+
},
17721778
"ParallelizationFactor": {
17731779
"allOf": [
17741780
{
@@ -2973,6 +2979,9 @@
29732979
"markdownDescription": "The maximum amount of time, in seconds, to gather records before invoking the function\\. \n*Type*: Integer \n*Required*: No \n*AWS CloudFormation compatibility*: This property is passed directly to the [`MaximumBatchingWindowInSeconds`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumbatchingwindowinseconds) property of an `AWS::Lambda::EventSourceMapping` resource\\.",
29742980
"title": "MaximumBatchingWindowInSeconds"
29752981
},
2982+
"MetricsConfig": {
2983+
"$ref": "#/definitions/PassThroughProp"
2984+
},
29762985
"Queue": {
29772986
"allOf": [
29782987
{
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Resources:
2+
FilteredEventsFunction:
3+
Type: AWS::Serverless::Function
4+
Properties:
5+
CodeUri: s3://sam-demo-bucket/metricsConfig.zip
6+
Handler: index.handler
7+
Runtime: nodejs16.x
8+
Events:
9+
KinesisStream:
10+
Type: Kinesis
11+
Properties:
12+
Stream: !GetAtt KinesisStream.Arn
13+
StartingPosition: LATEST
14+
MetricsConfig:
15+
Metrics:
16+
- EventCount
17+
FilterCriteria:
18+
Filters:
19+
- Pattern: '{"name": "value"}'
20+
- Pattern: '{"name2": "value2"}'
21+
DynamoDBStreamEvent:
22+
Type: DynamoDB
23+
Properties:
24+
Stream: !GetAtt DynamoDBTable.StreamArn
25+
StartingPosition: TRIM_HORIZON
26+
MetricsConfig:
27+
Metrics: []
28+
FilterCriteria:
29+
Filters: []
30+
MySqsQueue:
31+
Type: SQS
32+
Properties:
33+
Queue: !GetAtt MySqsQueue.Arn
34+
MetricsConfig:
35+
Metrics:
36+
- EventCount
37+
FilterCriteria:
38+
Filters:
39+
- Pattern: '{"name": "value"}'
40+
41+
KinesisStream:
42+
Type: AWS::Kinesis::Stream
43+
Properties:
44+
ShardCount: 1
45+
46+
DynamoDBTable:
47+
Type: AWS::DynamoDB::Table
48+
Properties:
49+
AttributeDefinitions:
50+
- AttributeName: id
51+
AttributeType: S
52+
BillingMode: PAY_PER_REQUEST
53+
KeySchema:
54+
- AttributeName: id
55+
KeyType: HASH
56+
57+
MySqsQueue:
58+
Type: AWS::SQS::Queue
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
{
2+
"Resources": {
3+
"DynamoDBTable": {
4+
"Properties": {
5+
"AttributeDefinitions": [
6+
{
7+
"AttributeName": "id",
8+
"AttributeType": "S"
9+
}
10+
],
11+
"BillingMode": "PAY_PER_REQUEST",
12+
"KeySchema": [
13+
{
14+
"AttributeName": "id",
15+
"KeyType": "HASH"
16+
}
17+
]
18+
},
19+
"Type": "AWS::DynamoDB::Table"
20+
},
21+
"FilteredEventsFunction": {
22+
"Properties": {
23+
"Code": {
24+
"S3Bucket": "sam-demo-bucket",
25+
"S3Key": "metricsConfig.zip"
26+
},
27+
"Handler": "index.handler",
28+
"Role": {
29+
"Fn::GetAtt": [
30+
"FilteredEventsFunctionRole",
31+
"Arn"
32+
]
33+
},
34+
"Runtime": "nodejs16.x",
35+
"Tags": [
36+
{
37+
"Key": "lambda:createdBy",
38+
"Value": "SAM"
39+
}
40+
]
41+
},
42+
"Type": "AWS::Lambda::Function"
43+
},
44+
"FilteredEventsFunctionDynamoDBStreamEvent": {
45+
"Properties": {
46+
"EventSourceArn": {
47+
"Fn::GetAtt": [
48+
"DynamoDBTable",
49+
"StreamArn"
50+
]
51+
},
52+
"FilterCriteria": {
53+
"Filters": []
54+
},
55+
"FunctionName": {
56+
"Ref": "FilteredEventsFunction"
57+
},
58+
"MetricsConfig": {
59+
"Metrics": []
60+
},
61+
"StartingPosition": "TRIM_HORIZON"
62+
},
63+
"Type": "AWS::Lambda::EventSourceMapping"
64+
},
65+
"FilteredEventsFunctionKinesisStream": {
66+
"Properties": {
67+
"EventSourceArn": {
68+
"Fn::GetAtt": [
69+
"KinesisStream",
70+
"Arn"
71+
]
72+
},
73+
"FilterCriteria": {
74+
"Filters": [
75+
{
76+
"Pattern": "{\"name\": \"value\"}"
77+
},
78+
{
79+
"Pattern": "{\"name2\": \"value2\"}"
80+
}
81+
]
82+
},
83+
"FunctionName": {
84+
"Ref": "FilteredEventsFunction"
85+
},
86+
"MetricsConfig": {
87+
"Metrics": [
88+
"EventCount"
89+
]
90+
},
91+
"StartingPosition": "LATEST"
92+
},
93+
"Type": "AWS::Lambda::EventSourceMapping"
94+
},
95+
"FilteredEventsFunctionMySqsQueue": {
96+
"Properties": {
97+
"EventSourceArn": {
98+
"Fn::GetAtt": [
99+
"MySqsQueue",
100+
"Arn"
101+
]
102+
},
103+
"FilterCriteria": {
104+
"Filters": [
105+
{
106+
"Pattern": "{\"name\": \"value\"}"
107+
}
108+
]
109+
},
110+
"FunctionName": {
111+
"Ref": "FilteredEventsFunction"
112+
},
113+
"MetricsConfig": {
114+
"Metrics": [
115+
"EventCount"
116+
]
117+
}
118+
},
119+
"Type": "AWS::Lambda::EventSourceMapping"
120+
},
121+
"FilteredEventsFunctionRole": {
122+
"Properties": {
123+
"AssumeRolePolicyDocument": {
124+
"Statement": [
125+
{
126+
"Action": [
127+
"sts:AssumeRole"
128+
],
129+
"Effect": "Allow",
130+
"Principal": {
131+
"Service": [
132+
"lambda.amazonaws.com"
133+
]
134+
}
135+
}
136+
],
137+
"Version": "2012-10-17"
138+
},
139+
"ManagedPolicyArns": [
140+
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
141+
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaDynamoDBExecutionRole",
142+
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole",
143+
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole"
144+
],
145+
"Tags": [
146+
{
147+
"Key": "lambda:createdBy",
148+
"Value": "SAM"
149+
}
150+
]
151+
},
152+
"Type": "AWS::IAM::Role"
153+
},
154+
"KinesisStream": {
155+
"Properties": {
156+
"ShardCount": 1
157+
},
158+
"Type": "AWS::Kinesis::Stream"
159+
},
160+
"MySqsQueue": {
161+
"Type": "AWS::SQS::Queue"
162+
}
163+
}
164+
}

0 commit comments

Comments
 (0)