S3StateStore
The S3StateStore provides reliable, scalable state storage for Alchemy applications using Amazon S3. It’s designed for cloud-based deployments where you need durable, shared state storage across multiple environments or team members.
Basic Usage
Section titled “Basic Usage”Configure Alchemy to use S3 for state storage:
import { S3StateStore } from "alchemy/aws";
const app = await alchemy("my-app", { stage: "prod", phase: process.argv.includes("--destroy") ? "destroy" : "up", stateStore: (scope) => new S3StateStore(scope, { bucketName: "my-app-alchemy-state", region: "us-east-1" })});
Configuration Options
Section titled “Configuration Options”Bucket Name and Region
Section titled “Bucket Name and Region”Specify the S3 bucket and AWS region for state storage:
import { S3StateStore } from "alchemy/aws";
const app = await alchemy("my-app", { stateStore: (scope) => new S3StateStore(scope, { bucketName: "my-company-alchemy-state", region: "us-west-2" })});
Custom Prefix
Section titled “Custom Prefix”Use a prefix to organize state files when sharing buckets across projects:
import { S3StateStore } from "alchemy/aws";
const app = await alchemy("my-app", { stateStore: (scope) => new S3StateStore(scope, { bucketName: "shared-alchemy-state", prefix: "my-team/my-app/", region: "us-east-1" })});
Prerequisites
Section titled “Prerequisites”Create S3 Bucket
Section titled “Create S3 Bucket”The S3 bucket must exist before using S3StateStore. Use the Alchemy bootstrap command (recommended) or create it manually:
# Recommended: Use Alchemy bootstrapalchemy bootstrap s3
# Or create manually with AWS CLIaws s3 mb s3://my-app-alchemy-state --region us-east-1
Configure AWS Credentials
Section titled “Configure AWS Credentials”Ensure AWS credentials are configured via:
- AWS credentials file (
~/.aws/credentials
) - Environment variables (
AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
) - IAM roles (for EC2/Lambda)
- AWS CLI profile
The credentials need S3 permissions for the target bucket:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-app-alchemy-state", "arn:aws:s3:::my-app-alchemy-state/*" ] } ]}
State Organization
Section titled “State Organization”S3StateStore organizes state files using scope-based prefixes:
my-app-alchemy-state/ alchemy/my-app/dev/ my-resource my-other-resource alchemy/my-app/prod/ my-resource my-other-resource
Keys containing forward slashes are converted to colons for S3 compatibility:
- Resource key:
api/database/connection
- S3 object key:
alchemy/my-app/dev/api:database:connection
Environment-Specific Configuration
Section titled “Environment-Specific Configuration”Development
Section titled “Development”Use a development-specific bucket or prefix:
const isDev = process.env.NODE_ENV === "development";
const app = await alchemy("my-app", { stage: isDev ? "dev" : "prod", stateStore: (scope) => new S3StateStore(scope, { bucketName: isDev ? "my-app-dev-state" : "my-app-prod-state", region: "us-east-1" })});
Team Environments
Section titled “Team Environments”Share state across team members with appropriate bucket permissions:
const app = await alchemy("my-app", { stage: "shared", stateStore: (scope) => new S3StateStore(scope, { bucketName: "team-shared-alchemy-state", prefix: `${process.env.USER || "unknown"}/`, region: "us-east-1" })});
Error Handling
Section titled “Error Handling”S3StateStore includes built-in retry logic and proper error handling:
- NoSuchBucket: Clear error message if bucket doesn’t exist
- NoSuchKey: Gracefully handles missing state files
- Network errors: Automatic retry with exponential backoff
- Permissions: Clear AWS permission error messages
Performance Considerations
Section titled “Performance Considerations”- Eventual consistency: S3 provides eventual consistency for state operations
- Batch operations: Uses concurrent requests for multi-key operations
- Network latency: Consider bucket region proximity to your deployment location
- Costs: S3 charges for requests and storage (typically very low for state files)