Skip to content
Merged
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
37 changes: 31 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ This repository contains a collection of AI skills designed to help developers w

| Skill | Description |
|-------|-------------|
| [localstack-lifecycle](skills/localstack-lifecycle/) | Manage LocalStack container lifecycle (start, stop, status, restart) |
| [iac-deployment](skills/iac-deployment/) | Deploy infrastructure using Terraform, CDK, CloudFormation, and Pulumi |
| [state-management](skills/state-management/) | Save, load, and manage LocalStack state with Cloud Pods |
| [localstack-lifecycle](skills/localstack-lifecycle/) | Manage the emulator lifecycle with `lstk` (start, stop, status, restart, reset) |
| [iac-deployment](skills/iac-deployment/) | Deploy infrastructure using Terraform, CDK, CloudFormation, SAM, and Pulumi |
| [state-management](skills/state-management/) | Save, load, and manage LocalStack state with snapshots and Cloud Pods |
| [logs-analysis](skills/logs-analysis/) | Analyze LocalStack logs, identify errors, and debug issues |
| [iam-policy-analyzer](skills/iam-policy-analyzer/) | Analyze IAM policies and auto-generate least-privilege permissions |
| [localstack-extensions](skills/localstack-extensions/) | Manage LocalStack extensions and plugins |
| [localstack-extensions](skills/localstack-extensions/) | Manage LocalStack extensions and plugins (legacy CLI) |

## Installation

Expand All @@ -28,9 +28,34 @@ claude plugin install localstack@localstack-dev

## Prerequisites

- [LocalStack](https://docs.localstack.cloud/getting-started/installation/) installed and configured
- [AWS CLI](https://aws.amazon.com/cli/) or [awslocal](https://docs.localstack.cloud/user-guide/integrations/aws-cli/#localstack-aws-cli-awslocal) wrapper
- Docker running on your machine
- A [LocalStack account](https://app.localstack.cloud/) and auth token
- The [`lstk` CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/), the current LocalStack CLI:

```bash
# Homebrew (macOS/Linux)
brew install localstack/tap/lstk

# npm
npm install -g @localstack/lstk

# Authenticate
lstk login
```

- The tools you want `lstk` to proxy, on your `PATH`: [AWS CLI](https://aws.amazon.com/cli/), `terraform`, `cdk`, or `sam`. `lstk aws`, `lstk terraform`, `lstk cdk`, and `lstk sam` point them at LocalStack for you, replacing the `awslocal`, `tflocal`, `cdklocal`, and `samlocal` wrappers.

### Optional extra CLIs

The `lstk` CLI does not cover every workflow yet. Install these only if you need them:

| Tool | Install | Needed for |
|------|---------|-----------|
| `pulumilocal` | `pip install pulumi-local` | Pulumi deployments — `lstk` has no Pulumi proxy |
| `samlocal` | `pip install aws-sam-cli-local` | Image/container-based Lambda (ECR) deploys and nested CloudFormation stacks, which `lstk sam` does not support |
| legacy `localstack` CLI | `pip install localstack` | LocalStack Extensions, and the `localstack aws iam stream` / `summary` policy generators |

The legacy `localstack` CLI is deprecated and will be removed in a future version — use it only for the gaps listed above. It manages its own container, so stop one CLI's emulator before starting the other's.

## Usage

Expand Down
119 changes: 82 additions & 37 deletions skills/iac-deployment/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,63 @@
---
name: localstack-deploy
description: Deploy infrastructure to LocalStack using IaC tools. Use when users want to deploy Terraform, CDK, CloudFormation, or Pulumi to LocalStack, or need help configuring tflocal, cdklocal, pulumilocal, or awslocal wrappers.
description: Deploy infrastructure to LocalStack using IaC tools. Use when users want to deploy Terraform, CDK, CloudFormation, SAM, or Pulumi to LocalStack, or need help with the lstk proxy commands (lstk terraform, lstk cdk, lstk sam, lstk aws) or the pulumilocal wrapper.
---

# Infrastructure as Code Deployment

Deploy AWS infrastructure to LocalStack using popular IaC tools including Terraform, AWS CDK, CloudFormation, and Pulumi.
Deploy AWS infrastructure to LocalStack using popular IaC tools including Terraform, AWS CDK, CloudFormation, SAM, and Pulumi.

## Capabilities

- Deploy Terraform configurations to LocalStack
- Run AWS CDK deployments locally
- Deploy CloudFormation stacks
- Build and deploy AWS SAM applications
- Execute Pulumi programs against LocalStack
- Validate infrastructure before deployment

## Prerequisites

- The `lstk` CLI installed and the emulator running (`lstk start`) — see the `localstack` skill
- The underlying tool on your `PATH`: `terraform`, `cdk`, `sam`, or `aws`. `lstk` proxies them; it does not bundle them.

`lstk` replaces the old `awslocal` / `tflocal` / `cdklocal` / `samlocal` wrappers — you no longer need to `pip install`/`npm install` them. Pulumi is the exception; see [Pulumi](#pulumi).

## Terraform

### Using tflocal (Preferred)
### Using `lstk terraform` (Preferred)

`lstk terraform` (alias `lstk tf`) runs Terraform against LocalStack by generating a provider-override file, so your `.tf` files need no LocalStack-specific changes.

```bash
lstk terraform init
lstk terraform plan
lstk terraform apply -auto-approve
lstk terraform destroy -auto-approve

# Short alias
lstk tf apply -auto-approve
```

The `tflocal` wrapper is the preferred way to deploy Terraform configurations to LocalStack. It automatically configures all AWS provider endpoints to point to LocalStack, requiring no changes to your Terraform files.
`lstk`-specific flags go **before** the Terraform subcommand:

```bash
# Install tflocal wrapper
pip install terraform-local

# Use tflocal instead of terraform - no provider changes needed
tflocal init
tflocal plan
tflocal apply -auto-approve
tflocal destroy -auto-approve
lstk terraform --region us-west-2 plan
lstk terraform --account 000000000000 apply
```

| Flag | Default | Notes |
|------|---------|-------|
| `--region <region>` | `us-east-1` | Falls back to `AWS_REGION` |
| `--account <id>` | `test` | 12 digits; falls back to `AWS_ACCESS_KEY_ID` |

Useful environment variables: `AWS_ENDPOINT_URL`, `LSTK_TF_CMD` (binary name, default `terraform`), `LSTK_TF_OVERRIDE_FILE_NAME` (default `localstack_providers_override.tf`), `LSTK_TF_DRY_RUN`.

`lstk terraform` targets the AWS emulator only.

### Manual Provider Configuration (Fallback)

Only use manual provider configuration if `tflocal` cannot be installed (e.g., Python/pip is not available in the environment). This approach requires modifying your Terraform files:
Only use manual provider configuration if `lstk` cannot be used (for example, a CI image that only has `terraform`). This approach requires modifying your Terraform files:

```hcl
# In your provider configuration:
Expand All @@ -60,59 +83,76 @@ Note: When using manual configuration, you must list endpoints for each AWS serv

## AWS CDK

### Setup
Requires AWS CDK CLI `2.177.0` or newer.

```bash
# Install cdklocal wrapper
npm install -g aws-cdk-local aws-cdk

# Bootstrap (first time only)
cdklocal bootstrap
```

### Deploy
lstk cdk bootstrap

```bash
# Deploy all stacks
cdklocal deploy --all --require-approval never
lstk cdk deploy --all --require-approval never

# Deploy a specific stack
lstk cdk deploy MyStack

# Deploy specific stack
cdklocal deploy MyStack
# Synthesize
lstk cdk synth

# Destroy
cdklocal destroy --all --force
lstk cdk destroy --all --force
```

`lstk cdk` accepts `--region <region>` (default `us-east-1`) before the CDK command. There is no `--account` flag — CDK always targets the default account `000000000000`.

Useful environment variables: `AWS_ENDPOINT_URL`, `AWS_ENDPOINT_URL_S3`, `LSTK_CDK_CMD` (default `cdk`), `AWS_REGION`.

## CloudFormation

### Deploy with awslocal
Use `lstk aws`, which proxies the host `aws` CLI with the endpoint, credentials, and region pre-configured.

```bash
# Create stack
awslocal cloudformation create-stack \
lstk aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml

# Update stack
awslocal cloudformation update-stack \
lstk aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://template.yaml

# Delete stack
awslocal cloudformation delete-stack --stack-name my-stack
lstk aws cloudformation delete-stack --stack-name my-stack

# Describe stack
awslocal cloudformation describe-stacks --stack-name my-stack
lstk aws cloudformation describe-stacks --stack-name my-stack
```

If you would rather use the plain `aws` CLI, run `lstk setup aws` once to write a `localstack` profile into `~/.aws/config` and `~/.aws/credentials`, then use `aws --profile localstack ...`.

## AWS SAM

Requires AWS SAM CLI `1.95.0` or newer.

```bash
lstk sam build
lstk sam validate
lstk sam deploy
lstk sam --region us-west-2 deploy
```

`lstk sam` accepts `--region <region>` (default `us-east-1`) and `--account <id>` (default `000000000000`) before the SAM command.

**Limitation:** image/container-based Lambda (ECR) deploys and nested CloudFormation stacks are not supported by `lstk sam`. For those workflows, install the `samlocal` wrapper (`pip install aws-sam-cli-local`) and use it instead.

## Pulumi

### Using pulumilocal (Preferred)
`lstk` has no Pulumi proxy command, so Pulumi still needs the `pulumilocal` wrapper.

The `pulumilocal` wrapper is the preferred way to deploy Pulumi programs to LocalStack. It automatically configures AWS endpoints, requiring no changes to your Pulumi configuration.
### Using `pulumilocal` (Preferred)

```bash
# Install pulumilocal wrapper
# Requires Python/pip — this is an extra install beyond lstk
pip install pulumi-local

# Use pulumilocal instead of pulumi - no config changes needed
Expand Down Expand Up @@ -140,9 +180,14 @@ pulumi up --yes
pulumi destroy --yes
```

## Endpoint Resolution

`lstk aws`, `lstk terraform`, `lstk cdk`, and `lstk sam` probe whether `localhost.localstack.cloud` resolves to `127.0.0.1` and use it when it does; otherwise they fall back to `127.0.0.1:4566`. Override with the `LOCALSTACK_HOST` environment variable.

## Best Practices

- Use wrapper tools (`tflocal`, `cdklocal`, `awslocal`) for simplified configuration
- Use the `lstk` proxy commands (`lstk terraform`, `lstk cdk`, `lstk sam`, `lstk aws`) rather than editing endpoints into your IaC files
- Test infrastructure changes locally before deploying to AWS
- Use `PERSISTENCE=1` to retain state across LocalStack restarts
- Leverage Cloud Pods to save/restore infrastructure state
- Use `lstk start --persist` to retain state across LocalStack restarts
- Snapshot deployed infrastructure with `lstk save` so you can restore it instantly instead of re-deploying — see the `localstack-state` skill
- In CI, add `--non-interactive` to `lstk` commands and set `LOCALSTACK_AUTH_TOKEN`
74 changes: 53 additions & 21 deletions skills/iam-policy-analyzer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,32 @@ Analyze IAM policies, detect permission violations, and automatically generate l

## Prerequisites

IAM enforcement requires LocalStack Pro:

```bash
export LOCALSTACK_AUTH_TOKEN=<your-token>
```
- The `lstk` CLI, authenticated with a LocalStack account (`lstk login`, or `LOCALSTACK_AUTH_TOKEN` in CI) — see the `localstack` skill
- Optional: the legacy `localstack` CLI (`pip install localstack`) for the IAM policy stream — see [Auto-Generate Policies](#auto-generate-policies). `lstk` has no equivalent command yet.

## IAM Enforcement Modes

### Enable Enforcement

`lstk` forwards host environment variables prefixed with `LOCALSTACK_`, so `ENFORCE_IAM` is set as `LOCALSTACK_ENFORCE_IAM`:

```bash
# Soft mode - logs violations but allows requests
ENFORCE_IAM=soft localstack start -d
LOCALSTACK_ENFORCE_IAM=soft lstk start

# Enforced mode - denies unauthorized requests
ENFORCE_IAM=1 localstack start -d
LOCALSTACK_ENFORCE_IAM=1 lstk start
```

To make enforcement the default for a project, use an environment profile in `config.toml` (keys inside a profile need no prefix):

```toml
[[containers]]
type = "aws"
env = ["iam"]

[env.iam]
ENFORCE_IAM = "soft"
```

### Configuration
Expand All @@ -45,17 +55,19 @@ ENFORCE_IAM=1 localstack start -d

## Creating IAM Resources

`lstk aws` proxies the host `aws` CLI with the LocalStack endpoint, credentials, and region pre-configured.

### Create a User with Policy

```bash
# Create user
awslocal iam create-user --user-name dev-user
lstk aws iam create-user --user-name dev-user

# Create access key
awslocal iam create-access-key --user-name dev-user
lstk aws iam create-access-key --user-name dev-user

# Attach policy
awslocal iam attach-user-policy \
lstk aws iam attach-user-policy \
--user-name dev-user \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
```
Expand All @@ -64,11 +76,13 @@ awslocal iam attach-user-policy \

```bash
# Create policy from JSON file
awslocal iam create-policy \
lstk aws iam create-policy \
--policy-name my-custom-policy \
--policy-document file://policy.json
```

# Example policy.json
```json
// Example policy.json
{
"Version": "2012-10-17",
"Statement": [
Expand All @@ -93,26 +107,42 @@ awslocal iam create-policy \
3. Check logs for access denied messages

```bash
# View IAM-related log entries
localstack logs | grep -i "access denied"
localstack logs | grep -i "iam"
# View IAM-related log entries (-v disables lstk's default log filtering)
lstk logs -v | grep -i "access denied"
lstk logs -v | grep -i "iam"
```

### Auto-Generate Policies

Based on access patterns observed in soft mode, create least-privilege policies:
The legacy `localstack` CLI can print the exact policy each request would need, which is far more reliable than reading logs. There is no `lstk` equivalent yet, so install the legacy CLI alongside `lstk` for this workflow:

```bash
pip install localstack

# Live stream of recommended policies as requests come in
localstack aws iam stream
localstack aws iam stream --format json

# Aggregate summary of policies for all enforced requests
localstack aws iam summary
```

Workflow:

1. Start with `LOCALSTACK_ENFORCE_IAM=soft lstk start`
2. Run `localstack aws iam stream` in a second terminal
3. Exercise your application
4. Collect the recommended statements and merge them into a minimal policy

1. Run application with `ENFORCE_IAM=soft`
2. Collect all accessed resources and actions from logs
3. Generate minimal policy covering observed access
If the legacy CLI is not available, fall back to reading `lstk logs -v` for access-denied entries and building the policy from the observed actions and resources.

## Testing Policies

### Simulate Policy

```bash
# Test if action would be allowed
awslocal iam simulate-principal-policy \
lstk aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::000000000000:user/dev-user \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::my-bucket/file.txt
Expand All @@ -122,15 +152,17 @@ awslocal iam simulate-principal-policy \

```bash
# Check policy syntax
awslocal accessanalyzer validate-policy \
lstk aws accessanalyzer validate-policy \
--policy-document file://policy.json \
--policy-type IDENTITY_POLICY
```

## Best Practices

- Start with soft enforcement to discover required permissions
- Use `localstack aws iam stream` rather than log grepping when generating policies
- Use least-privilege principles when creating policies
- Test policies locally before deploying to AWS
- Snapshot a known-good IAM setup with `lstk save` so you can restore it after experiments
- Regularly audit and refine policies based on actual usage
- Use IAM roles instead of users where possible
Loading