Skip to content
Open
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: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
"name": "databases-on-aws",
"source": "./plugins/databases-on-aws",
"tags": ["aws", "database", "aurora", "dsql", "serverless", "postgresql"],
"version": "1.3.2"
"version": "1.3.3"
},
{
"category": "deployment",
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/security-scanners.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ jobs:
set +e
semgrep scan --oss-only --verbose --metrics=off --config=r/all \
--max-log-list-entries=0 \
--exclude-rule="bbp-pattern-inject" \
--exclude-rule="ai.generic.detect-generic-ai-anthprop.detect-generic-ai-anthprop" \
--exclude-rule="generic.secrets.security.detected-sonarqube-docs-api-key.detected-sonarqube-docs-api-key" \
--exclude-rule="apex.lang.best-practice.ncino.accessmodifiers.globalaccessmodifiers.global-access-modifiers" \
Expand Down
5 changes: 5 additions & 0 deletions .semgrep.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

# Excluded rules:
#
# bbp-pattern-inject
# Reason: Broken rule in the community registry (r/all) - fails to parse
# ("Invalid pattern for Python: Stdlib.Parsing.Parse_error"), which makes
# semgrep exit 2 and fail every PR regardless of findings. Not our rule.
#
# ai.generic.detect-generic-ai-anthprop.detect-generic-ai-anthprop
# Reason: This contains a Claude Code plugin repository - Anthropic references are expected
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ description: >
Evaluate, configure, and migrate workloads to AWS Lambda Managed Instances (LMI).
Triggers on: Lambda Managed Instances, LMI, capacity provider, multi-concurrency Lambda,
dedicated instance Lambda, EC2-backed Lambda, cold start elimination, Graviton Lambda,
instance type for Lambda, Lambda cost optimization with Reserved Instances or Savings Plans.
Also trigger when users describe high-volume predictable workloads seeking cost savings,
instance type for Lambda, scheduled scaling for LMI, Lambda cost optimization with
Reserved Instances or Savings Plans. Also trigger when users describe high-volume
predictable workloads seeking cost savings, want to scale LMI capacity on a schedule,
or compare Lambda vs EC2 for steady-state traffic. For standard Lambda without LMI,
use the aws-lambda skill instead.
argument-hint: "[describe your workload or what you need help with]"
metadata:
tags: lambda, lmi, managed-instances, ec2, capacity-provider, multi-concurrency, cost-optimization
tags: lambda, lmi, managed-instances, ec2, capacity-provider, multi-concurrency, cost-optimization, scheduled-scaling
---

# AWS Lambda Managed Instances (LMI)
Expand All @@ -22,10 +23,10 @@ For standard Lambda development, see [aws-lambda skill](../aws-lambda/). For SAM
## When to Load Reference Files

- **Cost comparison**, **pricing analysis**, **Lambda vs LMI cost**, **Savings Plans**, or **Reserved Instances** -> see [references/cost-comparison.md](references/cost-comparison.md)
- **Instance types**, **memory sizing**, **vCPU ratios**, **scaling tuning**, or **capacity provider config** -> see [references/configuration-guide.md](references/configuration-guide.md)
- **Instance types**, **memory sizing**, **vCPU ratios**, **scaling tuning**, **scheduled scaling**, or **capacity provider config** -> see [references/configuration-guide.md](references/configuration-guide.md)
- **Thread safety**, **concurrency model**, **code review checklist**, **Powertools compatibility**, or **multi-concurrency readiness** -> see [references/thread-safety.md](references/thread-safety.md)
- **Before/after code examples**, **runtime-specific migration** (Node.js, Python, Java, .NET), or **connection pooling** -> see [references/migration-patterns.md](references/migration-patterns.md)
- **IAM roles**, **VPC setup**, **CLI commands**, **SAM template**, or **CDK example** -> see [references/infrastructure-setup.md](references/infrastructure-setup.md) and [scripts/setup-lmi.sh](scripts/setup-lmi.sh)
- **IAM roles**, **VPC setup**, **CLI commands**, **SAM template**, **CDK example**, or **scheduled scaling setup (EventBridge Scheduler)** -> see [references/infrastructure-setup.md](references/infrastructure-setup.md) and [scripts/setup-lmi.sh](scripts/setup-lmi.sh)
- **Errors**, **throttling**, **debugging**, or **stuck deployments** -> see [references/troubleshooting.md](references/troubleshooting.md)

## Quick Decision: Is LMI Right for This Workload?
Expand Down Expand Up @@ -77,6 +78,8 @@ For discount analysis (Savings Plans, Reserved Instances), refer users to the [A

**Scaling**: MinExecutionEnvironments (default 3), MaxVCpuCount (default 400), TargetResourceUtilization.

**Scheduled scaling**: For predictable traffic (business hours, marketing events), use EventBridge Scheduler to adjust Min/Max execution environments on a one-time or recurring schedule — scale up before peak, scale down or to zero when idle.

See [references/configuration-guide.md](references/configuration-guide.md) for decision trees and detailed tuning.

### Step 4: Migrate the Code
Expand Down Expand Up @@ -135,8 +138,10 @@ See [references/infrastructure-setup.md](references/infrastructure-setup.md) for
### Operations

- Do: Set CloudWatch alarms on throttle rate > 1% and CPU > 80%
- Do: Use scheduled scaling (EventBridge Scheduler) for predictable traffic — raise Min/Max before peak periods and lower them (or scale to zero) when idle
- Don't: Manually terminate LMI EC2 instances (delete the capacity provider instead)
- Don't: Forget to publish a version — unpublished functions cannot run on LMI
- Don't: Rely on a deactivated (Min=Max=0) function to self-recover — schedule an explicit scale-up to reactivate it

## Limits Quick Reference

Expand Down Expand Up @@ -172,7 +177,7 @@ REQUIRED: AWS credentials configured on the host machine.

### Regional Availability

Currently available: us-east-1, us-east-2, us-west-2, ap-northeast-1, eu-west-1. Expanding to all commercial regions soon.
Available in all commercial AWS Regions except Israel (Tel Aviv), Middle East (Bahrain), Middle East (UAE), and Asia Pacific (Auckland).

Check the [Lambda Managed Instances documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html) for the latest regional availability.

Expand Down Expand Up @@ -204,12 +209,14 @@ Override: "use SAM" → SAM YAML, "use CloudFormation" → CloudFormation YAML.

### Unsupported Region

- State: "Lambda Managed Instances is not yet available in [region]"
- List available regions
- State: "Lambda Managed Instances is not available in [region]"
- Name the excluded regions: Israel (Tel Aviv), Middle East (Bahrain), Middle East (UAE), Asia Pacific (Auckland)
- Suggest the nearest supported region

## Resources

- [Lambda Managed Instances Docs](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html)
- [Scaling LMI & Scheduled Scaling Docs](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances-scaling.html)
- [Introducing LMI (AWS Blog)](https://aws.amazon.com/blogs/aws/introducing-aws-lambda-managed-instances-serverless-simplicity-with-ec2-flexibility/)
- [Build High-Performance Apps with LMI](https://aws.amazon.com/blogs/compute/build-high-performance-apps-with-aws-lambda-managed-instances/)
- [Migrating Functions to LMI (AWS Blog)](https://aws.amazon.com/blogs/compute/migrating-your-functions-to-aws-lambda-managed-instances/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,26 @@ Total capacity = MinExecutionEnvironments × PerExecutionEnvironmentMaxConcurren
| AllowedInstanceTypes | All | Restrict only for specific hardware needs |
| ExcludedInstanceTypes | None | Exclude expensive types in dev/test |

## Scheduled Scaling (Predictable Traffic)

For workloads with known traffic patterns (business hours, marketing events, batch windows), use [Amazon EventBridge Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-targets-universal.html) to adjust a function's `MinExecutionEnvironments` and `MaxExecutionEnvironments` on a one-time or recurring schedule. A schedule (cron or rate expression) targets the Lambda `PutFunctionScalingConfig` API as an EventBridge Scheduler universal target, passing new Min/Max values in the input payload.

**Behavior:**

- Scheduled scaling sets the provisioned floor and ceiling. Actual scaling between Min and Max still responds to CPU utilization and concurrency saturation.
- If traffic more than doubles within 5 minutes of a scheduled scale-up, you may still see throttles while capacity provisions.
- Setting both `MinExecutionEnvironments` and `MaxExecutionEnvironments` to 0 deactivates the function version (instances terminate). A deactivated function does NOT auto-recover — schedule a separate action with non-zero values to reactivate it.

**Common patterns:**

| Pattern | Scale-up schedule | Scale-down schedule |
| ---------------------- | ----------------------------------- | -------------------------------- |
| Business hours | Raise Min/Max before work starts | Lower Min/Max after hours |
| Marketing/launch event | Raise Min ahead of the campaign | Restore baseline after the event |
| Idle scale-to-zero | Reactivate (non-zero) before demand | Set Min=Max=0 when idle |

See [infrastructure-setup.md](infrastructure-setup.md) for the EventBridge Scheduler IAM role and `create-schedule` CLI examples.

## Monitoring Thresholds

- **CPU > 80%**: reduce concurrency or add vCPUs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,83 @@ Resources:
CapacityProviderArn: !GetAtt MyCP.Arn
```

## Scheduled Scaling (EventBridge Scheduler)

For predictable traffic, adjust `MinExecutionEnvironments`/`MaxExecutionEnvironments` on a schedule using [Amazon EventBridge Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-targets-universal.html). The schedule calls the Lambda `PutFunctionScalingConfig` API directly as a universal target — no Lambda code or extra glue required.

### 1. Scheduler execution role

Trust policy (allow EventBridge Scheduler to assume the role):

```json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "scheduler.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}
```

Permissions (call `PutFunctionScalingConfig` on the target function):

```json
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "lambda:PutFunctionScalingConfig",
"Resource": "arn:aws:lambda:*:*:function:my-lmi-function"
}]
}
```

### 2. Create schedules

Scale up before peak (08:00 UTC daily):

```bash
aws scheduler create-schedule \
--name ScaleUpLmi \
--schedule-expression "cron(0 8 * * ? *)" \
--flexible-time-window '{"Mode": "OFF"}' \
--target '{
"Arn": "arn:aws:scheduler:::aws-sdk:lambda:PutFunctionScalingConfig",
"RoleArn": "arn:aws:iam::<account-id>:role/eventbridge-scheduler-role",
"Input": "{\"FunctionName\": \"my-lmi-function\", \"Qualifier\": \"$LATEST.PUBLISHED\", \"FunctionScalingConfig\": {\"MinExecutionEnvironments\": 100, \"MaxExecutionEnvironments\": 1000}}"
}'
```

Scale down after peak (18:00 UTC daily):

```bash
aws scheduler create-schedule \
--name ScaleDownLmi \
--schedule-expression "cron(0 18 * * ? *)" \
--flexible-time-window '{"Mode": "OFF"}' \
--target '{
"Arn": "arn:aws:scheduler:::aws-sdk:lambda:PutFunctionScalingConfig",
"RoleArn": "arn:aws:iam::<account-id>:role/eventbridge-scheduler-role",
"Input": "{\"FunctionName\": \"my-lmi-function\", \"Qualifier\": \"$LATEST.PUBLISHED\", \"FunctionScalingConfig\": {\"MinExecutionEnvironments\": 5, \"MaxExecutionEnvironments\": 20}}"
}'
```

Set both values to `0` to deactivate during idle periods; schedule a separate non-zero action to reactivate (a deactivated function does not auto-recover).

### Manual override

Update scaling limits directly at any time:

```bash
aws lambda put-function-scaling-config \
--function-name my-lmi-function \
--qualifier '$LATEST.PUBLISHED' \
--function-scaling-config MinExecutionEnvironments=5,MaxExecutionEnvironments=20
```

`MinExecutionEnvironments` and `MaxExecutionEnvironments` accept values from 0 to 15000 and must be set together. Setting them on `$LATEST.PUBLISHED` propagates to future published versions.

## Cleanup

```bash
Expand Down
2 changes: 1 addition & 1 deletion plugins/databases-on-aws/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@
"license": "Apache-2.0",
"name": "databases-on-aws",
"repository": "https://github.com/awslabs/agent-plugins",
"version": "1.3.2"
"version": "1.3.3"
}
2 changes: 1 addition & 1 deletion plugins/databases-on-aws/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "databases-on-aws",
"version": "1.3.2",
"version": "1.3.3",
"description": "Expert database guidance for the AWS database portfolio. Design schemas, execute queries, handle migrations, and choose the right database for your workload.",
"author": {
"name": "Amazon Web Services",
Expand Down
2 changes: 1 addition & 1 deletion plugins/databases-on-aws/skills/dsql/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ See [scripts/README.md](../../scripts/README.md) for usage and hook configuratio
- MUST include tenant_id in all tables
- MUST use `CREATE INDEX ASYNC` exclusively
- MUST issue each DDL in its own transact call: `transact(["CREATE TABLE ..."])`
- MUST serialize arrays as JSONB; expand at query time with `jsonb_array_elements_text(data)`
- MUST serialize arrays into a single-column representation — DSQL has no array column type; PREFER `JSONB` (operators work directly); MAY use `TEXT` when the column is opaque to the database; ASK the user. For `JSONB` arrays, expand at query time with `jsonb_array_elements_text(data)`

### Workflow 2: Safe Data Migration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ effortless scaling, multi-region viability, among other advantages.
- **REQUIRED: Follow DDL Guidelines** - Refer to [DDL Rules](#schema-ddl-rules)
- **SHALL repeatedly generate fresh tokens** - Refer to [Connection Limits](auth/authentication-guide.md#connection-rules)
- **ALWAYS use ASYNC indexes** - `CREATE INDEX ASYNC` is mandatory
- **MUST serialize arrays as JSONB** - see [Schema Design Rules](#schema-design-rules)
- **MUST serialize arrays** into a single-column representation; **PREFER `JSONB`** (operators work directly); **MAY use `TEXT`** when the column is opaque to the database; **ASK** the user - see [Schema Design Rules](#schema-design-rules)
- **ALWAYS Batch within row limit** - maintain transaction limits (verify via `awsknowledge`: `aurora dsql transaction limits`)
- **REQUIRED: Build and sanitize all SQL with `safe_query.build()`** - See [Input Validation](../mcp/tools/input-validation.md#required-pattern)
- **MUST follow correct Application Layer Patterns** - when multi-tenant isolation or application referential integrity are required; refer to [Application Layer Patterns](#application-layer-patterns)
Expand Down Expand Up @@ -54,7 +54,14 @@ effortless scaling, multi-region viability, among other advantages.
### Schema Design Rules

- MUST verify column types via `awsknowledge`: `aurora dsql supported data types` or the [DSQL supported data types list](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types.html)
- MUST serialize arrays as JSONB; expand at query time via `jsonb_array_elements_text(data)`
- MUST serialize arrays into a single-column representation — DSQL has no array column type:
- **PREFER `JSONB`** — `@>`, `?`, `?|`, `?&`, and `jsonb_array_elements_text(data)` work directly; values validated and normalized at write
- **MAY use `TEXT`** when the column is opaque to the database (application reads the whole value, parses it, never queries inside)
- For document columns:
- **`JSONB`** when querying with `@>`, `?`, or indexed JSONB paths
- **`JSON`** when writes dominate (no parse/sort overhead), when byte-exact input matters (audit, replay, payloads with duplicate keys), or when only `->`/`->>` is needed
- **SHOULD keep** existing `JSON` columns as `JSON` when migrating; **MAY upgrade to `JSONB`** if the application needs JSONB-only operators or indexed paths
- ASK the user about query patterns and read/write ratio before defaulting
- **MUST NOT** add per-column `COLLATE` clauses — DSQL uses C collation database-wide and rejects `COLLATE "C"` in DDL. `dsql_lint(fix=true)` auto-strips `COLLATE` clauses from migrated schemas (rule `collation`, fix status `fixed`).
- ALWAYS include tenant_id in tables for multi-tenant isolation
- SHOULD create async indexes for tenant_id and common query patterns
Expand Down Expand Up @@ -127,7 +134,7 @@ UPDATE table SET c = 'default' WHERE c IS NULL; ← AFTER ADD COLUMN

**MUST verify** column types against the [DSQL supported data types docs](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types.html) or via `awsknowledge`: `aurora dsql supported data types` — the supported set evolves, so do not treat any static list as exhaustive.

Arrays and `INET` are **[runtime-only](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types.html#working-with-postgresql-compatibility-query-runtime)** — cast at query time. For structured data, prefer `JSONB` over `JSON` for queryable fields.
Arrays and `INET` are **[runtime-only](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types.html#working-with-postgresql-compatibility-query-runtime)** — cast at query time. For structured data, **PREFER `JSONB`** when querying inside the value (`@>`, `?`, indexed JSONB paths); `JSON` is valid when writes dominate, byte-exact input matters, or only `->`/`->>` is needed. ASK the user about query patterns before defaulting.

### Supported Key

Expand Down
Loading