Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tools-lambda-function-construct/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.venv
__pycache__
10 changes: 10 additions & 0 deletions tools-lambda-function-construct/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div align="center">

<h1>Explore <a href="https://serverlessland.com">ServerlessLand</a></h1>


![ServerlessLand.com](../serverlessland.png)
[Explore 700+ patterns](https://serverlessland.com/patterns?ref=github-snippets) | [Explore 50+ guides](https://serverlessland.com/learn?ref=github-snippets) | [Explore 80+ guides](https://serverlessland.com/snippets?ref=github-snippets)

</div>

14 changes: 14 additions & 0 deletions tools-lambda-function-construct/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python3

import aws_cdk as cdk

from cdk.cdk_stack import StandardLambdaExample


app = cdk.App()
StandardLambdaExample(
app,
"StandardLambdaExample",
)

app.synth()
101 changes: 101 additions & 0 deletions tools-lambda-function-construct/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"app": "python3 app.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/__init__.py",
"**/__pycache__",
"tests"
]
},
"context": {
"@aws-cdk/aws-signer:signingProfileNamePassedToCfn": true,
"@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": true,
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
"@aws-cdk/aws-redshift:columnId": true,
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
"@aws-cdk/aws-kms:aliasNameRef": true,
"@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": true,
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
"@aws-cdk/core:explicitStackTags": true,
"@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
"@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true,
"@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true,
"@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true,
"@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true,
"@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true,
"@aws-cdk/core:enableAdditionalMetadataCollection": true,
"@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": false,
"@aws-cdk/aws-s3:setUniqueReplicationRoleName": true,
"@aws-cdk/aws-events:requireEventBusPolicySid": true,
"@aws-cdk/core:aspectPrioritiesMutating": true,
"@aws-cdk/aws-dynamodb:retainTableReplica": true,
"@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": true,
"@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": true,
"@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": true,
"@aws-cdk/aws-s3:publicAccessBlockedByDefault": true,
"@aws-cdk/aws-lambda:useCdkManagedLogGroup": true,
"@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault": true,
"@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": true
}
}
109 changes: 109 additions & 0 deletions tools-lambda-function-construct/cdk/cdk_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from aws_cdk import (
aws_iam as iam,
aws_lambda as lambda_,
Duration,
Stack,
)
from constructs import Construct
from cdk.constructs.standard_lambda_construct import StandardLambda


class StandardLambdaExample(Stack):
"""
Example CDK stack demonstrating three usage patterns of the StandardLambda
construct: a minimal function, a function with overridden defaults, and a
function with external dependencies and additional layers/permissions.
"""

def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

stack = Stack.of(self)

# Resolve the deployment region — used below to build region-specific
# layer ARNs (e.g. Lambda Insights)
region = stack.region

# ---------------------------------------------------------------
# Example 1: Minimal Lambda — no external dependencies
# ---------------------------------------------------------------
# Demonstrates the simplest usage of the StandardLambda construct.
# The "lambda/simple" directory contains only the handler code and
# empty requirements.txt, so CDK packages the code as a plain asset
# without spinning up a Container.
#
# All defaults from the construct are inherited:
# - Python 3.14 runtime on ARM_64
# - 256 MB memory, 30s timeout
# - Powertools layer + environment variables
# - Dedicated CloudWatch Log Group with 1-week retention
# - X-Ray active tracing
simple_lambda = StandardLambda(
self,
"SimpleLambda",
handler="index.handler",
code_path="lambda/simple",
)

# ---------------------------------------------------------------
# Example 2: Overriding defaults — custom runtime and env vars
# ---------------------------------------------------------------
# Demonstrates how to override construct defaults on a per-function
# basis. Here we pin the runtime to Python 3.13 and add a custom
# environment variable.
override_lambda = StandardLambda(
self,
"OverrideLambda",
handler="index.handler",
code_path="lambda/simple",
runtime=lambda_.Runtime.PYTHON_3_13,
environment={
"CUSTOM_VAR": "custom_value",
# POWERTOOLS_SERVICE_NAME and LOG_LEVEL are still included
# automatically via the construct's merge logic
},
)

# ---------------------------------------------------------------
# Example 3: Lambda with dependencies, extra layers, and permissions
# ---------------------------------------------------------------
# Demonstrates a more complex function that:
# 1. Has external pip dependencies (requirements.txt exists in
# "lambda/dependency"), so Container bundling kicks in automatically.
# 2. Uses X86_64 architecture instead of the default ARM_64 — the
# construct automatically selects the matching Powertools layer ARN.
# 3. Adds an additional Lambda layer (CloudWatch Lambda Insights)
# on top of the default Powertools layer — layers are merged,
# not replaced.
# 4. Overrides timeout (60s) and memory (512 MB) for a heavier
# workload.
# 5. Attaches an additional IAM managed policy to the function's
# execution role via the exposed self.role attribute.

# Look up the AWS-managed Lambda Insights extension layer for X86_64.
# This provides enhanced monitoring metrics in CloudWatch.
lambda_insights_layer = lambda_.LayerVersion.from_layer_version_arn(
self,
"LambdaInsightsLayer",
f"arn:aws:lambda:{region}:580247275435:layer:LambdaInsightsExtension:31",
)

dependency_lambda = StandardLambda(
self,
"DependencyLambda",
handler="index.handler",
code_path="lambda/dependency",
architecture=lambda_.Architecture.X86_64,
timeout=Duration.seconds(60),
layers=[lambda_insights_layer],
memory_size=512,
)

# Grant the Lambda Insights managed policy to the function's role.
# This is needed for the Insights layer to publish enhanced metrics.
# Uses the exposed self.role attribute from the construct.
dependency_lambda.role.add_managed_policy(
iam.ManagedPolicy.from_aws_managed_policy_name(
"CloudWatchLambdaInsightsExecutionRolePolicy"
)
)
Loading