Deploying Infrastructureο
Audience: DevOps engineers running
strata deploy runin production. You understand the workspace/deployment/environment model and want to know how to execute deployments safely, understand output, and handle partial failures.
strata deploy run is the command that applies infrastructure changes: provisioning resources,
running configuration management, and enforcing state consistency. This guide covers the practical
operational aspects.
Before You Deployο
1. Validate the deployment fileο
Always validate before deploying:
strata validate -f deployments/deploy-prd.yaml
strata validate -f deployments/deploy-prd.yaml --deep
--deep checks cross-file references and secret store connectivity. Fix any validation errors
before proceeding.
2. Check the dry-run planο
strata deploy run -f deployments/deploy-prd.yaml --dry-run
This:
Validates all YAML
Resolves all variables, secrets, and features
Runs
terraform plan(if Terraform is the provisioner)Prints what will change
Writes nothing to the backend or infrastructure
Read the plan carefully. If the proposed changes are not what you expect, debug before proceeding.
3. Verify state lock statusο
If locking is enabled (spec.locking.enabled: true in the deployment):
strata deploy lock status -f deployments/deploy-prd.yaml
If a lock is held, find out who holds it and why. Do not force-release unless the lock is stale (the owning process crashed).
Running a Deploymentο
Basic deploymentο
strata deploy run -f deployments/deploy-prd.yaml
strata will:
Acquire the deployment lock (if enabled)
Run
before_deploylifecycle hooksExecute stages sequentially (by default)
Run
after_deploylifecycle hooksRelease the lock
Write an audit record to
.strata/deploy-log/
Non-interactive mode (CI/CD)ο
In CI/CD pipelines, add --force to skip interactive prompts:
strata deploy run -f deployments/deploy-prd.yaml --force
Deploy a single stageο
To deploy only a specific stage (and skip others):
strata deploy run -f deployments/deploy-prd.yaml --stage networking
Useful when:
A previous deployment failed and youβre retrying a specific stage
Youβre testing one stage in isolation
You want to defer later stages (e.g., Ansible configuration) to a separate run
Dry-run: verify without applyingο
strata deploy run -f deployments/deploy-prd.yaml --dry-run
Runs the full workflow (validation, planning, hooks) but does not apply any changes:
Terraform:
planmode only (noapply)Ansible: playbooks not executed
Infrastructure: no resources created/modified
Files: nothing written
Understanding Deployment Outputο
Console output structureο
=== strata deploy run ===
Deployment: xyz-deploy-prd
Workspace: xyz-platform
Environment: prd
Stages: 3
Lock: enabled (acquired)
Stage: infrastructure (1/3)
βββββββββββββββββββββββββ
Provisioner: terraform
Status: running...
Terraform plan summary:
Add: 12
Modify: 3
Delete: 0
Resources:
+ azurerm_resource_group.platform
+ azurerm_virtual_network.core
+ azurerm_network_security_group.allow_http
~ azurerm_storage_account.logs (modify tags)
...
Apply: β
success (24s)
Stage: configuration (2/3)
ββββββββββββββββββββββββββ
Provisioner: ansible
Status: running...
Playbooks:
- site.yml β
ok
Tasks run: 42
Handlers run: 5
Duration: 1m 23s
Stage: health-check (3/3)
βββββββββββββββββββββββββ
Provisioner: shell-script
Status: running...
Script: health-check.sh
Status: β
ok
Duration: 8s
Summary
βββββββ
Total duration: 3m 15s
All stages: β
success
Audit record written to: .strata/deploy-log/2026-07-21T10-30-45Z-deploy-prd.json
Key fields to watchο
Section |
What to look for |
Action if wrong |
|---|---|---|
Lock |
Should show |
If it shows |
Plan summary |
Check Add/Modify/Delete counts against your expectations |
If surprised by proposed changes, stop and debug |
Resource list |
Scan for resources you didnβt intend to modify |
If you see unexpected |
Apply status |
Should show |
See Handling Failures section if any stage fails |
Duration |
Reasonable? Terraform usually 10-30s, Ansible 30s-5m |
Unusually long runtimes might indicate hanging connections |
Audit record |
Path printed at end |
Verify it exists: |
Structured output (JSON/NDJSON)ο
For CI/CD and log aggregation:
strata deploy run -f deployments/deploy-prd.yaml --output json
Returns a JSON envelope after completion:
{
"success": true,
"data": {
"deployment": "xyz-deploy-prd",
"environment": "prd",
"stages": [
{
"name": "infrastructure",
"provisioner": "terraform",
"status": "success",
"duration_seconds": 24,
"resources": {
"add": 12,
"modify": 3,
"delete": 0
}
},
...
],
"total_duration_seconds": 195,
"audit_record_path": ".strata/deploy-log/2026-07-21T10-30-45Z-deploy-prd.json"
},
"messages": []
}
Handling Deployment Failuresο
Exit codes and meaningsο
Exit Code |
Meaning |
What to do |
|---|---|---|
|
β Success β all stages completed |
Nothing. Deployment is complete. |
|
β System error β strata crashed |
Check |
|
β Invalid arguments |
Check your command syntax. Run |
|
β Validation error β YAML invalid or policy failed |
Fix the YAML and re-validate. If policy failed, adjust config or policy. |
|
π Lock conflict β another deployment holds the lock |
Wait for the other deployment to complete, then retry. Do NOT force-release the lock. |
Partial failure (a stage failed mid-deployment)ο
If a stage fails, the lock is held and subsequent stages are skipped. Example:
Stage: infrastructure (1/3)
ββββββββββββββββββββββββββ
Status: β
success
Stage: configuration (2/3)
ββββββββββββββββββββββββββ
Status: β FAILED
Error: Ansible playbook site.yml exited with code 1
Task: restart-services
Error: SSH connection timeout on web-02
[Ansible output saved to: .strata/deploy-log/2026-07-21T10-30-45Z-ansible-output.log]
Stage: health-check (3/3)
βββββββββββββββββββββββββ
Status: βοΈ SKIPPED (infrastructure stage failed)
Summary
βββββββ
All stages: β FAILED
Lock: still held (to prevent concurrent corrections)
To recover from a partial failure:
Investigate the error. Read the full error output and any auxiliary logs (Ansible stdout, Terraform log, etc.).
Fix the root cause. This might be:
Network connectivity issue β fix the network, wait for recovery
Bad SSH key β update credentials and re-validate
Insufficient resources β scale up or wait for resource availability
Code bug in playbook/script β fix and re-deploy
Retry the failed stage:
strata deploy run -f deployments/deploy-prd.yaml --stage configuration --force
Runs only the
configurationstage (not the earlierinfrastructurestage which already passed).Or retry the full deployment (if the earlier stages are idempotent):
strata deploy run -f deployments/deploy-prd.yaml --force
The earlier stages will re-run (Terraform/Ansible will skip no-ops if the state is consistent).
State inspection after failureο
Check current infrastructure state without re-deploying:
strata deploy status -f deployments/deploy-prd.yaml
This shows:
Resource count per stage
Last-modified timestamp
Terraform state serial (version) β if it didnβt increase, nothing actually changed
Any resource drift since the last successful deploy
Stale locksο
If a lock is held but you know the owning process crashed:
strata deploy lock release -f deployments/deploy-prd.yaml --force
Use sparingly. If the original process is still running, forcing the lock release can cause concurrent modifications to the same infrastructure, which is dangerous.
Deployment Stages and Executionο
Sequential vs. parallel stagesο
By default, stages run sequentially (one at a time). This is safe β later stages can depend on outputs from earlier stages.
Typical stage order:
spec:
stages:
- name: foundation # VNets, subnets, security groups
- name: infrastructure # Compute, databases, storage
- name: configuration # Ansible playbooks for OS setup
- name: health-check # Integration tests
Stage dependenciesο
Later stages can reference outputs from earlier stages. Example:
# Stage 1: terraform provisions infrastructure
provisioners:
- name: terraform
provisioner: terraform
source: ...
stages:
- name: infrastructure
provisioner: terraform
# Stage 2: Ansible receives IPs from Stage 1 outputs
- name: configure
provisioner: ansible
configuration:
extra_vars:
web_servers: "{{ env.output.web_server_ips }}"
# Stage 3: health-check can reference both Stage 1 and 2 outputs
- name: health-check
provisioner: shell-script
script: |
#!/bin/bash
API_ENDPOINT="{{ env.output.api_endpoint }}"
curl -f "$API_ENDPOINT/health" || exit 1
Conditional stagesο
You can conditionally skip stages using environment overrides:
# deployments/deploy-prd.yaml
spec:
environment:
- env-prd # loads env-prd.yaml
stages:
- name: infrastructure
provisioner: terraform
- name: configure
provisioner: ansible
skip: "{{ env.variables.skip_ansible }}" # can be true/false
In env-prd.yaml:
spec:
variables:
- key: skip_ansible
store: constant
value: "false"
Lifecycle Hooks and Customizationο
Before/After hooksο
Run custom scripts before/after each stage:
stages:
- name: infrastructure
provisioner: terraform
lifecycle_events:
before_stage:
- script: |
echo "About to provision infrastructure..."
terraform validate
- script: |
notify-slack "Starting infrastructure deploy"
after_stage:
- script: |
echo "Infrastructure provisioned. Running smoke tests..."
./scripts/smoke-test.sh
Scripts have access to environment variables injected by strata:
Variable |
Value |
|---|---|
|
Current lifecycle phase (e.g., |
|
Path to workspace root |
|
Path to |
|
Path to build artifacts |
Failure handlingο
By default, if a hook fails, the stage fails and subsequent stages are skipped. You can continue despite hook failures:
lifecycle_events:
after_stage:
- script: ./optional-healthcheck.sh
on_failure: ignore # continue even if this script exits non-zero
Deployment Validation and Safetyο
Pre-deployment checklistο
# 1. Validate YAML syntax
strata validate -f deployments/deploy-prd.yaml
# 2. Cross-file validation (secret stores, references, etc.)
strata validate -f deployments/deploy-prd.yaml --deep
# 3. Check if all required secrets exist
strata env show -f deployments/deploy-prd.yaml | grep "status: required"
# 4. Dry-run to see what will change
strata deploy run -f deployments/deploy-prd.yaml --dry-run
# 5. Review the audit trail to see who deployed what last time
strata audit changes --last 5
# 6. Check if lock is free
strata deploy lock status -f deployments/deploy-prd.yaml
Approval gates (in CI/CD)ο
For high-risk environments, require approval before deploying:
# Azure Pipelines
- stage: Deploy
jobs:
- job: waitForValidation
displayName: Waiting for manual approval
pool: server
timeoutInMinutes: 1440
steps:
- task: ManualValidation@0
timeoutInMinutes: 1440
- job: Deploy
dependsOn: waitForValidation
steps:
- script: strata deploy run -f deployments/deploy-prd.yaml --force
Audit Trail and Complianceο
Every successful deploy writes an audit record:
# List recent deployments
strata audit changes
# Show detailed record for one deployment
strata audit changes --last 1 --output json
# Export records for compliance tools (Splunk, SIEM, etc.)
strata audit export --since 2026-06-01T00:00:00Z --format json
Each record captures:
Who ran the deployment (commit author + git user)
When it ran (ISO 8601 timestamp)
Which stages ran and their status
Infrastructure changes (resources added/modified/deleted)
Any PR metadata linked to the commit
Common Scenariosο
Scenario 1: Rollback a deploymentο
strata doesnβt have a built-in rollback. Instead:
Revert the commit(s) that introduced the bad change
Merge the revert
Run
strata deploy run -f deployments/deploy-prd.yaml --forceTerraform will detect the drift and correct it
For faster manual rollback (if needed):
# Restore from a previous Terraform state backup
strata deploy run -f deployments/deploy-prd.yaml --stage infrastructure --force
Scenario 2: Deploy just one moduleβs changesο
If you modified only one module and want to redeploy it:
# Edit your module, then re-run Terraform for that module only
strata deploy run -f deployments/deploy-prd.yaml --stage infrastructure --force
Terraform will detect what changed and apply only the diff.
Scenario 3: Deployment takes too longο
If strata deploy run times out or hangs:
Check CI/CD logs for the last output
SSH into the infrastructure or check provisioner logs (Terraform state, Ansible output)
Determine if itβs stuck or just slow
If truly stuck: Manually stop the process, release the lock, and investigate
strata deploy lock release -f deployments/deploy-prd.yaml --force
Scenario 4: Re-run a deployment exactly as it was beforeο
# Show the exact command that was run before (from audit)
strata audit changes --last 1 --output json | jq '.data.stages[] | .provisioner'
# Re-run with the same deployment file
git checkout deploy-prd.yaml # if you've made changes
strata deploy run -f deployments/deploy-prd.yaml --force
Best Practicesο
Always dry-run before deploying to production.
Use
--forcein CI/CD, but never interactively β you wonβt see warnings.Stage your deployments: dev β staging β production. Never deploy directly to production.
Lock deployments in production β set
spec.locking.enabled: trueto prevent concurrent runs.Monitor the audit trail β integrate
strata audit exportinto your SIEM or dashboard for compliance.Keep stages small and focused β one provisioner per stage when possible. Easier to debug failures.
Use lifecycle hooks for notifications β Slack, PagerDuty, etc. β to alert the team during deployments.
Test rollback procedures β know how to recover before you need to.
See Alsoο
How Deployments Work β conceptual model
Environment Composition β layering variables and secrets
Deployment Locking β concurrent deployment prevention
Troubleshooting β diagnosing issues
Commands Reference β deploy β full command documentation