Skip to main content

Local Development

This guide covers how to run Stratos locally for development and testing.

Prerequisites

  • Go 1.25 or later
  • kubectl configured with a Kubernetes cluster
  • AWS credentials (for AWS provider) or use fake provider

Running Locally

Using the Fake Provider

The fake provider allows development without cloud costs:

go run ./cmd/stratos/main.go \
--cluster-name=dev \
--cloud-provider=fake \
--zap-log-level=debug

The fake provider:

  • Simulates instance lifecycle in memory
  • Supports hooks for testing
  • Instant operations (no cloud latency)

Using the AWS Provider

To test with real AWS resources:

# Ensure AWS credentials are configured
aws sts get-caller-identity

# Run controller
go run ./cmd/stratos/main.go \
--cluster-name=dev \
--cloud-provider=aws \
--zap-log-level=debug
warning

Running with the AWS provider will create real EC2 instances. Ensure you have appropriate permissions and monitor costs.

Process Management

Starting the Controller

# Standard way to run locally
go run ./cmd/stratos/main.go --cluster-name=dev --cloud-provider=fake

Checking if Running

The controller process appears as main in the process list:

ps aux | grep -E "main.*--cluster-name" | grep -v grep

Stopping the Controller

# Kill any existing controller
pkill -f "cmd/stratos/main.go"
tip

Always check for and kill existing controller processes before starting a new one to avoid conflicts.

Development Cycle

1. Make Code Changes

Edit files in:

  • cmd/stratos/ - Entry point and flags
  • api/v1alpha1/ - CRD types
  • internal/controller/ - Reconciliation logic
  • internal/cloudprovider/ - Cloud provider implementations

2. Regenerate Code (if needed)

If you modified api/v1alpha1/*.go:

# Regenerate deepcopy methods
make generate

# Regenerate CRD manifests
make manifests

3. Apply CRDs

# Install/update CRDs in cluster
make install

4. Run the Controller

go run ./cmd/stratos/main.go --cluster-name=dev --cloud-provider=fake

5. Test with a NodePool

kubectl apply -f deploy/samples/nodepool_sample.yaml

6. Observe Behavior

# Watch NodePool status
kubectl get nodepools -w

# Watch nodes
kubectl get nodes -l stratos.sh/pool=workers -w

# Check controller logs (in the terminal running the controller)

Using Telepresence

For faster iteration with a remote cluster, use Telepresence:

# Connect to cluster
telepresence connect

# Run controller locally, connected to remote cluster
go run ./cmd/stratos/main.go --cluster-name=dev --cloud-provider=fake

Debugging

VS Code Launch Configuration

.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Stratos",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/stratos",
"args": [
"--cluster-name=dev",
"--cloud-provider=fake",
"--zap-log-level=debug"
]
}
]
}

GoLand Run Configuration

  1. Create a new "Go Build" configuration
  2. Set:
    • Package path: github.com/stratos-sh/stratos/cmd/stratos
    • Program arguments: --cluster-name=dev --cloud-provider=fake --zap-log-level=debug

Delve Debugging

# Build with debug symbols
go build -gcflags="all=-N -l" -o /tmp/stratos ./cmd/stratos

# Run with delve
dlv exec /tmp/stratos -- --cluster-name=dev --cloud-provider=fake

Testing Changes

Unit Tests

# Run all unit tests
make test

# Run specific package tests
go test -v ./internal/controller/...

# Run specific test
go test -v -run TestScaleUp ./internal/controller/...

Integration Tests

# Run integration tests (requires envtest)
make test-integration

# Run specific integration test
go test -v -tags=integration -run TestNodePoolLifecycle ./tests/integration/...

Manual Testing

  1. Create a test AWSNodeClass and NodePool:

    test-nodeclass.yaml
    apiVersion: stratos.sh/v1alpha1
    kind: AWSNodeClass
    metadata:
    name: test
    spec:
    instanceType: t3.small
    ami: ami-0123456789abcdef0
    subnetIds: ["subnet-12345678"]
    securityGroupIds: ["sg-12345678"]
    iamInstanceProfile: arn:aws:iam::123456789012:instance-profile/test
    userData: |
    #!/bin/bash
    echo "test"
    poweroff
    test-pool.yaml
    apiVersion: stratos.sh/v1alpha1
    kind: NodePool
    metadata:
    name: test
    spec:
    poolSize: 3
    minStandby: 1
    template:
    nodeClassRef:
    kind: AWSNodeClass
    name: test
    labels:
    stratos.sh/pool: test
  2. Apply and observe:

    kubectl apply -f test-nodeclass.yaml
    kubectl apply -f test-pool.yaml
    kubectl get nodepools -w
  3. Clean up:

    kubectl delete nodepool test
    kubectl delete awsnodeclass test

Environment Setup

Required Environment Variables

# For AWS provider
export AWS_REGION=us-east-1
# AWS credentials are typically loaded from ~/.aws/credentials or IRSA

# For testing
export KUBECONFIG=~/.kube/config

Optional Environment Variables

# Override cluster name
export CLUSTER_NAME=dev

# Enable verbose logging
export LOG_LEVEL=debug

Troubleshooting

Controller Won't Start

Check for existing processes:

ps aux | grep -E "main.*--cluster-name" | grep -v grep
pkill -f "cmd/stratos/main.go"

CRD Not Found

Regenerate and install CRDs:

make generate
make manifests
make install

Permission Denied

Ensure kubectl has cluster-admin access:

kubectl auth can-i '*' '*'

AWS Errors

Verify AWS credentials:

aws sts get-caller-identity
aws ec2 describe-instances --max-items 1

Next Steps