From 431aa0480efa8d89b8ff2db4020aa63d1b1921c6 Mon Sep 17 00:00:00 2001
From: Rob Morgan
Date: Tue, 30 Dec 2025 10:01:12 +0800
Subject: [PATCH 1/6] chore(docs): virtual cloud internal tweaks
---
README.md | 28 ++++++++-----------
.../src/content/docs/guides/live-testing.mdx | 17 +++++++++++
2 files changed, 28 insertions(+), 17 deletions(-)
create mode 100644 website/src/content/docs/guides/live-testing.mdx
diff --git a/README.md b/README.md
index 5bda1cd..4478966 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
InfraSpec
- β
Test your AWS infrastructure code in plain English.
+ β
Test your AWS infrastructure code in plain English against virtual or real AWS APIs.
@@ -15,25 +15,19 @@
-
-
-
-
-
- 100x faster tests β’ 90% cost savings β’ Zero cleanup
-
-
---
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
@@ -72,7 +66,7 @@ That's it! No code to write, no frameworks to learn. InfraSpec handles the rest.
- β‘ **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
+- π§ͺ **Flexible testing** - Test against real AWS or the Virtual Cloud emulator
## π Installation
@@ -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
diff --git a/website/src/content/docs/guides/live-testing.mdx b/website/src/content/docs/guides/live-testing.mdx
new file mode 100644
index 0000000..c0bcc61
--- /dev/null
+++ b/website/src/content/docs/guides/live-testing.mdx
@@ -0,0 +1,17 @@
+# Live Testing on AWS
+
+InfraSpec can run tests against real AWS APIs, allowing you to test your infrastructure code against a live AWS
+environment. This is useful for testing your infrastructure code in a live environment, or for testing your
+infrastructure code against a live environment.
+
+## Getting started
+
+To get started, you need to have a valid AWS account and credentials. You can use the `AWS_ACCESS_KEY_ID` and
+`AWS_SECRET_ACCESS_KEY` environment variables to configure your AWS credentials. For other configuration options, see
+the [Configuring AWS Credentials](/docs/providers/aws/configure) page.
+
+## Cleaning Up
+
+While InfraSpec attempts to clean up all resources after test execution including failures, unexpected errors or network
+interruptions may leave residual infrastructure. Running [cloud-nuke](https://github.com/gruntwork-io/cloud-nuke)
+nightly in a dedicated test AWS account provides a reliable backstop for removing any orphaned resources.
From e68f756390149c09acd234f613473bbc1db75cd8 Mon Sep 17 00:00:00 2001
From: Rob Morgan
Date: Tue, 30 Dec 2025 10:03:04 +0800
Subject: [PATCH 2/6] chore(docs): vc no longer needed for dev
---
README.md | 3 ---
1 file changed, 3 deletions(-)
diff --git a/README.md b/README.md
index 4478966..402e3ba 100644
--- a/README.md
+++ b/README.md
@@ -284,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
From 0716261749d822a31511e233bead812e0a231b2b Mon Sep 17 00:00:00 2001
From: Rob Morgan
Date: Tue, 30 Dec 2025 10:21:00 +0800
Subject: [PATCH 3/6] chore(docs): copy tweak
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 402e3ba..f01f6b0 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
InfraSpec
- β
Test your AWS infrastructure code in plain English against virtual or real AWS APIs.
+ β
Test your AWS infrastructure code in plain English using virtual or real AWS APIs.
From 8504de90dcfb57578b77e21411797c1c14081135 Mon Sep 17 00:00:00 2001
From: Rob Morgan
Date: Tue, 30 Dec 2025 10:42:18 +0800
Subject: [PATCH 4/6] chore(docs): pr feedback
---
CLAUDE.md | 66 ++++++++++++-------
README.md | 4 +-
test/README.md | 40 +++++++----
test/docker-compose.yml | 11 ----
test/run-tests.sh | 12 ----
test/set-env-vars.sh | 14 ----
.../templates/service_scaffold.go.tmpl | 2 +-
.../generator/templates/service_stub.go.tmpl | 2 +-
.../src/content/docs/guides/live-testing.mdx | 4 +-
9 files changed, 75 insertions(+), 80 deletions(-)
delete mode 100755 test/run-tests.sh
delete mode 100755 test/set-env-vars.sh
diff --git a/CLAUDE.md b/CLAUDE.md
index adf792b..809a38f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -5,10 +5,11 @@ 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)
@@ -16,6 +17,7 @@ Kubernetes without requiring users to write traditional test code using framewor
- **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)
@@ -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`.
@@ -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
@@ -49,18 +54,21 @@ 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
- Follow BDD patterns with Gherkin feature files
@@ -68,6 +76,7 @@ Kubernetes without requiring users to write traditional test code using framewor
- 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
@@ -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
@@ -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
@@ -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
@@ -114,10 +127,13 @@ 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/`
@@ -125,12 +141,14 @@ Use these scopes when relevant:
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
@@ -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
@@ -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
@@ -225,26 +246,21 @@ 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
- **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
@@ -304,12 +320,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
@@ -323,17 +339,20 @@ grep -rn 'fmt\.Sprintf.*\|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= --output=markdown
```
2. **Generate scaffold:**
+
```bash
./bin/cloudmirror scaffold --service=
```
3. **Generate response types with correct XML tags:**
+
```bash
./bin/cloudmirror gentypes --service=
```
@@ -343,6 +362,7 @@ grep -rn 'fmt\.Sprintf.*\|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
@@ -361,13 +381,17 @@ func (s *MyService) handleAction(ctx context.Context, params map[string]interfac
```
#### State Key Pattern
+
Use consistent keys: `::`
+
- `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`
@@ -416,6 +440,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
@@ -459,8 +484,3 @@ cd tools/cloudmirror && go build -o ../../bin/cloudmirror ./cmd/cloudmirror && c
./bin/cloudmirror gentypes --service= # 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
diff --git a/README.md b/README.md
index f01f6b0..5939a27 100644
--- a/README.md
+++ b/README.md
@@ -60,12 +60,12 @@ 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
+- π° **Cost effective** - Built-in emulator eliminates AWS testing costs
- π§ͺ **Flexible testing** - Test against real AWS or the Virtual Cloud emulator
## π Installation
diff --git a/test/README.md b/test/README.md
index db494df..cc2756a 100644
--- a/test/README.md
+++ b/test/README.md
@@ -5,54 +5,66 @@ This folder contains test helpers and utilities for InfraSpec.
## Test Structure
### Unit Tests
-Unit tests are located alongside the code they test (e.g., `pkg/awshelpers/region_test.go`). These tests verify individual functions and packages in isolation.
+
+Unit tests are located alongside the code they test (e.g., `pkg/awshelpers/region_test.go`). These tests verify
+individual functions and packages in isolation.
Run unit tests with:
+
```sh
make test
```
Or directly:
+
```sh
go test -v $(go list ./... | grep -v '/test$')
```
### Integration Tests
+
Integration tests are run in CI by executing the `infraspec` CLI against all feature files in the `features/` directory.
On GitHub Actions, the workflow:
+
1. Builds the `infraspec` binary
-2. Runs each feature file using `infraspec --virtual-cloud`
-3. Uses the InfraSpec Cloud API at `https://api.infraspec.sh`
+2. Runs each feature file against the builtin AWS emulator using `infraspec `
## Running Integration Tests Locally
-### Using InfraSpec Cloud API
-Build the binary and run features with the `--virtual-cloud` flag:
+### Using the Builtin InfraSpec AWS Emulator
+
+Build the binary and run features:
```sh
go build -o ./infraspec ./cmd/infraspec
-INFRASPEC_CLOUD_TOKEN= ./infraspec features/aws/s3/s3_bucket.feature --virtual-cloud
+./infraspec features/aws/s3/s3_bucket.feature
```
-### Using Local InfraSpec API
-First, start the local InfraSpec API and httpbin:
+### Using Real AWS APIs
+
+Build the binary and run features using the `--live` flag:
+
```sh
-docker-compose up -d
+go build -o ./infraspec ./cmd/infraspec
+./infraspec --live features/aws/s3/s3_bucket.feature
```
-Then run features without the virtual cloud flag:
+**Note:** This creates real running infrastructure. Be sure to cleanup any dangling resources.
+
+### HTTP Tests
+
+The HTTP tests require the `httpbin` emulator to be running locally:
+
```sh
-go build -o ./infraspec ./cmd/infraspec
-source ./test/set-env-vars.sh
-./infraspec features/aws/s3/s3_bucket.feature
+docker-compose up -d
```
## Test Helpers
This directory contains:
+
- `testhelpers/` - Common test utilities and setup functions
- `httpserver/` - Mock HTTP server for testing HTTP assertions
- `integration/` - Unit tests for HTTP assertion functions
- `docker-compose.yml` - Local test environment setup
-- `set-env-vars.sh` - Environment variable setup for local testing
diff --git a/test/docker-compose.yml b/test/docker-compose.yml
index a9a1ebd..90e9554 100644
--- a/test/docker-compose.yml
+++ b/test/docker-compose.yml
@@ -1,15 +1,4 @@
services:
- infraspec-api:
- container_name: "${INFRASPEC_API_DOCKER_NAME:-infraspec-api}"
- build:
- context: ../../infraspec-api
- dockerfile: Dockerfile
- ports:
- - "127.0.0.1:3687:3687" # InfraSpec API endpoint
- environment:
- - PORT=3687
- - DEBUG=${DEBUG:-0}
-
httpbin:
container_name: "${HTTPBIN_DOCKER_NAME:-httpbin-infraspec}"
image: kennethreitz/httpbin:latest
diff --git a/test/run-tests.sh b/test/run-tests.sh
deleted file mode 100755
index 7d4ce38..0000000
--- a/test/run-tests.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-# check if infraspec-api is available on port 3687
-if nc -z localhost 3687; then
- echo "InfraSpec API is available on port 3687"
-else
- echo "InfraSpec API is not available on port 3687"
- exit 1
-fi
-
-echo "Running tests..."
-AWS_ACCESS_KEY_ID="test" AWS_SECRET_ACCESS_KEY="test" AWS_DEFAULT_REGION="us-east-1" AWS_ENDPOINT_URL="http://localhost:3687" go test -v ./...
diff --git a/test/set-env-vars.sh b/test/set-env-vars.sh
deleted file mode 100755
index 31bfef6..0000000
--- a/test/set-env-vars.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-# NOTE: This script is used to set the environment variables for the InfraSpec API container.
-# It is used in the integration tests or local testing.
-#
-# In most cases, you shouldn't execute this script directly, use `make test` instead.
-# If you do use this script be sure to source it with: `source ./test/set-env-vars.sh` command to source the
-# environment variables.
-
-echo "Setting environment variables for InfraSpec API..."
-export AWS_ACCESS_KEY_ID="test"
-export AWS_SECRET_ACCESS_KEY="test"
-export AWS_DEFAULT_REGION="us-east-1"
-export AWS_ENDPOINT_URL="http://localhost:3687"
diff --git a/tools/cloudmirror/internal/generator/templates/service_scaffold.go.tmpl b/tools/cloudmirror/internal/generator/templates/service_scaffold.go.tmpl
index 9810524..424c8bf 100644
--- a/tools/cloudmirror/internal/generator/templates/service_scaffold.go.tmpl
+++ b/tools/cloudmirror/internal/generator/templates/service_scaffold.go.tmpl
@@ -13,7 +13,7 @@ import (
"net/url"
"strings"
- "github.com/robmorgan/infraspec-api/internal/emulator"
+ "github.com/robmorgan/infraspec/internal/emulator"
)
// {{.ServiceType}} implements the AWS {{.ServiceName}} service emulator
diff --git a/tools/cloudmirror/internal/generator/templates/service_stub.go.tmpl b/tools/cloudmirror/internal/generator/templates/service_stub.go.tmpl
index b0e8e72..36f7163 100644
--- a/tools/cloudmirror/internal/generator/templates/service_stub.go.tmpl
+++ b/tools/cloudmirror/internal/generator/templates/service_stub.go.tmpl
@@ -9,7 +9,7 @@ import (
"context"
"fmt"
- "github.com/robmorgan/infraspec-api/internal/emulator"
+ "github.com/robmorgan/infraspec/internal/emulator"
)
// NotImplementedError indicates an operation is not yet implemented
diff --git a/website/src/content/docs/guides/live-testing.mdx b/website/src/content/docs/guides/live-testing.mdx
index c0bcc61..27c2991 100644
--- a/website/src/content/docs/guides/live-testing.mdx
+++ b/website/src/content/docs/guides/live-testing.mdx
@@ -1,8 +1,8 @@
# Live Testing on AWS
InfraSpec can run tests against real AWS APIs, allowing you to test your infrastructure code against a live AWS
-environment. This is useful for testing your infrastructure code in a live environment, or for testing your
-infrastructure code against a live environment.
+environment. This is useful for end-to-end validation in actual AWS environments or for testing production-like
+configurations.
## Getting started
From f3193f7c8ecbab1fb5cc09d930cc43e6a80b5c18 Mon Sep 17 00:00:00 2001
From: Rob Morgan
Date: Tue, 30 Dec 2025 11:06:12 +0800
Subject: [PATCH 5/6] chore(docs): improve getting started
---
website/src/content/docs/getting-started.mdx | 24 ++++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/website/src/content/docs/getting-started.mdx b/website/src/content/docs/getting-started.mdx
index 359023d..adb88a8 100644
--- a/website/src/content/docs/getting-started.mdx
+++ b/website/src/content/docs/getting-started.mdx
@@ -56,23 +56,37 @@ infraspec init # This will create a ./features directory if it doesn't already e
Copy and paste the following into a Terraform configuration:
```hcl filename="main.tf" copy
-provider "aws" {
- region = "us-east-1"
+output "hello_world" {
+ description = "Hello World"
+ value = "Hello, World!"
}
```
### Create Your First Test
-Create your first infrastructure test:
+Create your first test scenario:
```sh
-infraspec new dynamodb.feature
+infraspec new terraform.feature
+```
+
+### Copy the feature code
+
+Copy and paste the following into the `terraform.feature`:
+
+```gherkin filename="terraform.feature" copy
+Feature: Terraform Hello World
+
+ Scenario: Run a simple test
+ Given the Terraform module at "../examples/terraform/hello-world"
+ When I run terraform apply
+ Then the "hello_world" output is "Hello, World!"
```
### Run it!
```sh
-infraspec features/dynamodb.feature
+infraspec features/terraform.feature
```
You should see some output.
From 56f6fd5648dae9ac58800d13d5f0e5652309bd75 Mon Sep 17 00:00:00 2001
From: Rob Morgan
Date: Tue, 30 Dec 2025 11:31:02 +0800
Subject: [PATCH 6/6] docs: update documentation for getting started guide
---
CLAUDE.md | 5 +-
website/src/content/docs/getting-started.mdx | 180 +++++++++++++++++--
2 files changed, 166 insertions(+), 19 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 809a38f..a40e92f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -70,7 +70,7 @@ without requiring users to write traditional test code using frameworks like Ter
### 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
@@ -252,10 +252,9 @@ When adding support for a new AWS service:
### 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 the AWS emulator
diff --git a/website/src/content/docs/getting-started.mdx b/website/src/content/docs/getting-started.mdx
index adb88a8..aa158f8 100644
--- a/website/src/content/docs/getting-started.mdx
+++ b/website/src/content/docs/getting-started.mdx
@@ -17,8 +17,8 @@ Then the S3 bucket "my-bucket" should have an encryption configuration
InfraSpec automatically:
- Generates the underlying test code to connect to AWS
-- Parses the S3 bucket configuration
-- Validates encryption settings against AWS APIs
+- Parses the S3 bucket configuration from Terraform/OpenTofu outputs
+- Validates encryption settings against virtual or real AWS APIs
- Provides clear, actionable error messages if validation fails
This means you can focus on **what** to test rather than **how** to test it. The tool handles all the complexity of API
@@ -51,15 +51,145 @@ Initialize a Git repo containing your infrastructure code:
infraspec init # This will create a ./features directory if it doesn't already exist
```
-### Create a Simple Terraform Example
+### Create a Simple AWS Terraform/OpenTofu Infrastructure Example
-Copy and paste the following into a Terraform configuration:
+Copy and paste the following into a Terraform/OpenTofu configuration that deploys an EC2 instance to AWS:
```hcl filename="main.tf" copy
-output "hello_world" {
- description = "Hello World"
- value = "Hello, World!"
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 5.72.1"
+ }
+ }
}
+
+provider "aws" {
+ region = var.region
+}
+
+variable "region" {
+ description = "The AWS region to deploy to"
+ type = string
+ default = "us-east-1"
+}
+
+variable "name" {
+ description = "The name of the EC2 instance"
+ type = string
+}
+
+variable "instance_type" {
+ description = "The instance type"
+ type = string
+ default = "t3.micro"
+}
+
+variable "ami_id" {
+ description = "The AMI ID to use for the instance"
+ type = string
+ default = "ami-12345678"
+}
+
+variable "tags" {
+ description = "A map of tags to apply to the resources"
+ type = map(string)
+ default = {}
+}
+
+# VPC for the instance
+resource "aws_vpc" "main" {
+ cidr_block = "10.0.0.0/16"
+ enable_dns_hostnames = true
+ enable_dns_support = true
+
+ tags = {
+ Name = "${var.name}-vpc"
+ }
+}
+
+# Subnet for the instance
+resource "aws_subnet" "main" {
+ vpc_id = aws_vpc.main.id
+ cidr_block = "10.0.1.0/24"
+ availability_zone = "${var.region}a"
+
+ tags = {
+ Name = "${var.name}-subnet"
+ }
+}
+
+# Security Group for the instance
+resource "aws_security_group" "main" {
+ name = "${var.name}-sg"
+ description = "Security group for ${var.name}"
+ vpc_id = aws_vpc.main.id
+
+ ingress {
+ description = "SSH"
+ from_port = 22
+ to_port = 22
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ egress {
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+
+ tags = {
+ Name = "${var.name}-sg"
+ }
+}
+
+# EC2 Instance
+resource "aws_instance" "main" {
+ ami = var.ami_id
+ instance_type = var.instance_type
+ subnet_id = aws_subnet.main.id
+
+ vpc_security_group_ids = [aws_security_group.main.id]
+
+ tags = merge(
+ var.tags,
+ {
+ Name = var.name
+ }
+ )
+}
+
+# Outputs
+output "instance_id" {
+ description = "The ID of the EC2 instance"
+ value = aws_instance.main.id
+}
+
+output "instance_type" {
+ description = "The instance type"
+ value = aws_instance.main.instance_type
+}
+
+output "vpc_id" {
+ description = "The ID of the VPC"
+ value = aws_vpc.main.id
+}
+
+output "subnet_id" {
+ description = "The ID of the subnet"
+ value = aws_subnet.main.id
+}
+
+output "security_group_id" {
+ description = "The ID of the security group"
+ value = aws_security_group.main.id
+}
+
```
### Create Your First Test
@@ -67,20 +197,38 @@ output "hello_world" {
Create your first test scenario:
```sh
-infraspec new terraform.feature
+infraspec new ec2.feature
```
### Copy the feature code
-Copy and paste the following into the `terraform.feature`:
+Copy and paste the following into the `ec2.feature`:
```gherkin filename="terraform.feature" copy
-Feature: Terraform Hello World
-
- Scenario: Run a simple test
- Given the Terraform module at "../examples/terraform/hello-world"
- When I run terraform apply
- Then the "hello_world" output is "Hello, World!"
+Feature: EC2 Instance Creation
+ As a DevOps engineer
+ I want to create EC2 instances with specific configurations
+ So that I can ensure my compute infrastructure meets requirements
+
+ Scenario: Create an EC2 instance with basic configuration
+ Given I have a Terraform configuration in "../../../examples/aws/ec2/instance"
+ And I set the variable "region" to "us-east-1"
+ And I set the variable "name" to "test-instance" with a random suffix
+ And I set the variable "instance_type" to "t3.micro"
+ And I set the variable "ami_id" to "ami-12345678"
+ And I set the variable "tags" to
+ | Key | Value |
+ | Environment | test |
+ | Project | infratest |
+ When I run Terraform apply
+ Then the EC2 instance from output "instance_id" should exist
+ And the EC2 instance from output "instance_id" state should be "running"
+ And the EC2 instance from output "instance_id" instance type should be "t3.micro"
+ And the EC2 instance from output "instance_id" AMI should be "ami-12345678"
+ And the EC2 instance from output "instance_id" should have the tags
+ | Key | Value |
+ | Environment | test |
+ | Project | infratest |
```
### Run it!
@@ -89,6 +237,6 @@ Feature: Terraform Hello World
infraspec features/terraform.feature
```
-You should see some output.
+By default, InfraSpec will run the test against the builtin AWS emulator. You should see some output.