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 @@ Release

-

- - Try Virtual Cloud - -
- 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.