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
71 changes: 45 additions & 26 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ This document provides guidance for AI coding assistants working on the InfraSpe
## Project Overview

**InfraSpec** is a tool for testing your cloud infrastructure written in Go that allows users to write infrastructure
tests in plain English using Gherkin syntax. The project tests infrastructure code for Terraform, Docker, and
Kubernetes without requiring users to write traditional test code using frameworks like Terratest.
tests in plain English using Gherkin syntax. The project tests infrastructure code for Terraform, Docker, and Kubernetes
without requiring users to write traditional test code using frameworks like Terratest.

### Key Technologies

- **Language**: Go 1.24.4
- **Testing Framework**: Cucumber/Godog for BDD testing
- **Cloud Integration**: AWS SDK v2 (DynamoDB, RDS, S3, EC2, SSM)
- **Website**: Next.js with Nextra documentation theme
- **CLI**: Cobra for command-line interface

### Project Structure

- `cmd/` - CLI commands and main entry point
- `pkg/` - Public packages (assertions, helpers, provisioners)
- `internal/` - Private packages (config, runners, generators)
Expand All @@ -27,11 +29,13 @@ Kubernetes without requiring users to write traditional test code using framewor
## Development Setup

### Prerequisites

- Go 1.24.4 or later
- Make (for build automation)
- InfraSpec API (for AWS emulation during testing)

### Getting Started

1. Clone the repository.
2. Fix a bug, improve documentation, or add a new feature.
3. Install dependencies: `make deps`.
Expand All @@ -40,6 +44,7 @@ Kubernetes without requiring users to write traditional test code using framewor
6. Lint code: `make lint`.

### Build Commands

- `make deps` - Install all dependencies and development tools
- `make tidy` - Run `go mod tidy`
- `make fmt` - Format code using gofumpt, goimports, and gci
Expand All @@ -49,25 +54,29 @@ Kubernetes without requiring users to write traditional test code using framewor
## Coding Standards

### Go Code Style

- **Formatting**: Use `gofumpt` for stricter formatting than `gofmt`
- **Imports**: Organize imports with `gci` in the order: standard, default, project-specific
- **Import Organization**: `goimports` for automatic import management
- **Linting**: All code must pass `golangci-lint` with project configuration

### Code Organization

- Follow Go project layout standards
- Use meaningful package names and avoid generic names like `utils`
- Keep public APIs in `pkg/` and internal logic in `internal/`
- Maintain clear separation between CLI, core logic, and cloud providers

### Testing Patterns

- Use `github.com/stretchr/testify` for assertions
- Write integration tests that work with InfraSpec API
- Write integration tests that work with the builtin AWS emulator
- Follow BDD patterns with Gherkin feature files
- Test both positive and negative scenarios
- Include retry logic for flaky cloud operations

### Error Handling

- Provide clear, actionable error messages
- Log appropriately using `go.uber.org/zap`
- Handle AWS SDK errors gracefully
Expand All @@ -85,6 +94,7 @@ This project uses **Conventional Commits** specification. All commit messages mu
```

### Commit Types

- `feat`: New features
- `fix`: Bug fixes
- `docs`: Documentation changes
Expand All @@ -96,6 +106,7 @@ This project uses **Conventional Commits** specification. All commit messages mu
- `ci`: CI/CD changes

### Examples

```
feat(s3): add bucket encryption validation
fix(dynamodb): handle missing table gracefully
Expand All @@ -104,7 +115,9 @@ test(rds): add integration tests for MySQL instances
```

### Scopes

Use these scopes when relevant:

- `s3`, `dynamodb`, `rds` - AWS service specific changes
- `terraform` - Terraform-related changes
- `cli` - Command-line interface changes
Expand All @@ -114,23 +127,28 @@ Use these scopes when relevant:
## Architecture Guidelines

## Adding New Assertion Functions
1. Create provider specific assertion functions below `pkg/assertions`. (e.g Create AWS service-specific assertion functions in `pkg/assertions/aws`).

1. Create provider specific assertion functions below `pkg/assertions`. (e.g Create AWS service-specific assertion
functions in `pkg/assertions/aws`).
2. All assertion function names should begin with `Assert`.

### Adding New AWS Cloud Services

1. Create AWS service-specific assertion functions in `pkg/assertions/aws/`
2. Add corresponding step definitions in `pkg/steps/aws/`
3. Create feature examples in `examples/aws/`
4. Write Gherkin feature files in `features/aws/`
5. Update documentation and roadmap

### Testing Philosophy

- **BDD First**: Write Gherkin scenarios before implementation
- **InfraSpec API Integration**: Use InfraSpec API for AWS service emulation
- **Real-world Examples**: Include practical Terraform configurations
- **Error Scenarios**: Test both success and failure paths

### CLI Design

- Use Cobra for consistent command structure
- Provide helpful error messages and suggestions
- Support both interactive and CI/CD usage
Expand All @@ -139,12 +157,14 @@ Use these scopes when relevant:
## Dependencies Management

### Go Modules

- Keep dependencies minimal and well-maintained
- Prefer AWS SDK v2 over v1
- Use official libraries when possible
- Regular dependency updates with testing

### Key Dependencies

- `github.com/cucumber/godog` - BDD testing framework
- `github.com/aws/aws-sdk-go-v2` - AWS SDK
- `github.com/spf13/cobra` - CLI framework
Expand Down Expand Up @@ -216,6 +236,7 @@ serviceMap := map[string]string{
```

**Critical:** Service keys must match AWS SDK expectations exactly. For example:

- `S3_CONTROL` (correct) - generates `AWS_ENDPOINT_URL_S3_CONTROL`
- `S3CONTROL` (wrong) - generates incorrect env var, requests go to real AWS

Expand All @@ -225,26 +246,20 @@ When adding support for a new AWS service:

1. Add entry to `serviceMap` in `pkg/steps/terraform/terraform.go`
2. Use the correct AWS SDK service identifier (check AWS docs)
3. Ensure infraspec-api implements the service (see `infraspec-api/AGENTS.md`)

### Authentication

Virtual Cloud validates tokens from InfraSpec Cloud:
- Set `INFRASPEC_CLOUD_TOKEN` environment variable with your API token
- Token is used as `AWS_SECRET_ACCESS_KEY` for SigV4 signing
- See `infraspec-cloud/CLAUDE.md` for token generation
3. Ensure the builtin AWS emulator implements the service.

## Troubleshooting

### Common Issues
- **InfraSpec API connectivity**: Ensure InfraSpec API is running and accessible on port 3687

- **InfraSpec emulator connectivity**: Ensure the InfraSpec emulator API runs on port 3687 during tests
- **AWS credentials**: Check AWS configuration and permissions
- **Go module issues**: Run `make tidy` to resolve dependencies
- **Test failures**: Verify InfraSpec API services are running
- **Virtual Cloud 403 errors**: Check service endpoint mapping uses correct AWS SDK identifier
- **Virtual Cloud 404 errors**: Service operation may not be implemented in infraspec-api
- **Virtual Cloud 404 errors**: Service operation may not be implemented in the AWS emulator

### Development Tools

- Use `make help` to see all available commands
- Check `cover.html` for test coverage reports
- Use Go's built-in profiling tools for performance analysis
Expand Down Expand Up @@ -304,12 +319,12 @@ return s.successResponse("CreateRole", result)

#### Protocol Requirements

| Protocol | Services | Content-Type | Response Builder |
|----------|----------|--------------|------------------|
| Query | RDS, EC2, IAM, STS, SQS | `text/xml` | `BuildQueryResponse()` |
| JSON | DynamoDB, CloudWatch | `application/x-amz-json-1.0` | `BuildJSONResponse()` |
| REST-XML | S3 | `application/xml` | `BuildRESTXMLResponse()` |
| REST-JSON | Lambda, API Gateway | `application/json` | `BuildRESTJSONResponse()` |
| Protocol | Services | Content-Type | Response Builder |
| --------- | ----------------------- | ---------------------------- | ------------------------- |
| Query | RDS, EC2, IAM, STS, SQS | `text/xml` | `BuildQueryResponse()` |
| JSON | DynamoDB, CloudWatch | `application/x-amz-json-1.0` | `BuildJSONResponse()` |
| REST-XML | S3 | `application/xml` | `BuildRESTXMLResponse()` |
| REST-JSON | Lambda, API Gateway | `application/json` | `BuildRESTJSONResponse()` |

#### Mandatory Verification

Expand All @@ -323,17 +338,20 @@ grep -rn 'fmt\.Sprintf.*<?xml\|fmt\.Sprintf.*<.*Response>\|xml\.MarshalIndent' i
### Adding a New AWS Service

1. **Analyze with CloudMirror:**

```bash
cd tools/cloudmirror && go build -o ../../bin/cloudmirror ./cmd/cloudmirror && cd ../..
./bin/cloudmirror analyze --service=<name> --output=markdown
```

2. **Generate scaffold:**

```bash
./bin/cloudmirror scaffold --service=<name>
```

3. **Generate response types with correct XML tags:**

```bash
./bin/cloudmirror gentypes --service=<name>
```
Expand All @@ -343,6 +361,7 @@ grep -rn 'fmt\.Sprintf.*<?xml\|fmt\.Sprintf.*<.*Response>\|xml\.MarshalIndent' i
### Emulator Code Patterns

#### Handler Pattern

```go
func (s *MyService) handleAction(ctx context.Context, params map[string]interface{}) (*emulator.AWSResponse, error) {
// 1. Extract and validate parameters
Expand All @@ -361,13 +380,17 @@ func (s *MyService) handleAction(ctx context.Context, params map[string]interfac
```

#### State Key Pattern

Use consistent keys: `<service>:<resource-type>:<identifier>`

- `rds:instances:my-database`
- `s3:buckets:my-bucket`
- `iam:roles:my-role`

#### File Naming Convention

Use **snake_case** for handler file names:

- `DeleteScheduledAction` → `delete_scheduled_action_handler.go`
- `CreateDBInstance` → `create_db_instance_handler.go`

Expand Down Expand Up @@ -416,6 +439,7 @@ func TestMyOperation_Success(t *testing.T) {
### Resource Relationship Graph

The graph (`internal/emulator/graph/`) models AWS resource dependencies for:

- **Dependency validation** - Block deletion of resources with dependents
- **Relationship tracking** - Model containment, references, attachments
- **Cross-service dependencies** - EC2 instances → IAM instance profiles
Expand Down Expand Up @@ -459,8 +483,3 @@ cd tools/cloudmirror && go build -o ../../bin/cloudmirror ./cmd/cloudmirror && c
./bin/cloudmirror gentypes --service=<name> # Generate Go types from Smithy models
./bin/cloudmirror check --target=internal/emulator/services/rds/ # Code pattern analysis
```

## Related Projects

- **infraspec-cloud**: SaaS dashboard for API tokens - see `infraspec-cloud/CLAUDE.md`
- **Root CLAUDE.md**: Cross-project workflows and integration guide
35 changes: 13 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<br>InfraSpec
</h1>
<p align="center">
<strong>✅ Test your AWS infrastructure code in plain English.</strong>
<strong>✅ Test your AWS infrastructure code in plain English using virtual or real AWS APIs.</strong>
</p>
</p>

Expand All @@ -15,25 +15,19 @@
<a href="https://github.com/robmorgan/infraspec/releases"><img src="https://img.shields.io/github/v/release/robmorgan/infraspec" alt="Release"></a>
</p>

<p align="center">
<a href="https://infraspec.sh/virtual-cloud">
<img src="https://img.shields.io/badge/🚀%20Try-InfraSpec%20Virtual%20Cloud-5B47ED?style=for-the-badge" alt="Try Virtual Cloud">
</a>
<br>
<sub>100x faster tests • 90% cost savings • Zero cleanup</sub>
</p>

---

Testing infrastructure code shouldn't require learning complex testing frameworks or writing hundreds of lines of code.
InfraSpec lets you write infrastructure tests in **plain English** using the battle-tested Gherkin syntax.

Traditional infrastructure testing solutions like Terratest require programming knowledge, so writing the tests can take
as long as writing the infrastructure itself. They also limit collaboration so non-technical stakeholders can’t review
or contribute, and tests often become difficult to maintain or understand over time.
as long as writing the infrastructure itself. InfraSpec focuses on **intent**. Tests read like documentation, are easy
to review, and remain understandable over time. This makes collaboration possible not just for engineers, but also for
platform, security, and compliance stakeholders.

InfraSpec combines a rich library of pre-built testing patterns with natural language specifications. Write tests that
read like documentation and are executable from day one.
InfraSpec runs tests against a built-in virtual cloud emulator for fast, deterministic local and CI workflows, or
against real AWS APIs for end-to-end validation. Pre-built testing patterns and natural-language specifications ensure
tests remain readable, maintainable, and executable from day one.

## ⚡ Quick Example

Expand Down Expand Up @@ -66,13 +60,13 @@ That's it! No code to write, no frameworks to learn. InfraSpec handles the rest.
## ✨ Features

- 🗣️ **Plain English syntax** - Write tests that read like documentation using Gherkin
- ⚡️ **Fast feedback** - 10-100x faster than creating real AWS infrastructure
- 👥 **Team-friendly** - Non-technical stakeholders can read, review, and contribute
- 🚀 **Zero boilerplate** - Works with your existing Terraform configurations out of the box
- 📚 **Rich assertion library** - Hundreds of pre-built assertions for AWS resources
- ⚡ **Fast feedback** - Catch infrastructure issues before they reach production
- 🔄 **CI/CD ready** - Integrates seamlessly with your existing pipelines
- 💰 **Cost effective** - Use Virtual Cloud to eliminate AWS testing costs
- 🧪 **Flexible testing** - Test against real AWS or Virtual Cloud emulator
- 💰 **Cost effective** - Built-in emulator eliminates AWS testing costs
- 🧪 **Flexible testing** - Test against real AWS or the Virtual Cloud emulator

## 🚀 Installation

Expand Down Expand Up @@ -144,13 +138,13 @@ Or run all tests:
infraspec features/
```

Optionally use [InfraSpec Virtual Cloud](https://infraspec.sh/virtual-cloud) for rapid testing with zero cleanup:
Optionally use the `--live` flag to run against real AWS APIs (be sure to cleanup any dangling resources):

```bash
infraspec --virtual-cloud features/
infraspec --live features/
```

→ [**Learn more about InfraSpec Virtual Cloud**](https://infraspec.sh/virtual-cloud)
→ [**Learn more about live testing on AWS**](https://infraspec.sh/docs/guides/live-testing)

### 4. Integrate with CI/CD

Expand Down Expand Up @@ -290,9 +284,6 @@ make test
make build
```

**Note:** Our tests use [InfraSpec Virtual Cloud](https://infraspec.sh/virtual-cloud), a high-fidelity AWS emulator, to
save time and costs during development. The Virtual Cloud API is available as a paid service for production use.

See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.

## 📞 Community & Support
Expand Down
Loading
Loading