220 lines
12 KiB
Plaintext
220 lines
12 KiB
Plaintext
---
|
|
description: Comprehensive guide for AWS Lambda development, covering best practices for code organization, performance, security, testing, and common pitfalls. Focuses on building robust, scalable, and secure serverless applications using AWS Lambda.
|
|
globs: *.js,*.ts,*.jsx,*.tsx,*.py,*.java,*.go,*.c#,*.cs,*.ps1,*.sh
|
|
---
|
|
- **Use Documented APIs Only:** Rely solely on AWS Lambda's documented APIs to ensure compatibility and avoid unexpected behavior. Do not use undocumented or internal APIs.
|
|
|
|
- **Single Responsibility Principle:** Design Lambda functions to perform a single, well-defined task. This promotes modularity, testability, and maintainability.
|
|
|
|
- **Native AWS Integrations:** Prefer native AWS integrations (e.g., SQS, SNS, Kinesis) for passing data between services instead of custom code, which enhances scalability and reduces complexity.
|
|
|
|
- **Local Dependencies:** Store and reference dependencies locally within the Lambda function package to minimize latency and improve cold start times.
|
|
|
|
- **Limit Variable Re-initialization:** Initialize variables outside the function handler to leverage execution context reuse and reduce initialization overhead.
|
|
|
|
- **Thorough Testing:** Implement a comprehensive testing strategy including unit, integration, and end-to-end tests to ensure function correctness and reliability.
|
|
|
|
## 1. Code Organization and Structure:
|
|
|
|
- **Directory Structure:**
|
|
- Organize code into logical directories based on functionality (e.g., `src`, `tests`, `utils`).
|
|
- Separate handler logic from core business logic.
|
|
- Example:
|
|
|
|
my-lambda-function/
|
|
├── src/
|
|
│ ├── handler.js # Lambda handler function
|
|
│ ├── business-logic.js # Core business logic
|
|
│ └── utils.js # Utility functions
|
|
├── tests/
|
|
│ ├── handler.test.js # Unit tests for handler.js
|
|
│ └── ...
|
|
├── package.json # Dependencies and scripts
|
|
└── ...
|
|
|
|
|
|
- **File Naming Conventions:**
|
|
- Use descriptive and consistent file names.
|
|
- Follow a naming convention (e.g., `kebab-case`, `PascalCase`) consistently.
|
|
- Example: `user-service.js`, `UserService.java`.
|
|
|
|
- **Module Organization:**
|
|
- Break down large functions into smaller, reusable modules.
|
|
- Use appropriate module systems (e.g., ES modules in JavaScript, packages in Python, modules in Go).
|
|
- Example (JavaScript):
|
|
javascript
|
|
// src/user-service.js
|
|
export function createUser(userData) { ... }
|
|
export function getUser(userId) { ... }
|
|
|
|
|
|
- **Component Architecture:**
|
|
- Design Lambda functions as part of a larger component-based architecture.
|
|
- Decouple functions from specific triggers (e.g., API Gateway, SQS) to increase reusability.
|
|
- Implement interfaces or contracts to define interactions between components.
|
|
|
|
- **Code Splitting Strategies:**
|
|
- Use code splitting techniques to reduce Lambda function package size.
|
|
- Implement dynamic imports or lazy loading for infrequently used modules (where supported by the runtime).
|
|
- Leverage layers for shared dependencies across multiple functions.
|
|
|
|
## 2. Common Patterns and Anti-patterns:
|
|
|
|
- **Design Patterns:**
|
|
- **Event-Driven Architecture:** Design functions to respond to events from various AWS services.
|
|
- **Command Pattern:** Encapsulate requests as objects to decouple request processing from the handler.
|
|
- **Dependency Injection:** Inject dependencies into functions to improve testability and maintainability.
|
|
|
|
- **Recommended Approaches:**
|
|
- **Configuration Management:** Use environment variables or AWS Systems Manager Parameter Store for configuration data.
|
|
- **Logging:** Implement structured logging with timestamps, request IDs, and relevant context.
|
|
- **Idempotency:** Ensure functions are idempotent to handle potential retry scenarios gracefully.
|
|
|
|
- **Anti-patterns:**
|
|
- **Monolithic Functions:** Avoid creating large, complex functions that perform multiple unrelated tasks.
|
|
- **Hardcoding Secrets:** Never hardcode sensitive information (e.g., API keys, passwords) in code. Use AWS Secrets Manager or environment variables.
|
|
- **Excessive Dependencies:** Minimize the number of dependencies to reduce package size and improve cold start times.
|
|
|
|
- **State Management:**
|
|
- Use external services (e.g., DynamoDB, Redis) for persistent state management.
|
|
- Leverage Lambda layers for caching frequently accessed data.
|
|
- Design functions to be stateless whenever possible.
|
|
|
|
- **Error Handling:**
|
|
- Implement robust error handling mechanisms, including try-catch blocks and error logging.
|
|
- Use custom exceptions for specific error scenarios.
|
|
- Return meaningful error messages to the caller.
|
|
- Implement dead-letter queues (DLQs) for asynchronous invocations to handle failed events.
|
|
|
|
## 3. Performance Considerations:
|
|
|
|
- **Optimization Techniques:**
|
|
- **Minimize Package Size:** Reduce the size of the deployment package by removing unnecessary files and dependencies.
|
|
- **Optimize Dependencies:** Use lightweight dependencies and avoid importing entire libraries when only specific functions are needed.
|
|
- **Code Optimization:** Profile and optimize code for performance bottlenecks.
|
|
- **Connection Reuse:** Reuse database connections, HTTP clients, and other resources to minimize overhead.
|
|
|
|
- **Memory Management:**
|
|
- Allocate sufficient memory to Lambda functions based on their needs.
|
|
- Monitor memory usage and adjust the memory allocation accordingly.
|
|
- Clean up resources (e.g., closing file streams, releasing memory) to avoid memory leaks.
|
|
|
|
- **Cold Starts:**
|
|
- Minimize cold start times by reducing package size, optimizing dependencies, and using provisioned concurrency.
|
|
- Use initilization logic outside the handler to take advantage of container reuse
|
|
|
|
- **Bundle Size Optimization:**
|
|
- Use tools like Webpack or esbuild to bundle and optimize code for production.
|
|
- Minify code and remove unused code (dead code elimination).
|
|
|
|
- **Lazy Loading Strategies:**
|
|
- Implement lazy loading or dynamic imports for infrequently used modules to reduce initial load time.
|
|
|
|
## 4. Security Best Practices:
|
|
|
|
- **Common Vulnerabilities:**
|
|
- **Injection Attacks:** Prevent SQL injection, command injection, and other injection attacks by validating and sanitizing input.
|
|
- **Cross-Site Scripting (XSS):** Protect against XSS vulnerabilities by encoding output properly.
|
|
- **Insecure Deserialization:** Avoid deserializing untrusted data to prevent arbitrary code execution.
|
|
- **Broken Authentication:** Implement strong authentication and authorization mechanisms.
|
|
|
|
- **Input Validation:**
|
|
- Validate all input data to prevent malicious or invalid data from being processed.
|
|
- Use schema validation libraries to enforce data types and formats.
|
|
- Sanitize input data to remove potentially harmful characters or code.
|
|
|
|
- **Authentication and Authorization:**
|
|
- Use AWS Identity and Access Management (IAM) roles to grant Lambda functions the necessary permissions.
|
|
- Implement authentication and authorization mechanisms to protect sensitive resources.
|
|
- Use AWS Cognito for user authentication and authorization.
|
|
|
|
- **Data Protection:**
|
|
- Encrypt sensitive data at rest and in transit.
|
|
- Use AWS Key Management Service (KMS) to manage encryption keys.
|
|
- Mask or redact sensitive data in logs.
|
|
|
|
- **Secure API Communication:**
|
|
- Use HTTPS for all API communication.
|
|
- Implement API authentication and authorization using API keys, JWT tokens, or other secure mechanisms.
|
|
- Protect against common web application attacks (e.g., CSRF, DDoS).
|
|
|
|
## 5. Testing Approaches:
|
|
|
|
- **Unit Testing:**
|
|
- Write unit tests to verify the correctness of individual functions or modules.
|
|
- Use mocking or stubbing to isolate units of code from external dependencies.
|
|
- Use testing frameworks (e.g., Jest, Mocha, pytest) to automate unit testing.
|
|
|
|
- **Integration Testing:**
|
|
- Write integration tests to verify the interactions between different components or services.
|
|
- Test the integration of Lambda functions with other AWS services (e.g., SQS, DynamoDB).
|
|
- Use tools like AWS SAM Local to run integration tests locally.
|
|
|
|
- **End-to-End Testing:**
|
|
- Write end-to-end tests to verify the entire application flow from end to end.
|
|
- Simulate user interactions to test the application's functionality.
|
|
- Use tools like Selenium or Cypress to automate end-to-end testing.
|
|
|
|
- **Test Organization:**
|
|
- Organize tests into separate directories based on the type of test (e.g., unit, integration, e2e).
|
|
- Use descriptive test names to clearly identify the purpose of each test.
|
|
- Follow a consistent testing strategy across all projects.
|
|
|
|
- **Mocking and Stubbing:**
|
|
- Use mocking or stubbing to replace external dependencies with controlled test doubles.
|
|
- Mock AWS SDK calls to isolate Lambda functions from AWS services.
|
|
- Use mocking frameworks (e.g., Jest, Sinon.js) to simplify mocking and stubbing.
|
|
|
|
## 6. Common Pitfalls and Gotchas:
|
|
|
|
- **Frequent Mistakes:**
|
|
- **Incorrect IAM Permissions:** Ensure that Lambda functions have the necessary IAM permissions to access required AWS resources.
|
|
- **Timeout Errors:** Increase the Lambda function timeout if it takes longer than expected to complete.
|
|
- **Memory Exhaustion:** Allocate sufficient memory to Lambda functions to avoid memory exhaustion errors.
|
|
- **Unclosed Connections:** Close database connections, HTTP clients, and other resources properly to avoid resource leaks.
|
|
|
|
- **Edge Cases:**
|
|
- **Concurrent Invocations:** Handle concurrent invocations gracefully to avoid race conditions or data corruption.
|
|
- **Throttling:** Implement retry mechanisms to handle throttling errors from AWS services.
|
|
- **Error Retries:** Design functions to be idempotent to handle potential retry scenarios gracefully.
|
|
|
|
- **Version-Specific Issues:**
|
|
- Be aware of version-specific issues or compatibility concerns when upgrading Lambda function runtimes or dependencies.
|
|
- Test Lambda functions thoroughly after upgrading to ensure they still function correctly.
|
|
|
|
- **Compatibility Concerns:**
|
|
- Ensure that Lambda functions are compatible with the supported runtime environment.
|
|
- Use compatible versions of dependencies to avoid compatibility issues.
|
|
|
|
- **Debugging Strategies:**
|
|
- Use CloudWatch Logs to debug Lambda function execution.
|
|
- Use AWS X-Ray to trace and analyze Lambda function performance.
|
|
- Use local debugging tools (e.g., AWS SAM Local) to debug Lambda functions locally.
|
|
|
|
## 7. Tooling and Environment:
|
|
|
|
- **Recommended Tools:**
|
|
- **AWS SAM:** Use AWS SAM (Serverless Application Model) to define and deploy Lambda functions and other serverless resources.
|
|
- **AWS CLI:** Use the AWS CLI (Command Line Interface) to manage AWS resources from the command line.
|
|
- **Terraform/CloudFormation:** Use Infrastructure as Code (IaC) tools like Terraform or CloudFormation to provision and manage AWS infrastructure.
|
|
- **IDE:** Use an IDE with support for Lambda development (e.g., VS Code with the AWS Toolkit extension).
|
|
|
|
- **Build Configuration:**
|
|
- Use build tools (e.g., npm, yarn, Maven, Gradle) to manage dependencies and build Lambda function packages.
|
|
- Configure build scripts to automate common tasks (e.g., linting, testing, bundling).
|
|
|
|
- **Linting and Formatting:**
|
|
- Use linters (e.g., ESLint, Pylint) to enforce coding standards and identify potential code quality issues.
|
|
- Use formatters (e.g., Prettier, Black) to automatically format code consistently.
|
|
|
|
- **Deployment:**
|
|
- Use AWS SAM CLI or other deployment tools to deploy Lambda functions to AWS.
|
|
- Implement blue/green deployments or canary deployments to minimize downtime during deployments.
|
|
- Automate deployments using CI/CD pipelines.
|
|
|
|
- **CI/CD Integration:**
|
|
- Integrate Lambda function deployments with CI/CD pipelines to automate testing and deployment.
|
|
- Use CI/CD tools (e.g., Jenkins, CircleCI, GitHub Actions) to build, test, and deploy Lambda functions.
|
|
|
|
@file aws-lambda-security.mdc
|
|
@file aws-lambda-performance.mdc |