diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/aws-cdk-lambda-logging-config.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/aws-cdk-lambda-logging-config.assets.json new file mode 100644 index 0000000000000..cc242bdce487c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/aws-cdk-lambda-logging-config.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "c10a26dd32e7f7d2a9c057ec71b82b23ad867563a9b092f09ed73ef671035641": { + "source": { + "path": "aws-cdk-lambda-logging-config.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "c10a26dd32e7f7d2a9c057ec71b82b23ad867563a9b092f09ed73ef671035641.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/aws-cdk-lambda-logging-config.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/aws-cdk-lambda-logging-config.template.json new file mode 100644 index 0000000000000..e121f281cd843 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/aws-cdk-lambda-logging-config.template.json @@ -0,0 +1,326 @@ +{ + "Resources": { + "MyLogGroupWithLogGroupNameB577EB65": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "LogGroupName": "customLogGroup", + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "LambdaWithLogGroupServiceRoleC5DDB031": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaWithLogGroupC3B62A1A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "LoggingConfig": { + "LogGroup": { + "Ref": "MyLogGroupWithLogGroupNameB577EB65" + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaWithLogGroupServiceRoleC5DDB031", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "LambdaWithLogGroupServiceRoleC5DDB031" + ] + }, + "MyLogGroupWithoutLogGroupName385E46B7": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "LambdaWithLogGroupAndNoLogGroupNameServiceRoleFEE6AF87": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaWithLogGroupAndNoLogGroupName1F5C7375": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "LoggingConfig": { + "LogGroup": { + "Ref": "MyLogGroupWithoutLogGroupName385E46B7" + } + }, + "Role": { + "Fn::GetAtt": [ + "LambdaWithLogGroupAndNoLogGroupNameServiceRoleFEE6AF87", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "LambdaWithLogGroupAndNoLogGroupNameServiceRoleFEE6AF87" + ] + }, + "LambdaWithTextFormatServiceRoleABCC0E93": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaWithTextFormatA0EDE227": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "LoggingConfig": { + "LogFormat": "Text" + }, + "Role": { + "Fn::GetAtt": [ + "LambdaWithTextFormatServiceRoleABCC0E93", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "LambdaWithTextFormatServiceRoleABCC0E93" + ] + }, + "LambdaWithJSONFormatServiceRole37FFB486": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaWithJSONFormat20E01C00": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "LoggingConfig": { + "LogFormat": "JSON" + }, + "Role": { + "Fn::GetAtt": [ + "LambdaWithJSONFormatServiceRole37FFB486", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "LambdaWithJSONFormatServiceRole37FFB486" + ] + }, + "LambdaWithLogLevelServiceRole90A45743": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LambdaWithLogLevelCBBBEFFC": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Handler": "index.handler", + "LoggingConfig": { + "ApplicationLogLevel": "INFO", + "LogFormat": "JSON", + "SystemLogLevel": "INFO" + }, + "Role": { + "Fn::GetAtt": [ + "LambdaWithLogLevelServiceRole90A45743", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "LambdaWithLogLevelServiceRole90A45743" + ] + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/integ.json new file mode 100644 index 0000000000000..e5feef0abe915 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "lambda-logging-config/DefaultTest": { + "stacks": [ + "aws-cdk-lambda-logging-config" + ], + "assertionStack": "lambda-logging-config/DefaultTest/DeployAssert", + "assertionStackName": "lambdaloggingconfigDefaultTestDeployAssert24012B25" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/lambdaloggingconfigDefaultTestDeployAssert24012B25.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/lambdaloggingconfigDefaultTestDeployAssert24012B25.assets.json new file mode 100644 index 0000000000000..a8e852ceaf06f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/lambdaloggingconfigDefaultTestDeployAssert24012B25.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "lambdaloggingconfigDefaultTestDeployAssert24012B25.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/lambdaloggingconfigDefaultTestDeployAssert24012B25.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/lambdaloggingconfigDefaultTestDeployAssert24012B25.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/lambdaloggingconfigDefaultTestDeployAssert24012B25.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/manifest.json new file mode 100644 index 0000000000000..8feb2b46a85b2 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/manifest.json @@ -0,0 +1,179 @@ +{ + "version": "34.0.0", + "artifacts": { + "aws-cdk-lambda-logging-config.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-lambda-logging-config.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-lambda-logging-config": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-lambda-logging-config.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c10a26dd32e7f7d2a9c057ec71b82b23ad867563a9b092f09ed73ef671035641.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-lambda-logging-config.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-lambda-logging-config.assets" + ], + "metadata": { + "/aws-cdk-lambda-logging-config/MyLogGroupWithLogGroupName/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLogGroupWithLogGroupNameB577EB65" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithLogGroup/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithLogGroupServiceRoleC5DDB031" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithLogGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithLogGroupC3B62A1A" + } + ], + "/aws-cdk-lambda-logging-config/MyLogGroupWithoutLogGroupName/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyLogGroupWithoutLogGroupName385E46B7" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithLogGroupAndNoLogGroupNameServiceRoleFEE6AF87" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithLogGroupAndNoLogGroupName1F5C7375" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithTextFormat/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithTextFormatServiceRoleABCC0E93" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithTextFormat/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithTextFormatA0EDE227" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithJSONFormat/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithJSONFormatServiceRole37FFB486" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithJSONFormat/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithJSONFormat20E01C00" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithLogLevel/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithLogLevelServiceRole90A45743" + } + ], + "/aws-cdk-lambda-logging-config/LambdaWithLogLevel/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaWithLogLevelCBBBEFFC" + } + ], + "/aws-cdk-lambda-logging-config/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-lambda-logging-config/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-lambda-logging-config" + }, + "lambdaloggingconfigDefaultTestDeployAssert24012B25.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "lambdaloggingconfigDefaultTestDeployAssert24012B25.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "lambdaloggingconfigDefaultTestDeployAssert24012B25": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "lambdaloggingconfigDefaultTestDeployAssert24012B25.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "lambdaloggingconfigDefaultTestDeployAssert24012B25.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "lambdaloggingconfigDefaultTestDeployAssert24012B25.assets" + ], + "metadata": { + "/lambda-logging-config/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/lambda-logging-config/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "lambda-logging-config/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/tree.json new file mode 100644 index 0000000000000..3807537378927 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.js.snapshot/tree.json @@ -0,0 +1,626 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-lambda-logging-config": { + "id": "aws-cdk-lambda-logging-config", + "path": "aws-cdk-lambda-logging-config", + "children": { + "MyLogGroupWithLogGroupName": { + "id": "MyLogGroupWithLogGroupName", + "path": "aws-cdk-lambda-logging-config/MyLogGroupWithLogGroupName", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/MyLogGroupWithLogGroupName/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Logs::LogGroup", + "aws:cdk:cloudformation:props": { + "logGroupName": "customLogGroup", + "retentionInDays": 731 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.CfnLogGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.LogGroup", + "version": "0.0.0" + } + }, + "LambdaWithLogGroup": { + "id": "LambdaWithLogGroup", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroup", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroup/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroup/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroup/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "handler": "index.handler", + "loggingConfig": { + "logGroup": { + "Ref": "MyLogGroupWithLogGroupNameB577EB65" + } + }, + "role": { + "Fn::GetAtt": [ + "LambdaWithLogGroupServiceRoleC5DDB031", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "MyLogGroupWithoutLogGroupName": { + "id": "MyLogGroupWithoutLogGroupName", + "path": "aws-cdk-lambda-logging-config/MyLogGroupWithoutLogGroupName", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/MyLogGroupWithoutLogGroupName/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Logs::LogGroup", + "aws:cdk:cloudformation:props": { + "retentionInDays": 731 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.CfnLogGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.LogGroup", + "version": "0.0.0" + } + }, + "LambdaWithLogGroupAndNoLogGroupName": { + "id": "LambdaWithLogGroupAndNoLogGroupName", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogGroupAndNoLogGroupName/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "handler": "index.handler", + "loggingConfig": { + "logGroup": { + "Ref": "MyLogGroupWithoutLogGroupName385E46B7" + } + }, + "role": { + "Fn::GetAtt": [ + "LambdaWithLogGroupAndNoLogGroupNameServiceRoleFEE6AF87", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "LambdaWithTextFormat": { + "id": "LambdaWithTextFormat", + "path": "aws-cdk-lambda-logging-config/LambdaWithTextFormat", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithTextFormat/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithTextFormat/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithTextFormat/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithTextFormat/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "handler": "index.handler", + "loggingConfig": { + "logFormat": "Text" + }, + "role": { + "Fn::GetAtt": [ + "LambdaWithTextFormatServiceRoleABCC0E93", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "LambdaWithJSONFormat": { + "id": "LambdaWithJSONFormat", + "path": "aws-cdk-lambda-logging-config/LambdaWithJSONFormat", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithJSONFormat/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithJSONFormat/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithJSONFormat/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithJSONFormat/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "handler": "index.handler", + "loggingConfig": { + "logFormat": "JSON" + }, + "role": { + "Fn::GetAtt": [ + "LambdaWithJSONFormatServiceRole37FFB486", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "LambdaWithLogLevel": { + "id": "LambdaWithLogLevel", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogLevel", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogLevel/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogLevel/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogLevel/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-lambda-logging-config/LambdaWithLogLevel/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "handler": "index.handler", + "loggingConfig": { + "logFormat": "JSON", + "systemLogLevel": "INFO", + "applicationLogLevel": "INFO" + }, + "role": { + "Fn::GetAtt": [ + "LambdaWithLogLevelServiceRole90A45743", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-lambda-logging-config/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-lambda-logging-config/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "lambda-logging-config": { + "id": "lambda-logging-config", + "path": "lambda-logging-config", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "lambda-logging-config/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "lambda-logging-config/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "lambda-logging-config/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "lambda-logging-config/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "lambda-logging-config/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.2.70" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.ts new file mode 100644 index 0000000000000..7029acfe3a94c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.logging-config.ts @@ -0,0 +1,55 @@ +import { App, Stack } from 'aws-cdk-lib'; +import * as logs from 'aws-cdk-lib/aws-logs'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import { Function, InlineCode, Runtime, LogFormat, SystemLogLevel, ApplicationLogLevel } from 'aws-cdk-lib/aws-lambda'; + +const app = new App(); + +const stack = new Stack(app, 'aws-cdk-lambda-logging-config'); + +const logGroup = new logs.LogGroup(stack, 'MyLogGroupWithLogGroupName', { + logGroupName: 'customLogGroup', +}); + +new Function(stack, 'LambdaWithLogGroup', { + code: new InlineCode('foo'), + handler: 'index.handler', + runtime: Runtime.NODEJS_18_X, + logGroup: logGroup, +}); + +new Function(stack, 'LambdaWithLogGroupAndNoLogGroupName', { + code: new InlineCode('foo'), + handler: 'index.handler', + runtime: Runtime.NODEJS_18_X, + logGroup: new logs.LogGroup(stack, 'MyLogGroupWithoutLogGroupName'), +}); + +new Function(stack, 'LambdaWithTextFormat', { + code: new InlineCode('foo'), + handler: 'index.handler', + runtime: Runtime.NODEJS_18_X, + logFormat: LogFormat.TEXT, +}); + +new Function(stack, 'LambdaWithJSONFormat', { + code: new InlineCode('foo'), + handler: 'index.handler', + runtime: Runtime.NODEJS_18_X, + logFormat: LogFormat.JSON, +}); + +new Function(stack, 'LambdaWithLogLevel', { + code: new InlineCode('foo'), + handler: 'index.handler', + runtime: Runtime.NODEJS_18_X, + logFormat: LogFormat.JSON, + systemLogLevel: SystemLogLevel.INFO, + applicationLogLevel: ApplicationLogLevel.INFO, +}); + +new integ.IntegTest(app, 'lambda-logging-config', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-lambda/README.md b/packages/aws-cdk-lib/aws-lambda/README.md index 1f18942c2128e..bf78d75090b26 100644 --- a/packages/aws-cdk-lib/aws-lambda/README.md +++ b/packages/aws-cdk-lib/aws-lambda/README.md @@ -151,6 +151,28 @@ if (fn.timeout) { } ``` +## Advanced Logging + +You can have more control over your function logs, by specifying the log format +(Json or plain text), the system log level, the application log level, as well +as choosing the log group: + +```ts +import { ILogGroup } from 'aws-cdk-lib/aws-logs'; + +declare const logGroup: ILogGroup; + +new lambda.Function(this, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logFormat: lambda.LogFormat.JSON, + systemLogLevel: lambda.SystemLogLevel.INFO, + applicationLogLevel: lambda.ApplicationLogLevel.INFO, + logGroup: logGroup, +}); +``` + ## Resource-based Policies AWS Lambda supports resource-based policies for controlling access to Lambda diff --git a/packages/aws-cdk-lib/aws-lambda/lib/function.ts b/packages/aws-cdk-lib/aws-lambda/lib/function.ts index 49474a936b89c..5c64c7069f65e 100644 --- a/packages/aws-cdk-lib/aws-lambda/lib/function.ts +++ b/packages/aws-cdk-lib/aws-lambda/lib/function.ts @@ -51,6 +51,76 @@ export enum Tracing { DISABLED = 'Disabled' } +/** + * Lambda service will automatically captures system logs about function invocation + * generated by the Lambda service (known as system logs) and sends these logs to a + * default CloudWatch log group named after the Lambda function. + */ +export enum SystemLogLevel { + /** + * Lambda will capture only logs at info level. + */ + INFO = 'INFO', + /** + * Lambda will capture only logs at debug level. + */ + DEBUG = 'DEBUG', + /** + * Lambda will capture only logs at warn level. + */ + WARN = 'WARN' +} + +/** + * Lambda service automatically captures logs generated by the function code + * (known as application logs) and sends these logs to a default CloudWatch + * log group named after the Lambda function. + */ +export enum ApplicationLogLevel { + /** + * Lambda will capture only logs at info level. + */ + INFO = 'INFO', + /** + * Lambda will capture only logs at debug level. + */ + DEBUG = 'DEBUG', + /** + * Lambda will capture only logs at warn level. + */ + WARN = 'WARN', + /** + * Lambda will capture only logs at trace level. + */ + TRACE = 'TRACE', + /** + * Lambda will capture only logs at error level. + */ + ERROR = 'ERROR', + /** + * Lambda will capture only logs at fatal level. + */ + FATAL = 'FATAL' +} + +/** + * This field takes in 2 values either Text or JSON. By setting this value to Text, + * will result in the current structure of logs format, whereas, by setting this value to JSON, + * Lambda will print the logs as Structured JSON Logs, with the corresponding timestamp and log level + * of each event. Selecting ‘JSON’ format will only allow customer’s to have different log level + * Application log level and the System log level. + */ +export enum LogFormat { + /** + * Lambda Logs text format. + */ + TEXT = 'Text', + /** + * Lambda structured logging in Json format. + */ + JSON = 'JSON' +} + /** * Non runtime options */ @@ -385,6 +455,30 @@ export interface FunctionOptions extends EventInvokeConfigOptions { * @default Auto */ readonly runtimeManagementMode?: RuntimeManagementMode; + + /** + * Sets the log group name for the function. + * @default `/aws/lambda/${this.functionName}` default log group name created by Lambda + */ + readonly logGroup?: logs.ILogGroup; + + /** + * Sets the logFormat for the function. + * @default Text format + */ + readonly logFormat?: string; + + /** + * Sets the application log level for the function. + * @default INFO + */ + readonly applicationLogLevel?: string; + + /** + * Sets the system log level for the function. + * @default INFO + */ + readonly systemLogLevel?: string; } export interface FunctionProps extends FunctionOptions { @@ -842,12 +936,15 @@ export class Function extends FunctionBase { architectures: this._architecture ? [this._architecture.name] : undefined, runtimeManagementConfig: props.runtimeManagementMode?.runtimeManagementConfig, snapStart: this.configureSnapStart(props), + loggingConfig: this.getLoggingConfig(props), }); if ((props.tracing !== undefined) || (props.adotInstrumentation !== undefined)) { resource.tracingConfig = this.buildTracingConfig(props.tracing ?? Tracing.ACTIVE); } + this._logGroup = props.logGroup; + resource.node.addDependency(this.role); this.functionName = this.getResourceNameAttribute(resource.ref); @@ -877,6 +974,9 @@ export class Function extends FunctionBase { // Log retention if (props.logRetention) { + if (props.logGroup) { + throw new Error('CDK does not support setting logRetention and logGroup'); + } const logRetention = new logs.LogRetention(this, 'LogRetention', { logGroupName: `/aws/lambda/${this.functionName}`, retention: props.logRetention, @@ -971,6 +1071,25 @@ export class Function extends FunctionBase { return this; } + /** + * Get Logging Config propety for the function. + * This method returns the function LoggingConfig Property if the property is set on the + * function and undefined if not. + */ + private getLoggingConfig(props: FunctionProps): CfnFunction.LoggingConfigProperty | undefined { + let loggingConfig: CfnFunction.LoggingConfigProperty; + if (props.logFormat || props.logGroup) { + loggingConfig = { + logFormat: props.logFormat, + systemLogLevel: props.systemLogLevel, + applicationLogLevel: props.applicationLogLevel, + logGroup: props.logGroup?.logGroupName, + }; + return loggingConfig; + } + return undefined; + }; + /** * Mix additional information into the hash of the Version object * @@ -1317,7 +1436,7 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett // See https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html Annotations.of(this).addWarningV2('@aws-cdk/aws-lambda:snapStartRequirePublish', 'SnapStart only support published Lambda versions. Ignore if function already have published versions'); - if (!props.runtime.supportsSnapStart ) { + if (!props.runtime.supportsSnapStart) { throw new Error(`SnapStart currently not supported by runtime ${props.runtime.name}`); } @@ -1466,7 +1585,7 @@ export function verifyCodeConfig(code: CodeConfig, props: FunctionProps) { } } -function undefinedIfNoKeys(struct: A): A | undefined { +function undefinedIfNoKeys(struct: A): A | undefined { const allUndefined = Object.values(struct).every(val => val === undefined); return allUndefined ? undefined : struct; } @@ -1479,7 +1598,7 @@ function undefinedIfNoKeys(struct: A): A | * which "validates" the new function hash. */ export class FunctionVersionUpgrade implements IAspect { - constructor(private readonly featureFlag: string, private readonly enabled=true) {} + constructor(private readonly featureFlag: string, private readonly enabled = true) { } public visit(node: IConstruct): void { if (node instanceof Function && diff --git a/packages/aws-cdk-lib/aws-lambda/test/logging-config.test.ts b/packages/aws-cdk-lib/aws-lambda/test/logging-config.test.ts new file mode 100644 index 0000000000000..ad4c5dd2b956b --- /dev/null +++ b/packages/aws-cdk-lib/aws-lambda/test/logging-config.test.ts @@ -0,0 +1,138 @@ +import { Template } from '../../assertions'; +import * as logs from '../../aws-logs'; +import * as cdk from '../../core'; +import * as lambda from '../lib'; + +describe('logging Config', () => { + test('Logging Config with LogGroup and no LogGroupName', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); + new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logGroup: logGroup, + }); + // WHEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + LoggingConfig: { + LogGroup: { + Ref: 'MyLogGroup5C0DAD85', + }, + }, + }); + }); + test('Logging Config with LogGroup', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: 'customLogGroup', + }); + new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logGroup: logGroup, + }); + // WHEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + LoggingConfig: { + LogGroup: { + Ref: 'MyLogGroup5C0DAD85', + }, + }, + }); + }); + test('Logging Config TEXT logFormat', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logFormat: lambda.LogFormat.TEXT, + }); + // WHEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + LoggingConfig: { + LogFormat: 'Text', + }, + }); + }); + test('Logging Config JSON logFormat', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logFormat: lambda.LogFormat.JSON, + }); + // WHEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + LoggingConfig: { + LogFormat: 'JSON', + }, + }); + }); + test('Logging Config with LogLevel set', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logFormat: lambda.LogFormat.JSON, + systemLogLevel: lambda.SystemLogLevel.INFO, + applicationLogLevel: lambda.ApplicationLogLevel.INFO, + }); + // WHEN + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { + LoggingConfig: { + LogFormat: 'JSON', + SystemLogLevel: 'INFO', + ApplicationLogLevel: 'INFO', + }, + }); + }); + + test('Get function custom logGroup', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: 'customLogGroup', + }); + const lambdaFunction = new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logGroup: logGroup, + }); + expect(lambdaFunction.logGroup).toEqual(logGroup); + expect(lambdaFunction.logGroup.logGroupName).toEqual(logGroup.logGroupName); + expect(lambdaFunction.logGroup.logGroupPhysicalName()).toEqual(logGroup.logGroupPhysicalName()); + }); + + test('Throws when logGroup and LogRention are set', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'stack'); + expect(() => { + new lambda.Function(stack, 'Lambda', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_18_X, + logRetention: logs.RetentionDays.INFINITE, + logGroup: new logs.LogGroup(stack, 'MyLogGroup', { + logGroupName: 'customLogGroup', + }), + }); + }).toThrowError('CDK does not support setting logRetention and logGroup'); + }); +}); diff --git a/tools/@aws-cdk/spec2cdk/temporary-schemas/us-east-1/aws-lambda-function.json b/tools/@aws-cdk/spec2cdk/temporary-schemas/us-east-1/aws-lambda-function.json new file mode 100644 index 0000000000000..3ea4aac85560f --- /dev/null +++ b/tools/@aws-cdk/spec2cdk/temporary-schemas/us-east-1/aws-lambda-function.json @@ -0,0 +1,546 @@ +{ + "tagging": { + "taggable": true, + "tagOnCreate": true, + "tagUpdatable": true, + "tagProperty": "/properties/Tags", + "cloudFormationSystemTags": true + }, + "handlers": { + "read": { + "permissions": [ + "lambda:GetFunction", + "lambda:GetFunctionCodeSigningConfig" + ] + }, + "create": { + "permissions": [ + "lambda:CreateFunction", + "lambda:GetFunction", + "lambda:PutFunctionConcurrency", + "iam:PassRole", + "s3:GetObject", + "s3:GetObjectVersion", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeVpcs", + "elasticfilesystem:DescribeMountTargets", + "kms:CreateGrant", + "kms:Decrypt", + "kms:Encrypt", + "kms:GenerateDataKey", + "lambda:GetCodeSigningConfig", + "lambda:GetFunctionCodeSigningConfig", + "lambda:GetLayerVersion", + "lambda:GetRuntimeManagementConfig", + "lambda:PutRuntimeManagementConfig", + "lambda:TagResource", + "lambda:GetPolicy", + "lambda:AddPermission", + "lambda:RemovePermission", + "lambda:GetResourcePolicy", + "lambda:PutResourcePolicy" + ] + }, + "update": { + "permissions": [ + "lambda:DeleteFunctionConcurrency", + "lambda:GetFunction", + "lambda:PutFunctionConcurrency", + "lambda:ListTags", + "lambda:TagResource", + "lambda:UntagResource", + "lambda:UpdateFunctionConfiguration", + "lambda:UpdateFunctionCode", + "iam:PassRole", + "s3:GetObject", + "s3:GetObjectVersion", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeVpcs", + "elasticfilesystem:DescribeMountTargets", + "kms:CreateGrant", + "kms:Decrypt", + "kms:GenerateDataKey", + "lambda:GetRuntimeManagementConfig", + "lambda:PutRuntimeManagementConfig", + "lambda:PutFunctionCodeSigningConfig", + "lambda:DeleteFunctionCodeSigningConfig", + "lambda:GetCodeSigningConfig", + "lambda:GetFunctionCodeSigningConfig", + "lambda:GetPolicy", + "lambda:AddPermission", + "lambda:RemovePermission", + "lambda:GetResourcePolicy", + "lambda:PutResourcePolicy", + "lambda:DeleteResourcePolicy" + ] + }, + "list": { + "permissions": [ + "lambda:ListFunctions" + ] + }, + "delete": { + "permissions": [ + "lambda:DeleteFunction", + "ec2:DescribeNetworkInterfaces" + ] + } + }, + "typeName": "AWS::Lambda::Function", + "readOnlyProperties": [ + "/properties/SnapStartResponse", + "/properties/SnapStartResponse/ApplyOn", + "/properties/SnapStartResponse/OptimizationStatus", + "/properties/Arn" + ], + "description": "Resource Type definition for AWS::Lambda::Function in region", + "writeOnlyProperties": [ + "/properties/SnapStart", + "/properties/SnapStart/ApplyOn", + "/properties/Code", + "/properties/Code/ImageUri", + "/properties/Code/S3Bucket", + "/properties/Code/S3Key", + "/properties/Code/S3ObjectVersion", + "/properties/Code/ZipFile", + "/properties/Policy" + ], + "createOnlyProperties": [ + "/properties/FunctionName" + ], + "additionalProperties": false, + "primaryIdentifier": [ + "/properties/FunctionName" + ], + "definitions": { + "ImageConfig": { + "additionalProperties": false, + "type": "object", + "properties": { + "WorkingDirectory": { + "description": "WorkingDirectory.", + "type": "string" + }, + "Command": { + "maxItems": 1500, + "uniqueItems": true, + "description": "Command.", + "type": "array", + "items": { + "type": "string" + } + }, + "EntryPoint": { + "maxItems": 1500, + "uniqueItems": true, + "description": "EntryPoint.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "TracingConfig": { + "description": "The function's AWS X-Ray tracing configuration. To sample and record incoming requests, set Mode to Active.", + "additionalProperties": false, + "type": "object", + "properties": { + "Mode": { + "description": "The tracing mode.", + "type": "string", + "enum": [ + "Active", + "PassThrough" + ] + } + } + }, + "VpcConfig": { + "description": "The VPC security groups and subnets that are attached to a Lambda function. When you connect a function to a VPC, Lambda creates an elastic network interface for each combination of security group and subnet in the function's VPC configuration. The function can only access resources and the internet through that VPC.", + "additionalProperties": false, + "type": "object", + "properties": { + "Ipv6AllowedForDualStack": { + "description": "A boolean indicating whether IPv6 protocols will be allowed for dual stack subnets", + "type": "boolean" + }, + "SecurityGroupIds": { + "maxItems": 5, + "uniqueItems": false, + "description": "A list of VPC security groups IDs.", + "type": "array", + "items": { + "type": "string" + } + }, + "SubnetIds": { + "maxItems": 16, + "uniqueItems": false, + "description": "A list of VPC subnet IDs.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "DeadLetterConfig": { + "description": "The dead-letter queue for failed asynchronous invocations.", + "additionalProperties": false, + "type": "object", + "properties": { + "TargetArn": { + "pattern": "^(arn:(aws[a-zA-Z-]*)?:[a-z0-9-.]+:.*)|()$", + "description": "The Amazon Resource Name (ARN) of an Amazon SQS queue or Amazon SNS topic.", + "type": "string" + } + } + }, + "RuntimeManagementConfig": { + "additionalProperties": false, + "type": "object", + "properties": { + "UpdateRuntimeOn": { + "description": "Trigger for runtime update", + "type": "string", + "enum": [ + "Auto", + "FunctionUpdate", + "Manual" + ] + }, + "RuntimeVersionArn": { + "description": "Unique identifier for a runtime version arn", + "type": "string" + } + }, + "required": [ + "UpdateRuntimeOn" + ] + }, + "SnapStart": { + "description": "The function's SnapStart setting. When set to PublishedVersions, Lambda creates a snapshot of the execution environment when you publish a function version.", + "additionalProperties": false, + "type": "object", + "properties": { + "ApplyOn": { + "description": "Applying SnapStart setting on function resource type.", + "type": "string", + "enum": [ + "PublishedVersions", + "None" + ] + } + }, + "required": [ + "ApplyOn" + ] + }, + "SnapStartResponse": { + "description": "The function's SnapStart Response. When set to PublishedVersions, Lambda creates a snapshot of the execution environment when you publish a function version.", + "additionalProperties": false, + "type": "object", + "properties": { + "OptimizationStatus": { + "description": "Indicates whether SnapStart is activated for the specified function version.", + "type": "string", + "enum": [ + "On", + "Off" + ] + }, + "ApplyOn": { + "description": "Applying SnapStart setting on function resource type.", + "type": "string", + "enum": [ + "PublishedVersions", + "None" + ] + } + } + }, + "Code": { + "additionalProperties": false, + "type": "object", + "properties": { + "S3ObjectVersion": { + "minLength": 1, + "description": "For versioned objects, the version of the deployment package object to use.", + "type": "string", + "maxLength": 1024 + }, + "S3Bucket": { + "minLength": 3, + "pattern": "^[0-9A-Za-z\\.\\-_]*(?