QuadrastackQuadrastack
Documentation

Docs

Variables

Environment-specific configuration with variable profiles

Variables

Manage environment-specific configuration with variable profiles.

Overview

Variables let you define different configurations for different environments (dev, staging, production) and switch between them easily using profiles.

Basic Variables

vars:
  default:
    baseUrl: http://localhost:8080
    apiKey: dev-key-123

  production:
    baseUrl: https://api.example.com
    apiKey: prod-key-789

Use with:

# Use default profile
quadrastack

# Use production profile
quadrastack --profile production

Variable Structure

Profiles

Top-level keys in vars are profile names.

vars:
  default:              # Default profile (used when --profile not specified)
    # variables here

  dev:                  # Development profile
    # variables here

  staging:              # Staging profile
    # variables here

  production:           # Production profile
    # variables here

Profile Variables

Each profile contains key-value pairs.

vars:
  default:
    baseUrl: http://localhost:8080
    apiKey: test-key
    timeout: "30s"
    retries: 3
    debugMode: true

No Inheritance Between Profiles

Each profile is completely independent. Variables are not inherited from default to other profiles.

vars:
  default:
    baseUrl: http://localhost:8080
    retryCount: 3

  production:
    baseUrl: https://api.example.com
    retryCount: 3    # Must be defined - not inherited from default

If you use a variable in your requests, it must be defined in the profile you're using.


Using Variables

Access variables in your playbooks with {{.vars.variableName}}.

In URLs

requests:
  get-users:
    method: GET
    url: "{{.vars.baseUrl}}/users"

In Headers

requests:
  authenticated:
    method: GET
    url: "{{.vars.baseUrl}}/api/data"
    headers:
      Authorization: "Bearer {{.vars.apiToken}}"
      X-API-Key: "{{.vars.apiKey}}"

In Body

requests:
  create-resource:
    method: POST
    url: "{{.vars.baseUrl}}/resources"
    body:
      environment: "{{.vars.environment}}"
      apiVersion: "{{.vars.apiVersion}}"
      userId: "{{.vars.userId}}"

In Assertions

requests:
  get-config:
    method: GET
    url: "{{.vars.baseUrl}}/config"
    expect:
      status: 200
      body:
        $.environment: "{{.vars.environment}}"

Complete Examples

Multi-Environment Setup

# vars.yaml
vars:
  default:
    environment: local
    baseUrl: http://localhost:8080
    apiKey: dev-key-123
    dbName: test_db
    timeout: "30s"
    debug: true

  dev:
    environment: development
    baseUrl: https://dev-api.example.com
    apiKey: dev-key-456
    dbName: dev_db
    timeout: "30s"
    debug: true

  staging:
    environment: staging
    baseUrl: https://staging-api.example.com
    apiKey: staging-key-789
    dbName: staging_db
    timeout: "60s"
    debug: false

  production:
    environment: production
    baseUrl: https://api.example.com
    apiKey: prod-key-xyz
    dbName: prod_db
    timeout: "60s"
    debug: false

Using in Requests

# requests.yaml
requests:
  health-check:
    method: GET
    url: "{{.vars.baseUrl}}/health"
    expect:
      status: 200
      body:
        $.environment: "{{.vars.environment}}"

  get-users:
    method: GET
    url: "{{.vars.baseUrl}}/api/v1/users"
    headers:
      X-API-Key: "{{.vars.apiKey}}"
      X-Environment: "{{.vars.environment}}"
    expect:
      status: 200

  create-user:
    method: POST
    url: "{{.vars.baseUrl}}/api/v1/users"
    headers:
      X-API-Key: "{{.vars.apiKey}}"
    body:
      name: Test User
      email: "test-{{.vars.environment}}@example.com"
      environment: "{{.vars.environment}}"

Authentication Variables

vars:
  default:
    baseUrl: http://localhost:8080
    username: admin
    password: admin123
    clientId: local-client
    clientSecret: local-secret

  production:
    baseUrl: https://api.example.com
    username: prod-admin
    # password set via PASSWORD env var
    # clientSecret set via CLIENTSECRET env var
    clientId: prod-client

Override at runtime:

PASSWORD=secret CLIENTSECRET=xyz quadrastack --profile production

Feature Flags

vars:
  dev:
    baseUrl: https://dev-api.example.com
    features:
      newUI: true
      betaFeatures: true
      experimentalAPI: true

  production:
    baseUrl: https://api.example.com
    features:
      newUI: true
      betaFeatures: false
      experimentalAPI: false

Variable Types

Strings

vars:
  default:
    baseUrl: http://localhost:8080
    environment: development
    version: "1.0.0"

Numbers

vars:
  default:
    port: 8080
    timeout: 30
    retries: 3
    rateLimit: 100

Booleans

vars:
  default:
    debug: true
    ssl: false
    verbose: true

Nested Objects

vars:
  default:
    api:
      baseUrl: http://localhost:8080
      version: v1
      timeout: 30
    database:
      host: localhost
      port: 5432
      name: testdb

Access nested values:

url: "{{.vars.api.baseUrl}}/{{.vars.api.version}}/users"

Arrays

vars:
  default:
    allowedOrigins:
      - http://localhost:3000
      - http://localhost:8080
    adminEmails:
      - admin@example.com
      - support@example.com

Environment Variable Overrides

Override vars with environment variables. The variable must already exist in your profile.

# Set environment variable
export BASEURL=https://custom-api.example.com

# Run tests (BASEURL overrides vars.baseurl)
quadrastack

Important: Environment variable names are converted to lowercase for matching. Use lowercase variable names in your YAML for env var overrides to work.

vars:
  default:
    baseurl: http://localhost:8080    # Overridden by BASEURL env var
    apikey: default-key               # Overridden by APIKEY env var

For nested variables, use underscores:

vars:
  default:
    api:
      url: http://localhost:8080      # Overridden by API_URL env var

In CI/CD

# GitHub Actions
env:
  BASEURL: ${{ secrets.API_URL }}
  APIKEY: ${{ secrets.API_KEY }}

steps:
  - run: quadrastack --scenario integration

Common Patterns

Regional Configuration

vars:
  us-east:
    region: us-east-1
    baseUrl: https://us-east-api.example.com
    s3Bucket: myapp-us-east

  eu-west:
    region: eu-west-1
    baseUrl: https://eu-west-api.example.com
    s3Bucket: myapp-eu-west

Test Data

vars:
  default:
    testUser:
      name: Test User
      email: test@example.com
      role: user

    testAdmin:
      name: Admin User
      email: admin@example.com
      role: admin

requests:
  create-user:
    method: POST
    url: "{{.vars.baseUrl}}/users"
    body:
      name: "{{.vars.testUser.name}}"
      email: "{{.vars.testUser.email}}"
      role: "{{.vars.testUser.role}}"

Best Practices

1. Always Provide Default Profile

vars:
  default:              # Always include default
    baseUrl: http://localhost:8080
    # ...

  production:
    baseUrl: https://api.example.com
    # ...

2. Use Environment Variable Overrides for Secrets

Do not commit secrets to vars.yaml. Instead, define placeholders or default values, and override them at runtime using environment variables.

Bad:

vars:
  production:
    password: super-secret-password  # Hard-coded secret!

Good:

vars.yaml:

vars:
  production:
    password: "change-me"     # Placeholder

Run with:

PASSWORD=my-secret-password quadrastack --profile production

(Assuming password maps to the variable key password. If nested like auth.password, use AUTH_PASSWORD).

3. Document Your Variables

vars:
  default:
    # Base URL for the API (include protocol and port)
    baseUrl: http://localhost:8080

    # API key for authentication
    apiKey: dev-key-123

    # Request timeout in seconds
    timeout: "30s"

4. Keep Profiles Complete

Since profiles don't inherit from each other, each profile must define all variables it uses:

Good:

vars:
  default:
    baseurl: http://localhost:8080
    apikey: dev-key
    timeout: 30

  production:
    baseurl: https://api.example.com
    apikey: prod-key
    timeout: 60

Bad:

vars:
  default:
    baseurl: http://localhost:8080
    apikey: dev-key
    timeout: 30

  production:
    baseurl: https://api.example.com
    # Missing apikey and timeout - will cause errors!

Tip: Use lowercase variable names if you plan to use environment variable overrides.

5. Separate Vars File

Keep variables in a separate file:

my-tests/
├── vars.yaml          # All variables
├── requests.yaml      # All requests
├── workflows.yaml     # All workflows
└── scenarios.yaml     # All scenarios

Multiple Variable Files

You can split variables across multiple files:

my-tests/
├── vars-common.yaml
├── vars-dev.yaml
├── vars-prod.yaml
└── requests.yaml

All vars sections are merged automatically.


See Also

Variables - Quadrastack Docs