diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..a0322f1 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,25 @@ +name: Validate Agent Plugin + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Install uv + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + version: "0.11.16" + + - name: Validate portable plugin and skills + run: ./scripts/validate.sh diff --git a/README.md b/README.md index 15b4257..dac4681 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,44 @@ -# LocalStack AI Skills +# LocalStack Agent Skills -AI Agent Skills for developing and testing cloud applications against [LocalStack](https://localstack.cloud) - the local cloud development platform. +Portable [Agent Skills](https://agentskills.io/) for developing and testing cloud applications with [LocalStack](https://localstack.cloud) through the [`lstk`](https://github.com/localstack/lstk) CLI. -## Overview +This repository is a skills-only [Agent Plugin](https://agent-plugins.org/) targeting the Agent Plugins v1.0.0 specification. It intentionally does not include `mcp.json`; LocalStack MCP integration is separate follow-up work. -This repository contains a collection of AI skills designed to help developers work more efficiently with LocalStack. These skills enable AI assistants to help with common LocalStack workflows, from managing the local environment to deploying infrastructure and analyzing logs. - -## Available Skills +## Available skills | 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 | -| [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](skills/localstack/) | Start, stop, configure, and troubleshoot LocalStack emulators with `lstk` | +| [localstack-deploy](skills/localstack-deploy/) | Deploy and verify infrastructure through the `lstk` Terraform, CDK, SAM, and AWS CLI proxies | +| [localstack-state](skills/localstack-state/) | Save, load, inspect, and manage LocalStack snapshots and persistent state | +| [localstack-logs](skills/localstack-logs/) | Inspect emulator logs and diagnose AWS API or Lambda failures | +| [localstack-iam](skills/localstack-iam/) | Test IAM enforcement and derive least-privilege policies from observed behavior | +| [localstack-extensions](skills/localstack-extensions/) | Use and author Git-style `lstk-` CLI extensions | + +## Use as an Agent Plugin + +Clone the repository and point a compatible client's local-plugin workflow at the repository root: + +```bash +git clone https://github.com/localstack/skills.git +``` + +The client discovers the root `plugin.json` and each immediate child of `skills/`. Agent Plugins v1 standardizes the package, but intentionally leaves installation and distribution commands to each client. See the [compatible clients](https://agent-plugins.org/compatible-clients) page for client-specific instructions. + +This step only prepares a locally loadable skills package. Marketplace publication and bundled MCP configuration are deliberately out of scope. + +## Install individual Agent Skills + +Clients supported by the Agent Skills CLI can install the collection or select individual skills: + +```bash +npx skills add https://github.com/localstack/skills +npx skills add https://github.com/localstack/skills --skill localstack-deploy +``` -## Installation +## Install with Claude Code -### Via the LocalStack standalone marketplace +The existing Claude marketplace compatibility layer remains available: ```bash claude plugin marketplace add localstack/skills @@ -28,20 +47,46 @@ 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 +- [`lstk`](https://github.com/localstack/lstk#installation) +- A Docker-API-compatible container runtime supported by `lstk` +- A LocalStack account and `LOCALSTACK_AUTH_TOKEN` for workflows that require authentication +- The standard AWS, Terraform, CDK, or SAM CLI when using the corresponding proxy skill + +## Validate locally -## Usage +Validation requires [`uv`](https://docs.astral.sh/uv/), Git, and network access to PyPI, GitHub, and `agent-plugins.org`. The script validates `plugin.json` against the canonical Agent Plugins schema and validates every skill with a pinned revision of the official `skills-ref` implementation: + +```bash +./scripts/validate.sh +``` -These skills are designed to be used with AI coding assistants that support the skills/commands interface. Each skill provides contextual guidance and commands for specific LocalStack workflows. +If Claude Code is installed, also validate the compatibility package: + +```bash +claude plugin validate --strict . +``` + +## Package layout + +```text +. +├── plugin.json +├── skills/ +│ └── / +│ └── SKILL.md +├── .claude-plugin/ +│ ├── plugin.json +│ └── marketplace.json +└── scripts/ + └── validate.sh +``` -## Related Projects +## Related projects -- [LocalStack](https://github.com/localstack/localstack) - The core LocalStack platform -- [LocalStack MCP Server](https://github.com/localstack/localstack-mcp-server) - Model Context Protocol server for LocalStack -- [LocalStack Documentation](https://docs.localstack.cloud/) +- [lstk](https://github.com/localstack/lstk) +- [LocalStack MCP Server](https://github.com/localstack/localstack-mcp-server) +- [LocalStack documentation](https://docs.localstack.cloud/) ## License -Apache License 2.0 - see [LICENSE](LICENSE) for details. +Apache License 2.0 — see [LICENSE](LICENSE). diff --git a/plugin.json b/plugin.json new file mode 100644 index 0000000..1d85df0 --- /dev/null +++ b/plugin.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", + "name": "localstack", + "version": "1.0.0", + "description": "Portable agent skills for developing and testing cloud applications with LocalStack through lstk.", + "author": { + "name": "LocalStack" + }, + "homepage": "https://github.com/localstack/skills", + "repository": "https://github.com/localstack/skills", + "license": "Apache-2.0", + "keywords": [ + "localstack", + "cloud", + "aws", + "azure", + "snowflake", + "iac", + "terraform", + "cdk", + "testing", + "local-development" + ] +} diff --git a/scripts/validate.sh b/scripts/validate.sh new file mode 100755 index 0000000..1bda919 --- /dev/null +++ b/scripts/validate.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +plugin_schema="https://agent-plugins.org/schemas/1.0.0/plugin.schema.json" +check_jsonschema_version="0.37.4" +skills_ref_revision="217be548739f21d6008915c29aefe320ea1a90af" +skills_ref_source="git+https://github.com/agentskills/agentskills.git@${skills_ref_revision}#subdirectory=skills-ref" + +if ! command -v uvx >/dev/null 2>&1; then + echo "uvx is required; install uv from https://docs.astral.sh/uv/" >&2 + exit 1 +fi + +echo "Validating plugin.json" +uvx --from "check-jsonschema==${check_jsonschema_version}" check-jsonschema \ + --schemafile "$plugin_schema" \ + "$repo_root/plugin.json" + +skill_count=0 +for skill_dir in "$repo_root"/skills/*; do + [[ -d "$skill_dir" ]] || continue + if [[ ! -f "$skill_dir/SKILL.md" ]]; then + echo "missing SKILL.md in $skill_dir" >&2 + exit 1 + fi + + echo "Validating ${skill_dir#"$repo_root/"}" + uvx --from "$skills_ref_source" skills-ref validate "$skill_dir" + ((skill_count += 1)) +done + +if (( skill_count == 0 )); then + echo "no skills found under $repo_root/skills" >&2 + exit 1 +fi + +echo "Validated plugin.json and $skill_count skills" diff --git a/skills/iac-deployment/SKILL.md b/skills/iac-deployment/SKILL.md deleted file mode 100644 index a0ce91a..0000000 --- a/skills/iac-deployment/SKILL.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -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. ---- - -# Infrastructure as Code Deployment - -Deploy AWS infrastructure to LocalStack using popular IaC tools including Terraform, AWS CDK, CloudFormation, and Pulumi. - -## Capabilities - -- Deploy Terraform configurations to LocalStack -- Run AWS CDK deployments locally -- Deploy CloudFormation stacks -- Execute Pulumi programs against LocalStack -- Validate infrastructure before deployment - -## Terraform - -### Using tflocal (Preferred) - -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. - -```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 -``` - -### 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: - -```hcl -# In your provider configuration: -provider "aws" { - access_key = "test" - secret_key = "test" - region = "us-east-1" - - endpoints { - s3 = "http://localhost:4566" - dynamodb = "http://localhost:4566" - lambda = "http://localhost:4566" - # Add other services as needed - } - - skip_credentials_validation = true - skip_metadata_api_check = true - skip_requesting_account_id = true -} -``` - -Note: When using manual configuration, you must list endpoints for each AWS service used in your configuration. - -## AWS CDK - -### Setup - -```bash -# Install cdklocal wrapper -npm install -g aws-cdk-local aws-cdk - -# Bootstrap (first time only) -cdklocal bootstrap -``` - -### Deploy - -```bash -# Deploy all stacks -cdklocal deploy --all --require-approval never - -# Deploy specific stack -cdklocal deploy MyStack - -# Destroy -cdklocal destroy --all --force -``` - -## CloudFormation - -### Deploy with awslocal - -```bash -# Create stack -awslocal cloudformation create-stack \ - --stack-name my-stack \ - --template-body file://template.yaml - -# Update stack -awslocal cloudformation update-stack \ - --stack-name my-stack \ - --template-body file://template.yaml - -# Delete stack -awslocal cloudformation delete-stack --stack-name my-stack - -# Describe stack -awslocal cloudformation describe-stacks --stack-name my-stack -``` - -## Pulumi - -### Using pulumilocal (Preferred) - -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. - -```bash -# Install pulumilocal wrapper -pip install pulumi-local - -# Use pulumilocal instead of pulumi - no config changes needed -pulumilocal preview -pulumilocal up --yes -pulumilocal destroy --yes -``` - -### Manual Configuration (Fallback) - -Only use manual configuration if `pulumilocal` cannot be installed (e.g., Python/pip is not available in the environment): - -```bash -# Configure Pulumi for LocalStack -pulumi config set aws:accessKey test -pulumi config set aws:secretKey test -pulumi config set aws:region us-east-1 -pulumi config set aws:endpoints '[{"s3":"http://localhost:4566"}]' -``` - -```bash -# Deploy with standard pulumi commands -pulumi preview -pulumi up --yes -pulumi destroy --yes -``` - -## Best Practices - -- Use wrapper tools (`tflocal`, `cdklocal`, `awslocal`) for simplified configuration -- 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 diff --git a/skills/iam-policy-analyzer/SKILL.md b/skills/iam-policy-analyzer/SKILL.md deleted file mode 100644 index de1030a..0000000 --- a/skills/iam-policy-analyzer/SKILL.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -name: localstack-iam -description: Analyze and enforce IAM policies in LocalStack. Use when users want to enable IAM enforcement, detect permission violations, auto-generate least-privilege policies, or test IAM policies locally before deploying to AWS. ---- - -# IAM Policy Analyzer - -Analyze IAM policies, detect permission violations, and automatically generate least-privilege policies based on actual usage. - -## Capabilities - -- Enforce IAM policies locally -- Detect permission violations -- Auto-generate policies from access patterns -- Analyze existing policies for issues -- Test policies before deploying to AWS - -## Prerequisites - -IAM enforcement requires LocalStack Pro: - -```bash -export LOCALSTACK_AUTH_TOKEN= -``` - -## IAM Enforcement Modes - -### Enable Enforcement - -```bash -# Soft mode - logs violations but allows requests -ENFORCE_IAM=soft localstack start -d - -# Enforced mode - denies unauthorized requests -ENFORCE_IAM=1 localstack start -d -``` - -### Configuration - -| Mode | Behavior | -|------|----------| -| Disabled (default) | No IAM checks | -| `soft` | Logs violations, allows requests | -| `1` / `enforced` | Full enforcement, denies unauthorized | - -## Creating IAM Resources - -### Create a User with Policy - -```bash -# Create user -awslocal iam create-user --user-name dev-user - -# Create access key -awslocal iam create-access-key --user-name dev-user - -# Attach policy -awslocal iam attach-user-policy \ - --user-name dev-user \ - --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess -``` - -### Create Custom Policy - -```bash -# Create policy from JSON file -awslocal iam create-policy \ - --policy-name my-custom-policy \ - --policy-document file://policy.json - -# Example policy.json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:GetObject", - "s3:PutObject" - ], - "Resource": "arn:aws:s3:::my-bucket/*" - } - ] -} -``` - -## Policy Analysis - -### Detect Violations - -1. Enable soft enforcement mode -2. Run your application -3. Check logs for access denied messages - -```bash -# View IAM-related log entries -localstack logs | grep -i "access denied" -localstack logs | grep -i "iam" -``` - -### Auto-Generate Policies - -Based on access patterns observed in soft mode, create least-privilege policies: - -1. Run application with `ENFORCE_IAM=soft` -2. Collect all accessed resources and actions from logs -3. Generate minimal policy covering observed access - -## Testing Policies - -### Simulate Policy - -```bash -# Test if action would be allowed -awslocal 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 -``` - -### Validate Policy - -```bash -# Check policy syntax -awslocal accessanalyzer validate-policy \ - --policy-document file://policy.json \ - --policy-type IDENTITY_POLICY -``` - -## Best Practices - -- Start with soft enforcement to discover required permissions -- Use least-privilege principles when creating policies -- Test policies locally before deploying to AWS -- Regularly audit and refine policies based on actual usage -- Use IAM roles instead of users where possible diff --git a/skills/localstack-deploy/SKILL.md b/skills/localstack-deploy/SKILL.md new file mode 100644 index 0000000..cce2fad --- /dev/null +++ b/skills/localstack-deploy/SKILL.md @@ -0,0 +1,130 @@ +--- +name: localstack-deploy +description: Deploy and verify AWS infrastructure through lstk's Terraform, CDK, SAM, and AWS CLI proxies. Use when running IaC against LocalStack or replacing tflocal, cdklocal, samlocal, and awslocal workflows. +--- + +# Deploy infrastructure through lstk + +Prefer a first-party `lstk` proxy whenever one exists. It injects the LocalStack endpoint, credentials, account, and region while preserving the standard tool's arguments and exit code. + +## Prepare the AWS emulator + +```bash +lstk start --type aws +lstk status +``` + +Install the standard CLI required by the workflow: + +- Terraform or OpenTofu for `lstk terraform` +- AWS CDK 2.177.0 or newer for `lstk cdk` +- AWS SAM CLI 1.95.0 or newer for `lstk sam` +- AWS CLI for `lstk aws` + +Do not install the `tflocal`, `cdklocal`, `samlocal`, or `awslocal` wrappers when `lstk` already covers the workflow. + +## Terraform and OpenTofu + +Run the normal Terraform lifecycle: + +```bash +lstk terraform init +lstk terraform plan +lstk terraform apply +lstk terraform destroy +``` + +Place `lstk`-specific flags before the Terraform action: + +```bash +lstk terraform --region us-west-2 plan +lstk terraform --account 000000000123 apply +``` + +Use OpenTofu without changing the skill workflow: + +```bash +LSTK_TF_CMD=tofu lstk terraform plan +``` + +`lstk` creates a provider override automatically. Do not add hard-coded LocalStack endpoints to the user's Terraform files unless they explicitly need a portable manual configuration. + +## AWS CDK + +```bash +lstk cdk bootstrap +lstk cdk synth +lstk cdk deploy +lstk cdk destroy +``` + +Place the region flag before the action: + +```bash +lstk cdk --region us-west-2 deploy +``` + +CDK always uses LocalStack account `000000000000`; do not invent an `--account` workflow. + +## AWS SAM + +```bash +lstk sam build +lstk sam validate +lstk sam deploy --guided +``` + +Place LocalStack flags before the SAM action: + +```bash +lstk sam --region us-west-2 deploy +``` + +For image/container-based Lambda deployments or nested CloudFormation stacks, check the current `lstk sam` limitations before proceeding; those workflows may still require `samlocal`. + +## CloudFormation through the AWS CLI + +```bash +lstk aws cloudformation create-stack \ + --stack-name my-stack \ + --template-body file://template.yaml + +lstk aws cloudformation describe-stacks \ + --stack-name my-stack + +lstk aws cloudformation update-stack \ + --stack-name my-stack \ + --template-body file://template.yaml + +lstk aws cloudformation delete-stack \ + --stack-name my-stack +``` + +## Pulumi boundary + +`lstk` does not currently provide a Pulumi proxy. Never invent `lstk pulumi`. If the user explicitly needs Pulumi, follow the current LocalStack Pulumi integration or use `pulumilocal`, clearly labeling it as an external fallback. + +## Target an external emulator + +Put the global endpoint before the proxy command: + +```bash +lstk --endpoint-url https://example.localstack.cloud terraform plan +lstk --endpoint-url https://example.localstack.cloud cdk deploy +lstk --endpoint-url https://example.localstack.cloud sam deploy +``` + +The endpoint must identify an AWS emulator for these proxies. + +## Verify the deployment + +Do not stop at a successful IaC exit code. Query the resources that matter: + +```bash +lstk status +lstk aws cloudformation describe-stacks +lstk aws s3 ls +lstk aws lambda list-functions +``` + +Before `apply`, `deploy`, `destroy`, or delete operations, surface the expected changes and obtain any approval the user requires. diff --git a/skills/localstack-extensions/SKILL.md b/skills/localstack-extensions/SKILL.md index 362fd01..458b299 100644 --- a/skills/localstack-extensions/SKILL.md +++ b/skills/localstack-extensions/SKILL.md @@ -1,135 +1,102 @@ --- name: localstack-extensions -description: Manage LocalStack Extensions. Use when users want to install, uninstall, list, or configure LocalStack extensions, or develop custom extensions to extend LocalStack functionality. +description: Use and author Git-style lstk CLI extensions. Use when invoking, discovering, or building an executable whose name starts with lstk-, handling LSTK_EXT_CONTEXT, or distinguishing CLI extensions from in-emulator LocalStack Extensions. --- -# LocalStack Extensions +# Use and author lstk CLI extensions -Manage LocalStack Extensions to add custom functionality, integrate third-party tools, and extend LocalStack capabilities. +`lstk` supports Git-style extensions. An executable named `lstk-` on `PATH` becomes `lstk `. There is no manifest, registry, install command, or registration step. -## Capabilities +This mechanism is different from Python-based LocalStack Extensions that run inside the emulator. -- Install and manage LocalStack Extensions -- Discover available extensions -- Configure extension settings -- Develop custom extensions +## Discover and invoke extensions -## Extension Management - -### List Installed Extensions +List built-in commands and discovered extensions: ```bash -localstack extensions list +lstk --help ``` -### Install Extensions +Locate an extension directly: ```bash -# Install from PyPI -localstack extensions install localstack-extension-name - -# Install specific version -localstack extensions install localstack-extension-name==1.0.0 - -# Install from Git repository -localstack extensions install "git+https://github.com/org/extension-repo.git" +command -v lstk-example ``` -### Uninstall Extensions +Invoke it through `lstk`: ```bash -localstack extensions uninstall localstack-extension-name +lstk example --flag value ``` -### Enable/Disable Extensions - -```bash -# Extensions are enabled by default after installation -# Disable via environment variable -EXTENSION_NAME_ENABLED=0 localstack start -d -``` +Built-in commands and aliases always win. Arguments after the extension name are forwarded verbatim, and the extension's exit code and standard streams pass through. -## Available Extensions +## Install an extension executable -### Community Extensions +1. Obtain or build a trusted executable named `lstk-`. +2. Put it in a directory on `PATH`. +3. Mark it executable on Unix-like systems. +4. Confirm it appears in `lstk --help`. +5. Run a harmless help or version command before allowing state changes. -Check the [LocalStack Extensions Registry](https://docs.localstack.cloud/user-guide/extensions/) for community-contributed extensions. +`lstk` does not sandbox or verify third-party extensions. Do not install or execute an untrusted binary. -## Using Extensions +## Read runtime context -### MailHog Extension +`lstk` supplies: -```bash -# Install -localstack extensions install localstack-extension-mailhog +- `LSTK_EXT_API_VERSION`: breaking-version number for the context contract. +- `LSTK_EXT_CONTEXT`: JSON containing the resolved config directory, optional auth token, output mode, optional telemetry session ID, and running emulators. -# Start LocalStack -localstack start -d +A shell extension can read the AWS endpoint with `jq`: -# Access MailHog UI -open http://localhost:8025 +```sh +context=${LSTK_EXT_CONTEXT:-} +aws_endpoint=$( + printf '%s' "$context" | + jq -r '.emulators[]? | select(.type == "aws") | .endpoint' | + head -n 1 +) -# SES emails will be captured by MailHog -awslocal ses send-email \ - --from sender@example.com \ - --to recipient@example.com \ - --subject "Test" \ - --text "Hello" +if [ -z "$aws_endpoint" ]; then + printf '%s\n' "an AWS emulator is required; run 'lstk start --type aws'" >&2 + exit 1 +fi ``` -## Developing Custom Extensions - -### Extension Structure +Treat the context as runtime input: -``` -my-extension/ -├── setup.py -├── my_extension/ -│ ├── __init__.py -│ └── extension.py -``` +- Check a field's presence instead of inferring it from the API version. +- Use `LSTK_EXT_API_VERSION` only to reject a breaking contract generation. +- Handle an empty `emulators` array. +- Select an emulator by `type`; do not assume only one entry. +- Never print or persist `authToken`. +- Do not prompt when `nonInteractive` is true. +- Emit machine-readable output when choosing to honor `json`. -### Basic Extension +## Author an extension -```python -# extension.py -from localstack.extensions.api import Extension, http +Name the executable `lstk-` and parse only the arguments it owns. A minimal POSIX shell extension: -class MyExtension(Extension): - name = "my-extension" +```sh +#!/usr/bin/env sh +set -eu - def on_extension_load(self): - print("Extension loaded!") +if [ "${LSTK_EXT_API_VERSION:-0}" -gt 1 ]; then + printf '%s\n' "unsupported lstk extension API version" >&2 + exit 1 +fi - def on_platform_start(self): - print("LocalStack is starting!") +if [ -z "${LSTK_EXT_CONTEXT:-}" ]; then + printf '%s\n' "this command must be run through lstk" >&2 + exit 1 +fi - @http.route("/my-endpoint") - def my_endpoint(self, request): - return {"message": "Hello from extension!"} +printf '%s\n' "extension is ready" ``` -### Install Local Extension - -```bash -# Install in development mode -localstack extensions install -e ./my-extension -``` - -## Configuration - -Extensions can be configured via environment variables: - -```bash -# General pattern -EXTENSION__=value localstack start -d - -# Example -EXTENSION_MAILHOG_PORT=8025 localstack start -d -``` +Keep failures actionable and preserve meaningful exit codes. If the extension performs paid or protected work, authorize server-side with the supplied token; a client-side check is not a security boundary. -## Troubleshooting +## Distinguish emulator extensions -- **Extension not loading**: Check `localstack logs` for errors -- **Conflicts**: Disable conflicting extensions -- **Version issues**: Ensure extension is compatible with your LocalStack version +When the user means a Python extension running inside the LocalStack emulator, do not invent commands such as `lstk extensions install`. `lstk` v2 does not manage that system. Use the current [LocalStack Extensions documentation](https://docs.localstack.cloud/aws/configuration/extensions/) or the Extensions Library instead. diff --git a/skills/localstack-iam/SKILL.md b/skills/localstack-iam/SKILL.md new file mode 100644 index 0000000..a0d59e2 --- /dev/null +++ b/skills/localstack-iam/SKILL.md @@ -0,0 +1,118 @@ +--- +name: localstack-iam +description: Test IAM policies and enforcement in LocalStack with lstk. Use when reproducing access denials, enabling soft or enforced IAM evaluation, validating policies, or deriving least-privilege permissions from observed requests. +--- + +# Test IAM policies in LocalStack + +Use the AWS emulator, `lstk aws`, and verbose logs to test real policy behavior. Do not claim that logs automatically generate a complete policy; treat observed actions as evidence for a candidate least-privilege policy. + +IAM enforcement and Policy Stream availability depend on the user's LocalStack plan. + +## Configure enforcement + +Find the active config: + +```bash +lstk config path +``` + +For soft evaluation, reference a profile that enables enforcement without denying requests: + +```toml +[[containers]] +type = "aws" +env = ["iam-soft"] + +[env.iam-soft] +DEBUG = "1" +ENFORCE_IAM = "1" +IAM_SOFT_MODE = "1" +``` + +For enforced mode: + +```toml +[[containers]] +type = "aws" +env = ["iam-enforced"] + +[env.iam-enforced] +DEBUG = "1" +ENFORCE_IAM = "1" +``` + +Restart after changing the profile: + +```bash +lstk restart +``` + +Use soft mode first when discovering required permissions. Use enforced mode when testing that unauthorized calls really fail. + +## Create principals and policies + +```bash +lstk aws iam create-user --user-name dev-user + +lstk aws iam create-policy \ + --policy-name app-policy \ + --policy-document file://policy.json + +lstk aws iam attach-user-policy \ + --user-name dev-user \ + --policy-arn arn:aws:iam::000000000000:policy/app-policy + +lstk aws iam create-access-key --user-name dev-user +``` + +Capture the returned access key and secret without committing them. `lstk aws` respects explicit AWS credential environment variables, so use the created principal for the request under test: + +```bash +AWS_ACCESS_KEY_ID= \ +AWS_SECRET_ACCESS_KEY= \ +lstk aws s3 ls +``` + +## Investigate a denial + +1. Reproduce the request with the intended principal. +2. Inspect the policy-engine and request lines: + +```bash +lstk logs --verbose --tail 500 | grep -i 'denied\|accessdenied\|iam' +``` + +3. Record the principal, action, resource ARN, explicit denies, and missing allows. +4. Update the smallest relevant statement. +5. Re-run the same request with the same credentials. +6. Confirm both the API result and the verbose log. + +An explicit deny always wins. Check identity policies, resource policies, permission boundaries, and service-generated calls before broadening permissions. + +## Validate and simulate policies + +```bash +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 + +lstk aws accessanalyzer validate-policy \ + --policy-document file://policy.json \ + --policy-type IDENTITY_POLICY +``` + +Treat simulator and validator results as additional evidence; still run the application request against enforced mode. + +## Derive least privilege + +1. Start with soft mode and a clean test scenario. +2. Exercise every intended application path. +3. Collect the observed actions and resource ARNs from verbose logs or the LocalStack IAM Policy Stream. +4. Group actions by principal and resource scope. +5. Create a candidate policy with the narrowest useful actions and resources. +6. Switch to enforced mode and run positive and negative tests. +7. Review for wildcard actions, wildcard resources, and permissions not exercised by the scenario. + +The IAM Policy Stream in the LocalStack Web Application can help summarize observed permissions when the user's plan includes it. diff --git a/skills/localstack-lifecycle/SKILL.md b/skills/localstack-lifecycle/SKILL.md deleted file mode 100644 index 6d27137..0000000 --- a/skills/localstack-lifecycle/SKILL.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -name: localstack -description: Manage LocalStack container lifecycle. Use when users need to start, stop, restart, or check status of LocalStack, configure LocalStack environment variables, or troubleshoot LocalStack container issues. ---- - -# LocalStack Lifecycle Management - -Manage the LocalStack container lifecycle including starting, stopping, and monitoring the local cloud environment. - -## Capabilities - -- Start LocalStack with custom configuration -- Stop running LocalStack instances -- Check LocalStack status and health -- Restart LocalStack with new settings -- View LocalStack version and configuration - -## Common Commands - -### Start LocalStack - -```bash -# Basic start -localstack start -d - -# Start with debug mode -DEBUG=1 localstack start -d - -# Start with Pro features (requires auth token) -LOCALSTACK_AUTH_TOKEN= localstack start -d -``` - -### Check Status - -```bash -# Check if LocalStack is running -localstack status - -# Check service health -curl http://localhost:4566/_localstack/health - -# View running Docker container -docker ps | grep localstack -``` - -### Stop LocalStack - -```bash -# Graceful stop -localstack stop - -# Force stop via Docker -docker stop localstack-main -``` - -### View Logs - -```bash -# Follow logs -localstack logs -f - -# View last 100 lines -localstack logs --tail 100 -``` - -## Configuration Options - -Key environment variables for LocalStack: - -| Variable | Description | Default | -|----------|-------------|---------| -| `DEBUG` | Enable debug logging | `0` | -| `PERSISTENCE` | Enable persistence across restarts | `0` | -| `LOCALSTACK_AUTH_TOKEN` | Auth token for Pro features | None | -| `GATEWAY_LISTEN` | Port configuration | `4566` | - -## Troubleshooting - -- **Container won't start**: Check if port 4566 is already in use -- **Services unavailable**: Verify Docker is running and has sufficient resources -- **Auth errors**: Ensure `LOCALSTACK_AUTH_TOKEN` is set for Pro features diff --git a/skills/localstack-logs/SKILL.md b/skills/localstack-logs/SKILL.md new file mode 100644 index 0000000..6f9d763 --- /dev/null +++ b/skills/localstack-logs/SKILL.md @@ -0,0 +1,115 @@ +--- +name: localstack-logs +description: Analyze LocalStack emulator logs with lstk. Use when debugging AWS API errors, Lambda failures, startup problems, IAM denials, request patterns, or service-specific behavior. +--- + +# Analyze LocalStack logs + +Use `lstk logs` so log collection follows the configured emulator and container runtime. + +## Collect the right log view + +```bash +# Recent output +lstk logs --tail 100 + +# Stream new output +lstk logs --follow + +# Include request and provider lines filtered from the default view +lstk logs --verbose --tail 200 +``` + +Use `--verbose` for AWS request analysis; the default view removes routine request/provider noise. + +Filter a captured view when looking for a specific service, request ID, or failure: + +```bash +lstk logs --verbose --tail 500 | grep -i 's3' +lstk logs --verbose --tail 500 | grep -i 'error\|exception' +lstk logs --verbose --tail 500 | grep 'request-id-here' +``` + +Do not assume a fixed underlying container name. + +## Enable detailed emulator logging + +Find the active config: + +```bash +lstk config path +``` + +Attach a debug profile to the active emulator: + +```toml +[[containers]] +type = "aws" +env = ["debug"] + +[env.debug] +DEBUG = "1" +LS_LOG = "trace" +``` + +For Lambda-specific diagnostics, add `LAMBDA_DEBUG = "1"` only when the current LocalStack documentation recommends it for the runtime under investigation. Restart after changing emulator environment: + +```bash +lstk restart +``` + +## Diagnose AWS API failures + +1. Reproduce the failing request once. +2. Capture `lstk logs --verbose --tail 500`. +3. Locate the service and operation, HTTP status, request ID, and the first causal exception. +4. Distinguish an application error from an emulator startup, configuration, or coverage issue. +5. Verify the resource exists with the `lstk aws` proxy. +6. Make the smallest configuration or application change, reproduce, and compare the new logs. + +Common signals include: + +| Signal | Check | +| --- | --- | +| `ResourceNotFoundException` | Confirm resource name, region, and account | +| `AccessDenied` | Inspect IAM enforcement and the request credentials | +| `ValidationException` | Compare request parameters with the AWS API contract | +| Connection refusal or timeout | Check `lstk status`, ports, and readiness | +| Provider exception | Read the first stack trace and check service coverage | + +## Inspect Lambda logs + +First inspect emulator-level failures: + +```bash +lstk logs --verbose --tail 500 | grep -i 'lambda' +``` + +Then query emulated CloudWatch Logs: + +```bash +lstk aws logs describe-log-groups +lstk aws logs describe-log-streams \ + --log-group-name /aws/lambda/my-function \ + --order-by LastEventTime \ + --descending +lstk aws logs get-log-events \ + --log-group-name /aws/lambda/my-function \ + --log-stream-name +``` + +## Check health + +Prefer the configuration-aware status command: + +```bash +lstk status +``` + +For a default local endpoint, inspect the raw health payload only when needed: + +```bash +curl http://localhost:4566/_localstack/health +``` + +`lstk logs` has no external-emulator mode. When using `--endpoint-url`, obtain logs from the system that owns that emulator and use `lstk --endpoint-url status` for reachability. diff --git a/skills/localstack-state/SKILL.md b/skills/localstack-state/SKILL.md new file mode 100644 index 0000000..5eb24df --- /dev/null +++ b/skills/localstack-state/SKILL.md @@ -0,0 +1,116 @@ +--- +name: localstack-state +description: Manage LocalStack state with lstk snapshots and persistent volumes. Use when saving, loading, versioning, sharing, resetting, or reproducing emulator state locally, in Cloud Pods, or in S3. +--- + +# Manage LocalStack state + +Use `lstk snapshot` for explicit checkpoints and `--persist` for automatic state retention. Cloud Pod (`pod:`) operations require a LocalStack plan that includes State Management and a valid authentication token. Local-file and S3 operations run through the emulator and do not require a platform token for the snapshot command. + +## Save and load local snapshots + +```bash +# Save all services to a generated .snapshot file +lstk snapshot save + +# Save to a named file +lstk snapshot save ./baseline.snapshot + +# Save selected services +lstk snapshot save ./payments.snapshot --services s3,sqs,lambda + +# Load; starts the configured emulator when needed +lstk snapshot load ./baseline.snapshot +``` + +`lstk save` and `lstk load` are aliases, but prefer the explicit `lstk snapshot` form in documentation and automation. + +Choose the merge strategy deliberately: + +```bash +# Default: snapshot wins on overlapping service/account/region state +lstk snapshot load ./baseline.snapshot --merge=account-region-merge + +# Replace all running state +lstk snapshot load ./baseline.snapshot --merge=overwrite + +# Merge resources within each service +lstk snapshot load ./baseline.snapshot --merge=service-merge +``` + +Treat `--merge=overwrite` as destructive and obtain confirmation before running it. + +## Work with Cloud Pods + +Use the `pod:` prefix: + +```bash +lstk snapshot save pod:team-baseline +lstk snapshot list +lstk snapshot show pod:team-baseline +lstk snapshot versions pod:team-baseline +lstk snapshot load pod:team-baseline +lstk snapshot load pod:team-baseline:3 +``` + +Every save to an existing pod creates a new version. Preview a pod load without changing state: + +```bash +lstk snapshot load pod:team-baseline --dry-run +``` + +Remove a pod only after explicit confirmation: + +```bash +lstk snapshot remove pod:team-baseline +lstk --non-interactive snapshot remove pod:team-baseline --force +``` + +Removal still contacts a running emulator even though the snapshot is stored on the LocalStack platform. + +## Store snapshots in S3 + +Supply credentials through environment variables, `AWS_PROFILE`, or `--profile`; never put credentials in the URL: + +```bash +lstk snapshot save team-baseline s3://my-bucket/localstack +lstk snapshot list s3://my-bucket/localstack +lstk snapshot load team-baseline s3://my-bucket/localstack +``` + +S3 transfers are performed by the emulator and require one to be reachable. + +## Auto-load a baseline + +Set a Cloud Pod in the active AWS emulator config: + +```toml +[[containers]] +type = "aws" +snapshot = "pod:team-baseline" +``` + +Override or skip it for one start: + +```bash +lstk start --snapshot pod:another-baseline +lstk start --no-snapshot +``` + +## Persist state across restarts + +```bash +lstk start --persist +lstk volume path +``` + +For a persistent default, attach an environment profile with `PERSISTENCE = "1"`. Configuring a volume only chooses where state is stored; it does not enable persistence by itself. + +Treat the following as destructive and get confirmation first: + +```bash +lstk reset +lstk volume clear +``` + +Use a snapshot before destructive experiments when rollback matters. diff --git a/skills/localstack/SKILL.md b/skills/localstack/SKILL.md new file mode 100644 index 0000000..3e73954 --- /dev/null +++ b/skills/localstack/SKILL.md @@ -0,0 +1,112 @@ +--- +name: localstack +description: Manage LocalStack emulators with the lstk v2 CLI. Use when starting, stopping, restarting, configuring, checking, or troubleshooting a LocalStack AWS, Azure, or Snowflake emulator. +--- + +# Manage a LocalStack emulator + +Use `lstk` for emulator lifecycle and configuration. Prefer it over the legacy `localstack` CLI and direct container-runtime commands because `lstk` resolves the configured emulator, runtime, ports, authentication, and output mode. + +## Check prerequisites + +Verify the CLI and container runtime before changing state: + +```bash +lstk --version +lstk status +``` + +If `lstk` is missing, install it from the [lstk repository](https://github.com/localstack/lstk#installation). Do not put authentication tokens in committed files; use `LOCALSTACK_AUTH_TOKEN` or the browser login flow. + +## Start an emulator + +Start interactively and let the first-run flow select an emulator: + +```bash +lstk +``` + +Start explicitly: + +```bash +lstk start +lstk start --type aws +lstk start --type azure +lstk start --type snowflake +``` + +`--type` updates the selected type in the active configuration; it is not a temporary override. For automation, select the type and disable prompts: + +```bash +LOCALSTACK_AUTH_TOKEN= lstk --non-interactive start --type aws +``` + +Enable persistent emulator state for this start: + +```bash +lstk start --persist +``` + +Use `--timeout ` when automation needs a different readiness deadline: + +```bash +lstk --non-interactive start --timeout 90s +``` + +## Inspect and control the emulator + +```bash +lstk status +lstk logs --tail 100 +lstk logs --follow +lstk restart +lstk stop +``` + +Use `lstk restart --persist` when persistence must remain enabled after the restart. + +## Configure emulator environment + +Find the active configuration file: + +```bash +lstk config path +``` + +Add named environment profiles to that TOML file and reference them from the active `[[containers]]` block: + +```toml +[[containers]] +type = "aws" +tag = "latest" +port = "4566" +env = ["debug"] + +[env.debug] +DEBUG = "1" +LS_LOG = "trace" +``` + +Preserve unrelated settings and keep only one enabled `[[containers]]` block. Restart the emulator after changing its environment. + +## Target an external emulator + +Commands with a remote equivalent accept a global endpoint: + +```bash +lstk --endpoint-url https://example.localstack.cloud status +lstk --endpoint-url https://example.localstack.cloud aws s3 ls +``` + +Do not use `--endpoint-url` with `start`, `stop`, `restart`, `logs`, or `volume`; those operations require an emulator managed by the local runtime. + +## Troubleshoot startup + +1. Run `lstk status`. +2. Inspect `lstk logs --tail 200`, adding `--verbose` when request/provider lines matter. +3. Confirm the configured host port is available. +4. Confirm the detected container runtime is running. +5. Run `lstk config path` and inspect the active emulator type, image, port, environment profiles, and mounts. +6. For authentication failures, run `lstk login` or provide a valid `LOCALSTACK_AUTH_TOKEN`. + +Use direct container-runtime commands only as a last-resort diagnostic, not as the normal lifecycle workflow. diff --git a/skills/logs-analysis/SKILL.md b/skills/logs-analysis/SKILL.md deleted file mode 100644 index 9a0139d..0000000 --- a/skills/logs-analysis/SKILL.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -name: localstack-logs -description: Analyze LocalStack logs and debug issues. Use when users need to view LocalStack logs, debug AWS API errors, troubleshoot Lambda functions, identify error patterns, or enable debug mode. ---- - -# LocalStack Logs Analysis - -Analyze LocalStack logs to debug issues, identify errors, and understand AWS API interactions. - -## Capabilities - -- View and filter LocalStack logs -- Identify error patterns and failures -- Analyze AWS API request/response cycles -- Track service-specific operations -- Debug Lambda function executions - -## Viewing Logs - -### Basic Log Commands - -```bash -# Follow logs in real-time -localstack logs -f - -# View last N lines -localstack logs --tail 100 - -# Via Docker -docker logs localstack-main -f -docker logs localstack-main --tail 200 -``` - -### Filtering Logs - -```bash -# Filter by service -localstack logs | grep -i s3 -localstack logs | grep -i lambda -localstack logs | grep -i dynamodb - -# Filter errors only -localstack logs | grep -i error -localstack logs | grep -i exception - -# Filter by request ID -localstack logs | grep "request-id-here" -``` - -## Debug Mode - -Enable detailed logging: - -```bash -# Start with debug mode -DEBUG=1 localstack start -d - -# Enable specific debug flags -LS_LOG=trace localstack start -d -``` - -## Analyzing API Requests - -### Request/Response Tracking - -LocalStack logs include AWS API requests. Look for patterns like: - -``` -AWS . => -``` - -Example log entries: -``` -AWS s3.CreateBucket => 200 -AWS dynamodb.PutItem => 200 -AWS lambda.Invoke => 200 -``` - -### Common Error Patterns - -| Error | Possible Cause | Solution | -|-------|---------------|----------| -| `ResourceNotFoundException` | Resource doesn't exist | Create the resource first | -| `AccessDeniedException` | IAM policy issue | Check IAM enforcement mode | -| `ValidationException` | Invalid parameters | Verify request parameters | -| `ServiceException` | Internal error | Check LocalStack logs for details | - -## Lambda Debugging - -### View Lambda Logs - -```bash -# Lambda function logs appear in LocalStack logs -localstack logs | grep -A 10 "Lambda" - -# Or use CloudWatch Logs locally -awslocal logs describe-log-groups -awslocal logs get-log-events \ - --log-group-name /aws/lambda/my-function \ - --log-stream-name -``` - -### Enable Lambda Debug Mode - -```bash -LAMBDA_DEBUG=1 localstack start -d -``` - -## Health Check - -```bash -# Check overall health -curl http://localhost:4566/_localstack/health | jq - -# Check specific service -curl http://localhost:4566/_localstack/health | jq '.services.s3' -``` - -## Troubleshooting Tips - -- **No logs appearing**: Ensure LocalStack is running (`localstack status`) -- **Missing debug info**: Enable `DEBUG=1` for verbose logging -- **Lambda issues**: Check both LocalStack logs and CloudWatch Logs -- **Intermittent errors**: Look for resource limits or timing issues diff --git a/skills/state-management/SKILL.md b/skills/state-management/SKILL.md deleted file mode 100644 index efe2107..0000000 --- a/skills/state-management/SKILL.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -name: localstack-state -description: Manage LocalStack state and snapshots. Use when users want to save, load, export, or import LocalStack state, work with Cloud Pods, create local snapshots, or enable persistence across restarts. ---- - -# State Management - -Save, load, and manage LocalStack state for reproducible development environments and state snapshots. - -## Capabilities - -- Export and import state locally to files -- Save and load state to/from Cloud Pods (remote storage) -- Share state across teams via Cloud Pods -- Enable persistent state across container restarts - -## Local Snapshots (state export/import) - -Local snapshots allow you to export LocalStack state to files and import them back. This works without requiring a Pro subscription. - -### Export State - -```bash -# Export current state to a local file -localstack state export my-state.zip - -# Export to a specific path -localstack state export /path/to/backup/state.zip -``` - -### Import State - -```bash -# Import state from a local file -localstack state import my-state.zip - -# Import from a specific path -localstack state import /path/to/backup/state.zip -``` - -### Use Cases for Local Snapshots - -- **Backup/restore**: Save state before destructive operations -- **CI/CD pipelines**: Commit state files to version control for reproducible tests -- **Offline workflows**: Work with state files without cloud connectivity -- **Quick snapshots**: Fast local save/restore during development - -## Cloud Pods (pod save/load) - -Cloud Pods store state in LocalStack's cloud platform, enabling team collaboration and remote state management. - -### Prerequisites - -Cloud Pods require a LocalStack Pro subscription and auth token: - -```bash -export LOCALSTACK_AUTH_TOKEN= -``` - -### Save to Cloud Pod - -```bash -# Save current state to a Cloud Pod -localstack pod save my-pod-name - -# Save with a message -localstack pod save my-pod-name --message "Initial setup with S3 and DynamoDB" -``` - -### Load from Cloud Pod - -```bash -# Load state from a Cloud Pod -localstack pod load my-pod-name - -# Load and merge with existing state -localstack pod load my-pod-name --merge -``` - -### List Cloud Pods - -```bash -# List all available Cloud Pods -localstack pod list -``` - -### Delete Cloud Pods - -```bash -# Delete a Cloud Pod -localstack pod delete my-pod-name -``` - -### Inspect Cloud Pods - -```bash -# View Cloud Pod details -localstack pod inspect my-pod-name -``` - -### Use Cases for Cloud Pods - -- **Team collaboration**: Share consistent development environments across team members -- **Demo environments**: Prepare and share demo-ready states -- **Cross-machine development**: Access the same state from different machines - -## Local Persistence - -For automatic persistence across LocalStack restarts (without explicit export/import): - -```bash -# Enable local persistence -PERSISTENCE=1 localstack start -d - -# State is saved to .localstack/ directory -# Survives container restarts -``` - -## Comparison - -| Feature | Local Snapshots (export/import) | Cloud Pods (save/load) | -|---------|----------------------------|------------------------| -| Storage | Local files | LocalStack cloud | -| Pro required | No | Yes | -| Team sharing | Manual file sharing | Built-in | -| Version control | Can commit files | Cloud-managed | -| Offline use | Yes | No | - -## Best Practices - -- Use `state export/import` for local development and CI/CD pipelines -- Use Cloud Pods for team collaboration and shared environments -- Use descriptive names that indicate the state contents -- Enable `PERSISTENCE=1` for simple state retention across restarts