diff --git a/integration/combination/test_function_with_kinesis.py b/integration/combination/test_function_with_kinesis.py index 16f0adc5d..2e5af72aa 100644 --- a/integration/combination/test_function_with_kinesis.py +++ b/integration/combination/test_function_with_kinesis.py @@ -22,3 +22,26 @@ def test_function_with_kinesis_trigger(self): self.assertEqual(event_source_mapping_batch_size, 100) self.assertEqual(event_source_mapping_function_arn, lambda_function_arn) self.assertEqual(event_source_mapping_kinesis_stream_arn, kinesis_stream["StreamARN"]) + + +class TestFunctionWithKinesisIntrinsics(BaseTest): + def test_function_with_kinesis_trigger(self): + self.create_and_verify_stack("combination/function_with_kinesis_intrinsics") + + kinesis_client = self.client_provider.kinesis_client + kinesis_id = self.get_physical_id_by_type("AWS::Kinesis::Stream") + kinesis_stream = kinesis_client.describe_stream(StreamName=kinesis_id)["StreamDescription"] + + lambda_client = self.client_provider.lambda_client + function_name = self.get_physical_id_by_type("AWS::Lambda::Function") + lambda_function_arn = lambda_client.get_function_configuration(FunctionName=function_name)["FunctionArn"] + + event_source_mapping_arn = self.get_physical_id_by_type("AWS::Lambda::EventSourceMapping") + event_source_mapping_result = lambda_client.get_event_source_mapping(UUID=event_source_mapping_arn) + event_source_mapping_batch_size = event_source_mapping_result["BatchSize"] + event_source_mapping_function_arn = event_source_mapping_result["FunctionArn"] + event_source_mapping_kinesis_stream_arn = event_source_mapping_result["EventSourceArn"] + + self.assertEqual(event_source_mapping_batch_size, 100) + self.assertEqual(event_source_mapping_function_arn, lambda_function_arn) + self.assertEqual(event_source_mapping_kinesis_stream_arn, kinesis_stream["StreamARN"]) diff --git a/integration/resources/expected/combination/function_with_kinesis_intrinsics.json b/integration/resources/expected/combination/function_with_kinesis_intrinsics.json new file mode 100644 index 000000000..64511cfc4 --- /dev/null +++ b/integration/resources/expected/combination/function_with_kinesis_intrinsics.json @@ -0,0 +1,6 @@ +[ + { "LogicalResourceId":"MyLambdaFunction", "ResourceType":"AWS::Lambda::Function" }, + { "LogicalResourceId":"MyLambdaFunctionRole", "ResourceType":"AWS::IAM::Role" }, + { "LogicalResourceId":"MyStream", "ResourceType":"AWS::Kinesis::Stream" }, + { "LogicalResourceId":"MyLambdaFunctionKinesisStream", "ResourceType":"AWS::Lambda::EventSourceMapping" } +] \ No newline at end of file diff --git a/integration/resources/templates/combination/function_with_kinesis_intrinsics.yaml b/integration/resources/templates/combination/function_with_kinesis_intrinsics.yaml new file mode 100644 index 000000000..8dbd0b8b1 --- /dev/null +++ b/integration/resources/templates/combination/function_with_kinesis_intrinsics.yaml @@ -0,0 +1,82 @@ +Parameters: + IntValue: + Type: Number + Default: 100 + + One: + Type: Number + Default: 1 + + StartingPositionValue: + Type: String + Default: LATEST + + FunctionResponseTypesValue: + Type: String + Default: ReportBatchItemFailures + +Conditions: + TrueCondition: + Fn::Equals: + - true + - true + FalseCondition: + Fn::Equals: + - true + - false + +Resources: + MyLambdaFunction: + Type: AWS::Serverless::Function + Properties: + Handler: index.handler + Runtime: nodejs12.x + CodeUri: ${codeuri} + MemorySize: 128 + + Events: + KinesisStream: + Type: Kinesis + Properties: + BatchSize: + Ref: IntValue + BisectBatchOnFunctionError: + Fn::If: + - FalseCondition + - True + - False + Enabled: + Fn::If: + - TrueCondition + - True + - False + FunctionResponseTypes: + - Ref: FunctionResponseTypesValue + MaximumBatchingWindowInSeconds: + Ref: One + MaximumRecordAgeInSeconds: + Ref: IntValue + MaximumRetryAttempts: + Ref: One + ParallelizationFactor: + Ref: One + StartingPosition: + Ref: StartingPositionValue + Stream: + # Connect with the stream we have created in this template + Fn::Join: + - '' + - - 'arn:' + - Ref: AWS::Partition + - ':kinesis:' + - Ref: AWS::Region + - ':' + - Ref: AWS::AccountId + - ':stream/' + - Ref: MyStream + TumblingWindowInSeconds: + Ref: IntValue + MyStream: + Type: AWS::Kinesis::Stream + Properties: + ShardCount: 1 diff --git a/tests/translator/input/kinesis_intrinsics.yaml b/tests/translator/input/kinesis_intrinsics.yaml new file mode 100644 index 000000000..7107cb06a --- /dev/null +++ b/tests/translator/input/kinesis_intrinsics.yaml @@ -0,0 +1,82 @@ +Parameters: + IntValue: + Type: Number + Default: 50 + + StringValue: + Type: String + Default: us-east-1 + + StartingPositionValue: + Type: String + Default: LATEST + + FunctionResponseTypesValue: + Type: String + Default: ReportBatchItemFailures + +Conditions: + TrueCondition: + Fn::Equals: + - true + - true + FalseCondition: + Fn::Equals: + - true + - false + +Resources: + MyLambdaFunction: + Type: AWS::Serverless::Function + Properties: + Handler: index.handler + Runtime: nodejs12.x + CodeUri: s3://sam-demo-bucket/stream.zip + MemorySize: 128 + + Events: + KinesisStream: + Type: Kinesis + Properties: + BatchSize: + Ref: IntValue + BisectBatchOnFunctionError: + Fn::If: + - FalseCondition + - True + - False + Enabled: + Fn::If: + - TrueCondition + - True + - False + FunctionResponseTypes: + - Ref: FunctionResponseTypesValue + MaximumBatchingWindowInSeconds: + Ref: IntValue + MaximumRecordAgeInSeconds: + Ref: IntValue + MaximumRetryAttempts: + Ref: IntValue + ParallelizationFactor: + Ref: IntValue + StartingPosition: + Ref: StartingPositionValue + Stream: + # Connect with the stream we have created in this template + Fn::Join: + - '' + - - 'arn:' + - Ref: AWS::Partition + - ':kinesis:' + - Ref: AWS::Region + - ':' + - Ref: AWS::AccountId + - ':stream/' + - Ref: MyStream + TumblingWindowInSeconds: + Ref: IntValue + MyStream: + Type: AWS::Kinesis::Stream + Properties: + ShardCount: 1 diff --git a/tests/translator/output/aws-cn/kinesis_intrinsics.json b/tests/translator/output/aws-cn/kinesis_intrinsics.json new file mode 100644 index 000000000..0484d1fdc --- /dev/null +++ b/tests/translator/output/aws-cn/kinesis_intrinsics.json @@ -0,0 +1,168 @@ +{ + "Conditions": { + "TrueCondition": { + "Fn::Equals": [ + true, + true + ] + }, + "FalseCondition": { + "Fn::Equals": [ + true, + false + ] + } + }, + "Resources": { + "MyLambdaFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + }, + "ManagedPolicyArns": [ + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "arn:aws-cn:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole" + ], + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyLambdaFunctionKinesisStream": { + "Type": "AWS::Lambda::EventSourceMapping", + "Properties": { + "MaximumBatchingWindowInSeconds": { + "Ref": "IntValue" + }, + "FunctionName": { + "Ref": "MyLambdaFunction" + }, + "MaximumRecordAgeInSeconds": { + "Ref": "IntValue" + }, + "FunctionResponseTypes": [ + { + "Ref": "FunctionResponseTypesValue" + } + ], + "BatchSize": { + "Ref": "IntValue" + }, + "TumblingWindowInSeconds": { + "Ref": "IntValue" + }, + "Enabled": { + "Fn::If": [ + "TrueCondition", + true, + false + ] + }, + "EventSourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":kinesis:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stream/", + { + "Ref": "MyStream" + } + ] + ] + }, + "StartingPosition": { + "Ref": "StartingPositionValue" + }, + "ParallelizationFactor": { + "Ref": "IntValue" + }, + "MaximumRetryAttempts": { + "Ref": "IntValue" + }, + "BisectBatchOnFunctionError": { + "Fn::If": [ + "FalseCondition", + true, + false + ] + } + } + }, + "MyStream": { + "Type": "AWS::Kinesis::Stream", + "Properties": { + "ShardCount": 1 + } + }, + "MyLambdaFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "stream.zip" + }, + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "MemorySize": 128, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyLambdaFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs12.x" + } + } + }, + "Parameters": { + "StringValue": { + "Default": "us-east-1", + "Type": "String" + }, + "IntValue": { + "Default": 50, + "Type": "Number" + }, + "FunctionResponseTypesValue": { + "Default": "ReportBatchItemFailures", + "Type": "String" + }, + "StartingPositionValue": { + "Default": "LATEST", + "Type": "String" + } + } + } \ No newline at end of file diff --git a/tests/translator/output/aws-us-gov/kinesis_intrinsics.json b/tests/translator/output/aws-us-gov/kinesis_intrinsics.json new file mode 100644 index 000000000..a3490c279 --- /dev/null +++ b/tests/translator/output/aws-us-gov/kinesis_intrinsics.json @@ -0,0 +1,168 @@ +{ + "Conditions": { + "TrueCondition": { + "Fn::Equals": [ + true, + true + ] + }, + "FalseCondition": { + "Fn::Equals": [ + true, + false + ] + } + }, + "Resources": { + "MyLambdaFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + }, + "ManagedPolicyArns": [ + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "arn:aws-us-gov:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole" + ], + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyLambdaFunctionKinesisStream": { + "Type": "AWS::Lambda::EventSourceMapping", + "Properties": { + "MaximumBatchingWindowInSeconds": { + "Ref": "IntValue" + }, + "FunctionName": { + "Ref": "MyLambdaFunction" + }, + "MaximumRecordAgeInSeconds": { + "Ref": "IntValue" + }, + "FunctionResponseTypes": [ + { + "Ref": "FunctionResponseTypesValue" + } + ], + "BatchSize": { + "Ref": "IntValue" + }, + "TumblingWindowInSeconds": { + "Ref": "IntValue" + }, + "Enabled": { + "Fn::If": [ + "TrueCondition", + true, + false + ] + }, + "EventSourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":kinesis:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stream/", + { + "Ref": "MyStream" + } + ] + ] + }, + "StartingPosition": { + "Ref": "StartingPositionValue" + }, + "ParallelizationFactor": { + "Ref": "IntValue" + }, + "MaximumRetryAttempts": { + "Ref": "IntValue" + }, + "BisectBatchOnFunctionError": { + "Fn::If": [ + "FalseCondition", + true, + false + ] + } + } + }, + "MyStream": { + "Type": "AWS::Kinesis::Stream", + "Properties": { + "ShardCount": 1 + } + }, + "MyLambdaFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "stream.zip" + }, + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "MemorySize": 128, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyLambdaFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs12.x" + } + } + }, + "Parameters": { + "StringValue": { + "Default": "us-east-1", + "Type": "String" + }, + "IntValue": { + "Default": 50, + "Type": "Number" + }, + "FunctionResponseTypesValue": { + "Default": "ReportBatchItemFailures", + "Type": "String" + }, + "StartingPositionValue": { + "Default": "LATEST", + "Type": "String" + } + } + } \ No newline at end of file diff --git a/tests/translator/output/kinesis_intrinsics.json b/tests/translator/output/kinesis_intrinsics.json new file mode 100644 index 000000000..c7802de79 --- /dev/null +++ b/tests/translator/output/kinesis_intrinsics.json @@ -0,0 +1,168 @@ +{ + "Conditions": { + "TrueCondition": { + "Fn::Equals": [ + true, + true + ] + }, + "FalseCondition": { + "Fn::Equals": [ + true, + false + ] + } + }, + "Resources": { + "MyLambdaFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "sts:AssumeRole" + ], + "Effect": "Allow", + "Principal": { + "Service": [ + "lambda.amazonaws.com" + ] + } + } + ] + }, + "ManagedPolicyArns": [ + "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "arn:aws:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole" + ], + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ] + } + }, + "MyLambdaFunctionKinesisStream": { + "Type": "AWS::Lambda::EventSourceMapping", + "Properties": { + "MaximumBatchingWindowInSeconds": { + "Ref": "IntValue" + }, + "FunctionName": { + "Ref": "MyLambdaFunction" + }, + "MaximumRecordAgeInSeconds": { + "Ref": "IntValue" + }, + "FunctionResponseTypes": [ + { + "Ref": "FunctionResponseTypesValue" + } + ], + "BatchSize": { + "Ref": "IntValue" + }, + "TumblingWindowInSeconds": { + "Ref": "IntValue" + }, + "Enabled": { + "Fn::If": [ + "TrueCondition", + true, + false + ] + }, + "EventSourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":kinesis:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":stream/", + { + "Ref": "MyStream" + } + ] + ] + }, + "StartingPosition": { + "Ref": "StartingPositionValue" + }, + "ParallelizationFactor": { + "Ref": "IntValue" + }, + "MaximumRetryAttempts": { + "Ref": "IntValue" + }, + "BisectBatchOnFunctionError": { + "Fn::If": [ + "FalseCondition", + true, + false + ] + } + } + }, + "MyStream": { + "Type": "AWS::Kinesis::Stream", + "Properties": { + "ShardCount": 1 + } + }, + "MyLambdaFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "sam-demo-bucket", + "S3Key": "stream.zip" + }, + "Tags": [ + { + "Value": "SAM", + "Key": "lambda:createdBy" + } + ], + "MemorySize": 128, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "MyLambdaFunctionRole", + "Arn" + ] + }, + "Runtime": "nodejs12.x" + } + } + }, + "Parameters": { + "StringValue": { + "Default": "us-east-1", + "Type": "String" + }, + "IntValue": { + "Default": 50, + "Type": "Number" + }, + "FunctionResponseTypesValue": { + "Default": "ReportBatchItemFailures", + "Type": "String" + }, + "StartingPositionValue": { + "Default": "LATEST", + "Type": "String" + } + } + } \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index 0db19f45a..913bf81f3 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -341,6 +341,7 @@ class TestTranslatorEndToEnd(AbstractTestTranslator): "alexa_skill", "alexa_skill_with_skill_id", "iot_rule", + "kinesis_intrinsics", "layers_with_intrinsics", "layers_all_properties", "layer_deletion_policy_precedence",