Stackaroo is a Go CLI tool for managing AWS CloudFormation stacks as code. Provides declarative configuration, environment management, change preview, template validation, and dependency management.
Tech Stack: Go 1.24, AWS SDK v2, Cobra CLI, YAML configuration, CloudFormation
make build # Build binary
make test # Run tests
make lint # Run linting
./bin/stackaroo --help # Test CLIEssential Commands:
make build- Build main binarymake build-all- Build all binariesmake test- Unit testsmake lint- Format + vet + golangci-lintmake commit-check- Pre-commit validation
cmd/ - CLI commands
internal/ - Core packages
aws/ - AWS service interactions
config/ - Configuration handling
deploy/ - Deployment logic
resolve/ - Dependency resolution
examples/ - Usage examples
docs/ - Documentation
- Use
go fmt(enforced in CI) - Follow Go naming conventions
- Handle errors explicitly with wrapped context
- Use
context.Contextfor cancellation/timeouts - Write tests alongside code (
file.go+file_test.go)
Choose approach based on context:
Complex Logic (TDD): Write failing tests → implement → refactor AWS Integration: Build + mock together, test success/error paths Simple CLI: Implement → test edge cases and validation
Test Categories:
- Unit Tests: Fast, mocked dependencies, run with
go test -short - Integration Tests: Real AWS (dry-run preferred), use
//go:build integration
Test Structure:
func TestFunction_Scenario_Expected(t *testing.T) {
// Arrange: setup data/mocks
// Act: execute function
// Assert: verify behaviour
require.NoError(t, err)
assert.Equal(t, expected, actual)
}AWS Mocking Pattern:
type mockCloudFormationAPI struct {
mock.Mock
}
func (m *mockCloudFormationAPI) CreateStack(ctx context.Context, input *cloudformation.CreateStackInput, opts ...func(*cloudformation.Options)) (*cloudformation.CreateStackOutput, error) {
args := m.Called(ctx, input)
return args.Get(0).(*cloudformation.CreateStackOutput), args.Error(1)
}- Use British English throughout (colour, organisation, optimise)
- Apply to code comments, errors, variables, and documentation
- Use Mermaid for diagrams (flowcharts, sequence, state, class)
- ISO 8601 dates (YYYY/MM/DD)
- Uses AWS SDK v2 credential chain
- Supports profiles (
--profileorAWS_PROFILE) - Region from config/environment or
--regionflag
- Validate templates before deployment
- Handle stack lifecycle (create/update/delete)
- Support parameter files and dependency resolution
- Implement
depends_onrelationships
- Never use production accounts
- Use separate dev account/profile
- Dry-run mode is default for safety
- Clean up resources after testing
File Structure:
stackaroo.yml # Main configuration
templates/
vpc.yml # CloudFormation templates
app.yml
Features:
- Stack definitions in YAML
- Context-specific parameter overrides
- Template path resolution
- Dependency declarations with
depends_on - List parameter support for CloudFormation
List<Type>andCommaDelimitedList - Mixed parameter resolution (literals + stack outputs in single parameter)
- Heterogeneous list parameters with clean YAML array syntax
Example Configuration with List Parameters:
# stackaroo.yml
stacks:
web-app:
template: templates/webapp.yml
parameters:
# Simple literal parameter
Environment: production
# List parameter with mixed resolution types
SecurityGroupIds:
- sg-baseline123 # Literal value
- type: stack-output # Dynamic from stack output
stack: security-stack
output: WebSGId
- sg-additional456 # Another literal
# Simple literal list
AllowedPorts:
- "80"
- "443"
- "8080"Core:
github.com/aws/aws-sdk-go-v2- AWS SDKgithub.com/spf13/cobra- CLI frameworkgopkg.in/yaml.v3- YAML parsinggithub.com/stretchr/testify- Testing
Dev Tools:
golangci-lint- Lintinggovulncheck- Security scanning
- Create
cmd/newcommand.go - Register in
cmd/root.go - Add tests
cmd/newcommand_test.go - Update documentation
- Add client to
internal/aws/ - Create service functions with error handling
- Write unit tests with mocks
- Add integration tests
- Update structs in
internal/config/ - Add validation and YAML parsing
- Add migration logic if needed
- Update examples
GitHub Actions runs:
- Test - Unit tests with race detection
- Lint - golangci-lint
- Security - govulncheck
- Build - Cross-platform (Linux/macOS/Windows, AMD64/ARM64)
- Integration - Basic CLI functionality
All checks must pass before merge.
- Never commit credentials
- Use minimal IAM permissions
- Validate all inputs (especially file paths)
- Sanitise CloudFormation inputs
- Run
govulncheckregularly
make lint # Format and lint
make test # Run tests
make commit-check # Full validation- Use conventional commit format
- Include AWS resource context
- Reference issue numbers
🚨 MANDATORY WORKFLOW - NO EXCEPTIONS 🚨
CRITICAL UNDERSTANDING: Making code changes is COMPLETELY SEPARATE from committing them.
- ✅ User asks for changes → I implement immediately
- ❌ Any git operation → I MUST get explicit approval first
This applies to ALL changes:
- Source code modifications
- Documentation updates
- Configuration changes
- Test updates
- ANY file changes
CRITICAL: There are two distinct phases that require different handling:
User requests like:
- "Change X to Y"
- "Update the README"
- "Fix the bug in file.go"
- "Add parameter support"
Action: Make the requested code changes immediately.
ANY git command including:
git addgit commitgit commit --amendgit rebase
🚨🚨🚨 NO GIT COMMANDS WITHOUT EXPLICIT APPROVAL 🚨🚨🚨
Make the requested code changes, but DO NOT execute any git commands.
Present all modifications with:
- File paths and detailed explanations
- Breaking changes and dependency impacts
- Test results (
go test ./...,make lint,go build) - Performance or security implications
🛑 MANDATORY STOP - NO GIT COMMANDS UNTIL APPROVAL 🛑
Present changes and ask:
"Do you approve these changes for commit?"
🛑 DO NOT EXECUTE ANY GIT COMMANDS WITHOUT EXPLICIT APPROVAL 🛑
Required approval responses:
- ✅ "Yes, proceed" / "Approved" / "Go ahead"
- ✅ "proceed" / "commit these changes"
- ❌ Any other response means DO NOT COMMIT
git add [files]
git commit -m "[message]"
# OR for amendments:
git commit --amendNever execute git push - this remains human responsibility.
❌ WRONG: "Please change X" → Implement change → Automatically commit ✅ RIGHT: "Please change X" → Implement change → Ask for commit approval
❌ WRONG: User says "update the README" → Make changes → git commit
✅ RIGHT: User says "update the README" → Make changes → Present summary → Request approval → Wait → Commit only after approval
❌ WRONG: Assuming implementation request = commit approval ✅ RIGHT: Implementation and git operations are separate phases
BEFORE EVERY git COMMAND:
- ⏹️ Stop
- 📋 Present changes summary
- ❓ Ask: "Do you approve these changes for commit?"
- ⏳ Wait for explicit approval
- ✅ Only then execute git commands
This process applies to ALL changes:
- Source code (
.gofiles) - Configuration (YAML, Makefile)
- Documentation (README.md, AGENTS.md)
- Tests and dependencies
- CI/CD pipeline changes
- Git operations (
git commit,git commit --amend, interactive rebase, etc.)
Violation consequences: If this process is not followed, stop all work and acknowledge the mistake.
Common Issues:
- Credentials:
aws configure list - Templates:
aws cloudformation validate-template - Dependencies: Review
depends_oncycles - Permissions: Verify IAM policies
Debug Tools:
- Use
--verboseflag - Enable AWS SDK logging via environment
- Structured logging with request IDs
- Clear stack name/operation logging
Release:
make release-build # All platforms
make version # Version info