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
- Requests - Using variables in requests
- Templating - Template syntax and functions
- CLI Reference - Using --profile flag