mirror of
https://github.com/Sea-Haven-Industries/engineering-handbook.git
synced 2026-09-30 23:13:14 +00:00
Adds three handbook pages covering conventions that were previously scattered across feedback memories or rederived from scratch each time: - bedrock.md captures the cross-region inference profile requirement for Claude 4.x Bedrock Agents and the alias-version pinning gotcha, plus the IAM resource pattern and the KB Docker requirement. - dev-environment.md documents the workstation directory layout, pyenv/Node conventions, the macOS launchd/TCC sandbox gotcha, and cleanup cadence. - lambda-template.md provides a minimal SAM scaffold that follows the Lambda defaults already in aws-infrastructure.md (Python 3.12, arm64, explicit 60-day log retention, scoped Secrets Manager access, module-level secret cache). Also extends two existing pages: - sam-project-layout.md gains a Lambda Layers section with the BuildMethod nesting pattern that caused a ~22-hour production outage when violated. - naming-conventions.md adds a Legacy Stacks note acknowledging that pre-convention PascalCase stacks (SeaHavenDoorUnlockStack, WorkorderIngestStack) stay as-is rather than risk stack replacement.
98 lines
3.1 KiB
Markdown
98 lines
3.1 KiB
Markdown
# SAM Project Layout
|
|
|
|
## Standard Directory Structure
|
|
|
|
```
|
|
project-name/
|
|
├── template.yaml # SAM template at root
|
|
├── samconfig.toml # Deploy config (gitignored)
|
|
├── samconfig.toml.example # Template for onboarding (committed)
|
|
├── src/
|
|
│ ├── function_name/
|
|
│ │ ├── app.py # Lambda handler
|
|
│ │ └── requirements.txt # Per-function dependencies
|
|
│ └── shared/ # Shared layer code (if needed)
|
|
└── .gitignore
|
|
```
|
|
|
|
## File Purposes
|
|
|
|
### `template.yaml`
|
|
|
|
The SAM/CloudFormation template. Lives at the project root. Defines all Lambda functions, IAM roles, API Gateway endpoints, DynamoDB tables, and other resources.
|
|
|
|
### `samconfig.toml`
|
|
|
|
Contains real ARNs, S3 bucket names, and deploy parameters. **Gitignored** because it varies per environment and may contain account-specific values.
|
|
|
|
### `samconfig.toml.example`
|
|
|
|
A committed template showing the expected structure and parameter names. New contributors copy this to `samconfig.toml` and fill in their values.
|
|
|
|
### `src/function_name/`
|
|
|
|
One directory per Lambda function. Each contains its own handler (`app.py`) and dependencies (`requirements.txt`). This keeps functions independently deployable and avoids bloating one function with another's dependencies.
|
|
|
|
### `src/shared/`
|
|
|
|
Optional. Used for code shared across multiple functions, typically deployed as a Lambda layer. See the next section for layout details.
|
|
|
|
## Lambda Layers
|
|
|
|
When sharing code across functions via a layer, the source layout matters because SAM transforms `ContentUri` depending on whether `BuildMethod` is set.
|
|
|
|
### Correct layout (with `BuildMethod`)
|
|
|
|
```
|
|
src/shared/
|
|
├── shared/ # Package goes here directly — SAM wraps in python/ at build time
|
|
│ ├── __init__.py
|
|
│ └── utils.py
|
|
└── requirements.txt # Layer-level pip dependencies
|
|
```
|
|
|
|
Template:
|
|
|
|
```yaml
|
|
SharedLayer:
|
|
Type: AWS::Serverless::LayerVersion
|
|
Properties:
|
|
LayerName: my-stack-shared
|
|
ContentUri: src/shared/
|
|
CompatibleRuntimes:
|
|
- python3.12
|
|
CompatibleArchitectures:
|
|
- arm64
|
|
Metadata:
|
|
BuildMethod: python3.12
|
|
BuildArchitecture: arm64
|
|
```
|
|
|
|
### BuildMethod nesting gotcha
|
|
|
|
With `BuildMethod: python3.12`, SAM copies `ContentUri` into a `python/` subdirectory during build, then pip-installs `requirements.txt` deps into that same `python/` directory.
|
|
|
|
Do **not** include a `python/` wrapper in your source — SAM adds it. The wrong layout:
|
|
|
|
```
|
|
src/shared/
|
|
├── python/ # SAM wraps this again → python/python/shared/ — module unreachable
|
|
│ └── shared/
|
|
└── requirements.txt
|
|
```
|
|
|
|
A real production incident (~22 hours of outage) traced to this exact pattern when a refactor moved layer code under an extra `python/` directory.
|
|
|
|
### Without BuildMethod (raw zip)
|
|
|
|
If the layer has no pip dependencies and you omit `BuildMethod`, SAM zips `ContentUri` as-is — you DO need the `python/` wrapper. Reserve raw zip for layers that ship only Python source.
|
|
|
|
## Standard .gitignore
|
|
|
|
```
|
|
.aws-sam/
|
|
__pycache__/
|
|
*.pyc
|
|
.env
|
|
samconfig.toml
|
|
```
|