Skip to main content

Overview

The Lambda Function resource provides serverless compute execution for running code in response to events without provisioning or managing servers. It includes automatic scaling, built-in high availability, and integration with AWS services through IAM roles and Function URLs. Lambda Function is ideal for:
  • Event-driven applications and microservices
  • API backends with Function URLs
  • Scheduled tasks and cron jobs
  • Stream and queue processing
  • Serverless web applications
Key features:
  • Automatic IAM role creation with CloudWatch Logs access
  • Function URLs for HTTP/HTTPS endpoints with CORS support
  • Seamless database integration via environment variables and secrets
  • Container image support via Amazon ECR
  • Custom inline IAM policies for AWS service access
  • Multi-runtime support (Node.js, Python, Java, Go, .NET, Ruby, Custom)

Resource Class

import { LambdaFunction } from "@fjall/components-infrastructure";

Basic Usage

import { LambdaFunction } from "@fjall/components-infrastructure";
import { Code, Runtime } from "aws-cdk-lib/aws-lambda";

const myFunction = new LambdaFunction(this, "MyFunction", {
  code: Code.fromAsset("./lambda"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  inlinePolicy: {}
});

Configuration Options

Core Properties

PropertyTypeRequiredDescriptionDefault
codeCodeYesLambda code source (asset, ECR, inline)-
handlerstringYesHandler function (e.g., “index.handler”)-
runtimeRuntimeYesAWS Lambda runtime version-
inlinePolicyRecord<string, PolicyDocument>YesIAM inline policies by name-

Execution Configuration

PropertyTypeDescriptionDefaultLimits
timeoutnumberExecution timeout in seconds3001-900 seconds
memorySizenumberMemory allocation in MB128128-10,240 MB
lambdaDescriptionstringFunction description--
roleDescriptionstringIAM role description--

Environment & Configuration

PropertyTypeDescriptionDefault
environmentRecord<string, string>Environment variables-
tagsRecord<string, string>Custom resource tags-

Function URL Properties

PropertyTypeDescriptionDefault
enableFunctionUrlbooleanEnable public HTTPS endpointfalse
functionUrlAuthTypeFunctionUrlAuthTypeAuth type (AWS_IAM or NONE)AWS_IAM
functionUrlCorsFunctionUrlCorsOptionsCORS configuration-

Default Configuration

The LambdaFunction construct includes these defaults:
  • IAM Role automatically created with lambda.amazonaws.com service principal
  • CloudWatch Logs access via AWSLambdaBasicExecutionRole managed policy
  • Timeout of 300 seconds / 5 minutes (adjustable from 1 to 900 seconds)
  • Memory of 128 MB (adjustable up to 10 GB)
  • Function URL with IAM authentication when enabled

Code Sources

From Local Directory

import { Code } from "aws-cdk-lib/aws-lambda";

const lambda = new LambdaFunction(this, "AssetFunction", {
  code: Code.fromAsset("./src/lambda"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  inlinePolicy: {}
});

From ECR Image

import { Code, Runtime } from "aws-cdk-lib/aws-lambda";

const lambda = new LambdaFunction(this, "ContainerFunction", {
  code: Code.fromEcrImage(ecrRepository, {
    tagOrDigest: "latest"
  }),
  // For container images, use a dummy handler (ignored by Lambda)
  handler: "handler",
  runtime: Runtime.FROM_IMAGE,
  inlinePolicy: {}
});

From Inline Code

const lambda = new LambdaFunction(this, "InlineFunction", {
  code: Code.fromInline(`
    exports.handler = async (event) => {
      return { statusCode: 200, body: 'Hello World' };
    };
  `),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  inlinePolicy: {}
});

ComputeFactory Pattern

Basic Lambda with ComputeFactory

import { App, ComputeFactory } from "@fjall/components-infrastructure";
import { Code, Runtime } from "aws-cdk-lib/aws-lambda";

const app = App.getApp("MyApp");

app.addCompute(
  ComputeFactory.build("ApiHandler", {
    type: "lambda",
    code: Code.fromAsset("./api"),
    handler: "handler.main",
    runtime: Runtime.NODEJS_18_X,
    timeout: 30,
    memorySize: 512,
    lambdaDescription: "API request handler",
    inlinePolicy: {}
  })
);

With Function URL

import { FunctionUrlAuthType, HttpMethod } from "aws-cdk-lib/aws-lambda";

app.addCompute(
  ComputeFactory.build("PublicApi", {
    type: "lambda",
    code: Code.fromAsset("./api"),
    handler: "index.handler",
    runtime: Runtime.NODEJS_18_X,
    enableFunctionUrl: true,
    functionUrlAuthType: FunctionUrlAuthType.NONE,
    functionUrlCors: {
      allowedOrigins: ["*"],
      allowedMethods: [HttpMethod.GET, HttpMethod.POST],
      allowedHeaders: ["Content-Type", "Authorization"],
      allowCredentials: false,
      maxAge: Duration.hours(1)
    },
    inlinePolicy: {}
  })
);

// Function URL available as CloudFormation output: "LambdaFunctionUrl"

Database Integration

Important: VPC Configuration Required

Lambda functions must be deployed in a VPC to access RDS databases. Use the native CDK properties vpc, vpcSubnets, and securityGroups for VPC configuration. Database credentials should be accessed via AWS Secrets Manager using environment variables and IAM permissions.

Single Database Connection

import { App, ComputeFactory, StorageFactory } from "@fjall/components-infrastructure";
import { Code, Runtime } from "aws-cdk-lib/aws-lambda";
import { PolicyDocument, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { SubnetType } from "aws-cdk-lib/aws-ec2";

const app = App.getApp("MyApp");

// Create database
const database = app.addStorage(
  StorageFactory.build("AppDatabase", {
    type: "FreeTier",
    databaseName: "appdb"
  })
);

// Get VPC for Lambda deployment
const vpc = app.getDefaultVpc();

// Lambda with database access (using LambdaFunction directly for VPC config)
const dbWorker = new LambdaFunction(this, "DatabaseWorker", {
  code: Code.fromAsset("./worker"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  timeout: 60,

  // VPC configuration (required for RDS access)
  vpc: vpc,
  vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },

  // Environment variables with database connection info
  environment: {
    DATABASE_HOST: database.getHostEndpoint(),
    DATABASE_PORT: database.getHostPort(),
    DATABASE_NAME: database.getDatabaseName(),
    DATABASE_SECRET_ARN: database.getCredentials().secretArn
  },

  // IAM permissions to access Secrets Manager
  inlinePolicy: {
    "secrets-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["secretsmanager:GetSecretValue"],
          resources: [database.getCredentials().secretArn]
        })
      ]
    })
  }
});

// Allow Lambda to connect to database security group
database.connections.allowDefaultPortFrom(dbWorker);
Lambda function code to retrieve password:
// worker/index.js
const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");

const client = new SecretsManagerClient();

async function getDatabasePassword() {
  const response = await client.send(
    new GetSecretValueCommand({ SecretId: process.env.DATABASE_SECRET_ARN })
  );
  const secret = JSON.parse(response.SecretString);
  return secret.password;
}

Multiple Database Connections

const primaryDb = app.addStorage(
  StorageFactory.build("PrimaryDB", {
    type: "FreeTier",
    databaseName: "primary"
  })
);

const analyticsDb = app.addStorage(
  StorageFactory.build("AnalyticsDB", {
    type: "FreeTier",
    databaseName: "analytics"
  })
);

const vpc = app.getDefaultVpc();

const dataSync = new LambdaFunction(this, "DataSync", {
  code: Code.fromAsset("./sync"),
  handler: "sync.handler",
  runtime: Runtime.PYTHON_3_11,
  timeout: 300,
  memorySize: 1024,

  // VPC configuration
  vpc: vpc,
  vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },

  // Environment variables for both databases
  environment: {
    PRIMARY_DB_HOST: primaryDb.getHostEndpoint(),
    PRIMARY_DB_PORT: primaryDb.getHostPort(),
    PRIMARY_DB_NAME: primaryDb.getDatabaseName(),
    PRIMARY_DB_SECRET_ARN: primaryDb.getCredentials().secretArn,
    ANALYTICS_DB_HOST: analyticsDb.getHostEndpoint(),
    ANALYTICS_DB_PORT: analyticsDb.getHostPort(),
    ANALYTICS_DB_NAME: analyticsDb.getDatabaseName(),
    ANALYTICS_DB_SECRET_ARN: analyticsDb.getCredentials().secretArn
  },

  // IAM permissions for both Secrets
  inlinePolicy: {
    "secrets-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["secretsmanager:GetSecretValue"],
          resources: [
            primaryDb.getCredentials().secretArn,
            analyticsDb.getCredentials().secretArn
          ]
        })
      ]
    })
  }
});

// Allow Lambda to connect to both database security groups
primaryDb.connections.allowDefaultPortFrom(dataSync);
analyticsDb.connections.allowDefaultPortFrom(dataSync);

IAM Permissions

S3 Access

import { PolicyDocument, PolicyStatement } from "aws-cdk-lib/aws-iam";

const lambda = new LambdaFunction(this, "S3Processor", {
  code: Code.fromAsset("./processor"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  inlinePolicy: {
    "s3-read-write": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["s3:GetObject", "s3:PutObject"],
          resources: ["arn:aws:s3:::my-bucket/*"]
        })
      ]
    })
  }
});

DynamoDB Access

const lambda = new LambdaFunction(this, "DynamoProcessor", {
  code: Code.fromAsset("./dynamo"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  inlinePolicy: {
    "dynamodb-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: [
            "dynamodb:GetItem",
            "dynamodb:PutItem",
            "dynamodb:Query",
            "dynamodb:Scan"
          ],
          resources: ["arn:aws:dynamodb:*:*:table/MyTable"]
        })
      ]
    })
  }
});

Multiple Service Access

const lambda = new LambdaFunction(this, "MultiServiceFunction", {
  code: Code.fromAsset("./multi"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  inlinePolicy: {
    "s3-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["s3:*"],
          resources: ["arn:aws:s3:::my-bucket/*"]
        })
      ]
    }),
    "sqs-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["sqs:SendMessage", "sqs:ReceiveMessage"],
          resources: ["arn:aws:sqs:*:*:my-queue"]
        })
      ]
    }),
    "sns-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["sns:Publish"],
          resources: ["arn:aws:sns:*:*:my-topic"]
        })
      ]
    })
  }
});

Runtime Configuration

Node.js Function

const nodeFunction = new LambdaFunction(this, "NodeFunction", {
  code: Code.fromAsset("./node-app"),
  handler: "app.handler",
  runtime: Runtime.NODEJS_18_X,
  environment: {
    NODE_ENV: "production",
    LOG_LEVEL: "info"
  },
  inlinePolicy: {}
});

Python Function

const pythonFunction = new LambdaFunction(this, "PythonFunction", {
  code: Code.fromAsset("./python-app", {
    bundling: {
      image: Runtime.PYTHON_3_11.bundlingImage,
      command: [
        "bash", "-c",
        "pip install -r requirements.txt -t /asset-output && cp -au . /asset-output"
      ]
    }
  }),
  handler: "app.lambda_handler",
  runtime: Runtime.PYTHON_3_11,
  inlinePolicy: {}
});

Go Function

const goFunction = new LambdaFunction(this, "GoFunction", {
  code: Code.fromAsset("./go-app", {
    bundling: {
      image: Runtime.GO_1_X.bundlingImage,
      command: [
        "bash", "-c",
        "GOOS=linux GOARCH=amd64 go build -o /asset-output/bootstrap"
      ]
    }
  }),
  handler: "bootstrap",
  runtime: Runtime.PROVIDED_AL2,
  inlinePolicy: {}
});

Advanced Patterns

Scheduled Lambda (Cron)

import { Rule, Schedule } from "aws-cdk-lib/aws-events";
import { LambdaFunction as LambdaTarget } from "aws-cdk-lib/aws-events-targets";

const cronFunction = new LambdaFunction(this, "CronJob", {
  code: Code.fromAsset("./cron"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  timeout: 300,
  inlinePolicy: {}
});

new Rule(this, "DailyRule", {
  schedule: Schedule.cron({ hour: "0", minute: "0" }),
  targets: [new LambdaTarget(cronFunction)]
});

SQS-Triggered Lambda

import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
import { Queue } from "aws-cdk-lib/aws-sqs";

const queue = new Queue(this, "TaskQueue");

const queueProcessor = new LambdaFunction(this, "QueueProcessor", {
  code: Code.fromAsset("./processor"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  timeout: 60,
  inlinePolicy: {}
});

queueProcessor.addEventSource(new SqsEventSource(queue, {
  batchSize: 10
}));

S3-Triggered Lambda

import { S3EventSource } from "aws-cdk-lib/aws-lambda-event-sources";
import { Bucket, EventType } from "aws-cdk-lib/aws-s3";

const bucket = new Bucket(this, "UploadBucket");

const imageProcessor = new LambdaFunction(this, "ImageProcessor", {
  code: Code.fromAsset("./image-processor"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  timeout: 120,
  memorySize: 2048,
  inlinePolicy: {
    "s3-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["s3:GetObject", "s3:PutObject"],
          resources: [bucket.arnForObjects("*")]
        })
      ]
    })
  }
});

imageProcessor.addEventSource(new S3EventSource(bucket, {
  events: [EventType.OBJECT_CREATED]
}));

SingletonFunction for Custom Resources

import { SingletonFunction } from "@fjall/components-infrastructure";
import { Provider } from "aws-cdk-lib/custom-resources";

const singletonHandler = new SingletonFunction(this, "CustomResourceHandler", {
  code: Code.fromAsset("./custom-resource"),
  handler: "handler.onEvent",
  runtime: Runtime.PYTHON_3_11,
  timeout: 300,
  lambdaDescription: "Custom resource handler",
  inlinePolicy: {
    "cloudformation-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["cloudformation:DescribeStacks"],
          resources: ["*"]
        })
      ]
    })
  }
});

const provider = new Provider(this, "CustomResourceProvider", {
  onEventHandler: singletonHandler
});

Complete Example

import { App, StorageFactory, LambdaFunction } from "@fjall/components-infrastructure";
import { Code, Runtime, FunctionUrlAuthType, HttpMethod } from "aws-cdk-lib/aws-lambda";
import { PolicyDocument, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { SubnetType } from "aws-cdk-lib/aws-ec2";
import { Duration } from "aws-cdk-lib";
import { Construct } from "constructs";

const app = App.getApp("ProductionApp");

// Create database
const database = app.addStorage(
  StorageFactory.build("ProductionDB", {
    type: "FreeTier",
    databaseName: "production"
  })
);

// Get VPC for Lambda deployment
const vpc = app.getDefaultVpc();

// API Lambda with Function URL (in a construct for access to 'this')
class ApiStack extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    // API Lambda with Function URL
    const apiFunction = new LambdaFunction(this, "RestApi", {
      // Code configuration
      code: Code.fromAsset("./api", {
        exclude: ["*.test.js", "node_modules"]
      }),
      handler: "api/index.handler",
      runtime: Runtime.NODEJS_18_X,

      // VPC configuration (required for database access)
      vpc: vpc,
      vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },

      // Execution configuration
      timeout: 30,
      memorySize: 1024,
      lambdaDescription: "Production REST API handler",
      roleDescription: "API Lambda execution role",

      // Environment variables
      environment: {
        NODE_ENV: "production",
        LOG_LEVEL: "info",
        DATABASE_HOST: database.getHostEndpoint(),
        DATABASE_PORT: database.getHostPort(),
        DATABASE_NAME: database.getDatabaseName(),
        DATABASE_SECRET_ARN: database.getCredentials().secretArn,
        CACHE_TTL: "3600"
      },

      // Function URL with CORS
      enableFunctionUrl: true,
      functionUrlAuthType: FunctionUrlAuthType.NONE,
      functionUrlCors: {
        allowedOrigins: ["https://example.com"],
        allowedMethods: [
          HttpMethod.GET,
          HttpMethod.POST,
          HttpMethod.PUT,
          HttpMethod.DELETE
        ],
        allowedHeaders: [
          "Content-Type",
          "Authorization",
          "X-Requested-With"
        ],
        allowCredentials: true,
        maxAge: Duration.hours(1),
        exposeHeaders: ["X-Request-Id"]
      },

      // IAM permissions
      inlinePolicy: {
        "secrets-manager": new PolicyDocument({
          statements: [
            new PolicyStatement({
              actions: ["secretsmanager:GetSecretValue"],
              resources: [database.getCredentials().secretArn]
            })
          ]
        }),
        "s3-access": new PolicyDocument({
          statements: [
            new PolicyStatement({
              actions: ["s3:GetObject", "s3:PutObject"],
              resources: ["arn:aws:s3:::my-app-uploads/*"]
            })
          ]
        }),
        "dynamodb-cache": new PolicyDocument({
          statements: [
            new PolicyStatement({
              actions: [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:DeleteItem"
              ],
              resources: ["arn:aws:dynamodb:*:*:table/api-cache"]
            })
          ]
        })
      },

      // Tags
      tags: {
        Environment: "production",
        Application: "rest-api",
        CostCenter: "engineering"
      }
    });

    // Allow Lambda to connect to database
    database.connections.allowDefaultPortFrom(apiFunction);

    // Background worker Lambda
    const workerFunction = new LambdaFunction(this, "BackgroundWorker", {
      code: Code.fromAsset("./worker"),
      handler: "worker/index.handler",
      runtime: Runtime.NODEJS_18_X,

      // VPC configuration
      vpc: vpc,
      vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },

      // Execution configuration
      timeout: 300,  // 5 minutes
      memorySize: 2048,
      lambdaDescription: "Background job processor",

      // Environment variables
      environment: {
        DATABASE_HOST: database.getHostEndpoint(),
        DATABASE_PORT: database.getHostPort(),
        DATABASE_NAME: database.getDatabaseName(),
        DATABASE_SECRET_ARN: database.getCredentials().secretArn,
        BATCH_SIZE: "100"
      },

      // IAM permissions
      inlinePolicy: {
        "full-access": new PolicyDocument({
          statements: [
            new PolicyStatement({
              actions: ["secretsmanager:GetSecretValue"],
              resources: [database.getCredentials().secretArn]
            }),
            new PolicyStatement({
              actions: ["sqs:ReceiveMessage", "sqs:DeleteMessage"],
              resources: ["arn:aws:sqs:*:*:worker-queue"]
            })
          ]
        })
      }
    });

    // Allow worker Lambda to connect to database
    database.connections.allowDefaultPortFrom(workerFunction);
  }
}

// Instantiate the stack
new ApiStack(app, "ApiStack");

Best Practices

  1. Set appropriate timeouts - Use minimum necessary timeout to avoid runaway costs
  2. Right-size memory - Balance performance vs cost (CPU scales with memory)
  3. Use environment variables - Store configuration, not secrets
  4. Store secrets properly - Use AWS Secrets Manager or Parameter Store
  5. Implement idempotency - Handle duplicate invocations gracefully
  6. Enable CloudWatch Logs - Automatically included via AWSLambdaBasicExecutionRole
  7. Use inline policies - Grant least-privilege access to AWS services
  8. Enable Function URLs with auth - Use AWS_IAM auth type unless public access required
  9. Configure CORS carefully - Don’t use * for origins in production
  10. Tag resources - Enable cost tracking and resource organization
  11. Set memory efficiently - Start at 1024 MB for typical workloads, adjust based on metrics
  12. Use connection pooling - Reuse database connections across invocations

Memory and Performance Optimization

Memory Sizing Guidelines

Use CaseRecommended MemoryNotes
Simple API256-512 MBBasic CRUD operations
Database queries512-1024 MBConnection pooling helps
Image processing2048-3008 MBI/O intensive workloads
Data transformation1024-2048 MBBalance CPU and memory
ML inference3008-10240 MBModel size dependent

Cost vs Performance

// Under-provisioned (slower, cheaper per GB-second)
const cheapLambda = new LambdaFunction(this, "Cheap", {
  memorySize: 128,  // Minimum
  timeout: 900,     // May timeout
  // ...
});

// Optimized (faster, better cost efficiency)
const optimalLambda = new LambdaFunction(this, "Optimal", {
  memorySize: 1024,  // Good balance
  timeout: 30,       // Completes quickly
  // ...
});

// Over-provisioned (fastest, expensive)
const fastLambda = new LambdaFunction(this, "Fast", {
  memorySize: 10240,  // Maximum
  timeout: 60,
  // ...
});

Troubleshooting

Function Times Out

// Increase timeout
const lambda = new LambdaFunction(this, "SlowFunction", {
  timeout: 300,  // 5 minutes instead of default 3 seconds
  // ...
});

Out of Memory Errors

// Increase memory allocation
const lambda = new LambdaFunction(this, "MemoryIntensive", {
  memorySize: 2048,  // 2 GB instead of default 128 MB
  // ...
});

Permission Denied Errors

// Add required IAM permissions
const lambda = new LambdaFunction(this, "S3Lambda", {
  inlinePolicy: {
    "s3-access": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["s3:GetObject"],
          resources: ["arn:aws:s3:::my-bucket/*"]
        })
      ]
    })
  },
  // ...
});

Database Connection Failures

Common Issues:
  • Lambda not deployed in VPC
  • Incorrect security group rules
  • Missing IAM permissions for Secrets Manager
  • Wrong database endpoint or credentials
// Correct database connection setup
const dbLambda = new LambdaFunction(this, "DbLambda", {
  code: Code.fromAsset("./app"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,

  // REQUIRED: VPC configuration
  vpc: vpc,
  vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS },

  // Environment variables with connection info
  environment: {
    DATABASE_HOST: database.getHostEndpoint(),
    DATABASE_PORT: database.getHostPort(),
    DATABASE_NAME: database.getDatabaseName(),
    DATABASE_SECRET_ARN: database.getCredentials().secretArn
  },

  // IAM permissions to read secrets
  inlinePolicy: {
    "secrets": new PolicyDocument({
      statements: [
        new PolicyStatement({
          actions: ["secretsmanager:GetSecretValue"],
          resources: [database.getCredentials().secretArn]
        })
      ]
    })
  }
});

// REQUIRED: Allow Lambda security group access to database
database.connections.allowDefaultPortFrom(dbLambda);

CORS Issues with Function URL

// Configure CORS properly
const lambda = app.addCompute(
  ComputeFactory.build("CorsApi", {
    enableFunctionUrl: true,
    functionUrlAuthType: FunctionUrlAuthType.NONE,
    functionUrlCors: {
      allowedOrigins: ["https://example.com"],  // Specific origin
      allowedMethods: [HttpMethod.POST],        // Required methods
      allowedHeaders: ["Content-Type"],         // Required headers
      allowCredentials: true                    // If using cookies
    },
    // ...
  })
);

Cold Start Optimization

// Increase memory for faster cold starts
const lambda = new LambdaFunction(this, "WarmLambda", {
  memorySize: 1024,  // More memory = faster initialization
  // Keep dependencies minimal
  // Use Lambda SnapStart for Java (if applicable)
  // Consider provisioned concurrency for critical functions
  // ...
});

Cost Optimization

StrategyImplementationSavings
Right-size memoryStart at 1024 MB, adjust based on CloudWatch metrics20-40%
Reduce timeoutSet to expected duration + bufferPrevents runaway costs
Minimize dependenciesSmaller deployment packages = faster cold startsFaster execution
Reuse connectionsKeep database and HTTP connections outside handlerReduces init time
Provisioned concurrencyOnly for latency-critical functionsEliminates cold starts

Memory Optimization Example

// Monitor CloudWatch metrics and adjust memory
const optimizedLambda = new LambdaFunction(this, "OptimizedFunction", {
  code: Code.fromAsset("./app"),
  handler: "index.handler",
  runtime: Runtime.NODEJS_18_X,
  memorySize: 1024,  // Start here, adjust based on metrics
  timeout: 30,       // Set to expected duration + buffer
  inlinePolicy: {}
});
  • ECS Cluster - Container orchestration for long-running services
  • IAM Role - Identity and access management
  • RDS Aurora - Relational database service
  • S3 Bucket - Object storage service
  • VPC - Virtual private cloud networking