Skip to content

Commit f083c5c

Browse files
authored
Merge pull request #198 from robmorgan/chore/builtin-virtual-cloud
Chore/builtin virtual cloud
2 parents f2d8376 + 56f6fd5 commit f083c5c

10 files changed

Lines changed: 274 additions & 110 deletions

File tree

CLAUDE.md

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ This document provides guidance for AI coding assistants working on the InfraSpe
55
## Project Overview
66

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

1111
### Key Technologies
12+
1213
- **Language**: Go 1.24.4
1314
- **Testing Framework**: Cucumber/Godog for BDD testing
1415
- **Cloud Integration**: AWS SDK v2 (DynamoDB, RDS, S3, EC2, SSM)
1516
- **Website**: Next.js with Nextra documentation theme
1617
- **CLI**: Cobra for command-line interface
1718

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

2931
### Prerequisites
32+
3033
- Go 1.24.4 or later
3134
- Make (for build automation)
3235
- InfraSpec API (for AWS emulation during testing)
3336

3437
### Getting Started
38+
3539
1. Clone the repository.
3640
2. Fix a bug, improve documentation, or add a new feature.
3741
3. Install dependencies: `make deps`.
@@ -40,6 +44,7 @@ Kubernetes without requiring users to write traditional test code using framewor
4044
6. Lint code: `make lint`.
4145

4246
### Build Commands
47+
4348
- `make deps` - Install all dependencies and development tools
4449
- `make tidy` - Run `go mod tidy`
4550
- `make fmt` - Format code using gofumpt, goimports, and gci
@@ -49,25 +54,29 @@ Kubernetes without requiring users to write traditional test code using framewor
4954
## Coding Standards
5055

5156
### Go Code Style
57+
5258
- **Formatting**: Use `gofumpt` for stricter formatting than `gofmt`
5359
- **Imports**: Organize imports with `gci` in the order: standard, default, project-specific
5460
- **Import Organization**: `goimports` for automatic import management
5561
- **Linting**: All code must pass `golangci-lint` with project configuration
5662

5763
### Code Organization
64+
5865
- Follow Go project layout standards
5966
- Use meaningful package names and avoid generic names like `utils`
6067
- Keep public APIs in `pkg/` and internal logic in `internal/`
6168
- Maintain clear separation between CLI, core logic, and cloud providers
6269

6370
### Testing Patterns
71+
6472
- Use `github.com/stretchr/testify` for assertions
65-
- Write integration tests that work with InfraSpec API
73+
- Write integration tests that work with the builtin AWS emulator
6674
- Follow BDD patterns with Gherkin feature files
6775
- Test both positive and negative scenarios
6876
- Include retry logic for flaky cloud operations
6977

7078
### Error Handling
79+
7180
- Provide clear, actionable error messages
7281
- Log appropriately using `go.uber.org/zap`
7382
- Handle AWS SDK errors gracefully
@@ -85,6 +94,7 @@ This project uses **Conventional Commits** specification. All commit messages mu
8594
```
8695

8796
### Commit Types
97+
8898
- `feat`: New features
8999
- `fix`: Bug fixes
90100
- `docs`: Documentation changes
@@ -96,6 +106,7 @@ This project uses **Conventional Commits** specification. All commit messages mu
96106
- `ci`: CI/CD changes
97107

98108
### Examples
109+
99110
```
100111
feat(s3): add bucket encryption validation
101112
fix(dynamodb): handle missing table gracefully
@@ -104,7 +115,9 @@ test(rds): add integration tests for MySQL instances
104115
```
105116

106117
### Scopes
118+
107119
Use these scopes when relevant:
120+
108121
- `s3`, `dynamodb`, `rds` - AWS service specific changes
109122
- `terraform` - Terraform-related changes
110123
- `cli` - Command-line interface changes
@@ -114,23 +127,28 @@ Use these scopes when relevant:
114127
## Architecture Guidelines
115128

116129
## Adding New Assertion Functions
117-
1. Create provider specific assertion functions below `pkg/assertions`. (e.g Create AWS service-specific assertion functions in `pkg/assertions/aws`).
130+
131+
1. Create provider specific assertion functions below `pkg/assertions`. (e.g Create AWS service-specific assertion
132+
functions in `pkg/assertions/aws`).
118133
2. All assertion function names should begin with `Assert`.
119134

120135
### Adding New AWS Cloud Services
136+
121137
1. Create AWS service-specific assertion functions in `pkg/assertions/aws/`
122138
2. Add corresponding step definitions in `pkg/steps/aws/`
123139
3. Create feature examples in `examples/aws/`
124140
4. Write Gherkin feature files in `features/aws/`
125141
5. Update documentation and roadmap
126142

127143
### Testing Philosophy
144+
128145
- **BDD First**: Write Gherkin scenarios before implementation
129146
- **InfraSpec API Integration**: Use InfraSpec API for AWS service emulation
130147
- **Real-world Examples**: Include practical Terraform configurations
131148
- **Error Scenarios**: Test both success and failure paths
132149

133150
### CLI Design
151+
134152
- Use Cobra for consistent command structure
135153
- Provide helpful error messages and suggestions
136154
- Support both interactive and CI/CD usage
@@ -139,12 +157,14 @@ Use these scopes when relevant:
139157
## Dependencies Management
140158

141159
### Go Modules
160+
142161
- Keep dependencies minimal and well-maintained
143162
- Prefer AWS SDK v2 over v1
144163
- Use official libraries when possible
145164
- Regular dependency updates with testing
146165

147166
### Key Dependencies
167+
148168
- `github.com/cucumber/godog` - BDD testing framework
149169
- `github.com/aws/aws-sdk-go-v2` - AWS SDK
150170
- `github.com/spf13/cobra` - CLI framework
@@ -216,6 +236,7 @@ serviceMap := map[string]string{
216236
```
217237

218238
**Critical:** Service keys must match AWS SDK expectations exactly. For example:
239+
219240
- `S3_CONTROL` (correct) - generates `AWS_ENDPOINT_URL_S3_CONTROL`
220241
- `S3CONTROL` (wrong) - generates incorrect env var, requests go to real AWS
221242

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

226247
1. Add entry to `serviceMap` in `pkg/steps/terraform/terraform.go`
227248
2. Use the correct AWS SDK service identifier (check AWS docs)
228-
3. Ensure infraspec-api implements the service (see `infraspec-api/AGENTS.md`)
229-
230-
### Authentication
231-
232-
Virtual Cloud validates tokens from InfraSpec Cloud:
233-
- Set `INFRASPEC_CLOUD_TOKEN` environment variable with your API token
234-
- Token is used as `AWS_SECRET_ACCESS_KEY` for SigV4 signing
235-
- See `infraspec-cloud/CLAUDE.md` for token generation
249+
3. Ensure the builtin AWS emulator implements the service.
236250

237251
## Troubleshooting
238252

239253
### Common Issues
240-
- **InfraSpec API connectivity**: Ensure InfraSpec API is running and accessible on port 3687
254+
255+
- **InfraSpec emulator connectivity**: Ensure the InfraSpec emulator API runs on port 3687 during tests
241256
- **AWS credentials**: Check AWS configuration and permissions
242257
- **Go module issues**: Run `make tidy` to resolve dependencies
243-
- **Test failures**: Verify InfraSpec API services are running
244258
- **Virtual Cloud 403 errors**: Check service endpoint mapping uses correct AWS SDK identifier
245-
- **Virtual Cloud 404 errors**: Service operation may not be implemented in infraspec-api
259+
- **Virtual Cloud 404 errors**: Service operation may not be implemented in the AWS emulator
246260

247261
### Development Tools
262+
248263
- Use `make help` to see all available commands
249264
- Check `cover.html` for test coverage reports
250265
- Use Go's built-in profiling tools for performance analysis
@@ -304,12 +319,12 @@ return s.successResponse("CreateRole", result)
304319

305320
#### Protocol Requirements
306321

307-
| Protocol | Services | Content-Type | Response Builder |
308-
|----------|----------|--------------|------------------|
309-
| Query | RDS, EC2, IAM, STS, SQS | `text/xml` | `BuildQueryResponse()` |
310-
| JSON | DynamoDB, CloudWatch | `application/x-amz-json-1.0` | `BuildJSONResponse()` |
311-
| REST-XML | S3 | `application/xml` | `BuildRESTXMLResponse()` |
312-
| REST-JSON | Lambda, API Gateway | `application/json` | `BuildRESTJSONResponse()` |
322+
| Protocol | Services | Content-Type | Response Builder |
323+
| --------- | ----------------------- | ---------------------------- | ------------------------- |
324+
| Query | RDS, EC2, IAM, STS, SQS | `text/xml` | `BuildQueryResponse()` |
325+
| JSON | DynamoDB, CloudWatch | `application/x-amz-json-1.0` | `BuildJSONResponse()` |
326+
| REST-XML | S3 | `application/xml` | `BuildRESTXMLResponse()` |
327+
| REST-JSON | Lambda, API Gateway | `application/json` | `BuildRESTJSONResponse()` |
313328

314329
#### Mandatory Verification
315330

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

325340
1. **Analyze with CloudMirror:**
341+
326342
```bash
327343
cd tools/cloudmirror && go build -o ../../bin/cloudmirror ./cmd/cloudmirror && cd ../..
328344
./bin/cloudmirror analyze --service=<name> --output=markdown
329345
```
330346

331347
2. **Generate scaffold:**
348+
332349
```bash
333350
./bin/cloudmirror scaffold --service=<name>
334351
```
335352

336353
3. **Generate response types with correct XML tags:**
354+
337355
```bash
338356
./bin/cloudmirror gentypes --service=<name>
339357
```
@@ -343,6 +361,7 @@ grep -rn 'fmt\.Sprintf.*<?xml\|fmt\.Sprintf.*<.*Response>\|xml\.MarshalIndent' i
343361
### Emulator Code Patterns
344362

345363
#### Handler Pattern
364+
346365
```go
347366
func (s *MyService) handleAction(ctx context.Context, params map[string]interface{}) (*emulator.AWSResponse, error) {
348367
// 1. Extract and validate parameters
@@ -361,13 +380,17 @@ func (s *MyService) handleAction(ctx context.Context, params map[string]interfac
361380
```
362381

363382
#### State Key Pattern
383+
364384
Use consistent keys: `<service>:<resource-type>:<identifier>`
385+
365386
- `rds:instances:my-database`
366387
- `s3:buckets:my-bucket`
367388
- `iam:roles:my-role`
368389

369390
#### File Naming Convention
391+
370392
Use **snake_case** for handler file names:
393+
371394
- `DeleteScheduledAction``delete_scheduled_action_handler.go`
372395
- `CreateDBInstance``create_db_instance_handler.go`
373396

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

418441
The graph (`internal/emulator/graph/`) models AWS resource dependencies for:
442+
419443
- **Dependency validation** - Block deletion of resources with dependents
420444
- **Relationship tracking** - Model containment, references, attachments
421445
- **Cross-service dependencies** - EC2 instances → IAM instance profiles
@@ -459,8 +483,3 @@ cd tools/cloudmirror && go build -o ../../bin/cloudmirror ./cmd/cloudmirror && c
459483
./bin/cloudmirror gentypes --service=<name> # Generate Go types from Smithy models
460484
./bin/cloudmirror check --target=internal/emulator/services/rds/ # Code pattern analysis
461485
```
462-
463-
## Related Projects
464-
465-
- **infraspec-cloud**: SaaS dashboard for API tokens - see `infraspec-cloud/CLAUDE.md`
466-
- **Root CLAUDE.md**: Cross-project workflows and integration guide

README.md

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<br>InfraSpec
55
</h1>
66
<p align="center">
7-
<strong>✅ Test your AWS infrastructure code in plain English.</strong>
7+
<strong>✅ Test your AWS infrastructure code in plain English using virtual or real AWS APIs.</strong>
88
</p>
99
</p>
1010

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

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

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

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

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

3832
## ⚡ Quick Example
3933

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

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

7771
## 🚀 Installation
7872

@@ -144,13 +138,13 @@ Or run all tests:
144138
infraspec features/
145139
```
146140

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

149143
```bash
150-
infraspec --virtual-cloud features/
144+
infraspec --live features/
151145
```
152146

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

155149
### 4. Integrate with CI/CD
156150

@@ -290,9 +284,6 @@ make test
290284
make build
291285
```
292286

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

298289
## 📞 Community & Support

0 commit comments

Comments
 (0)