Deployments
Deploy Terraform code to create, update, or destroy infrastructure. View real-time plan output, cost estimates, and resource outputs.
Deployment Flow
Validate
Check syntax errors before deployment
Push
Sync code to GitHub for version control
Plan
Preview what will be created, updated, or destroyed
Review
Check plan output, cost estimate, and policy compliance
Apply
Create or update resources in AWS
Deployment Actions
Plan
Preview changes without applying
Apply
Execute the planned changes
Destroy
Delete all managed resources
Plan Output
The plan shows exactly what will change before you apply:
| Symbol | Color | Meaning |
|---|---|---|
+ | Green | Resource will be created |
~ | Yellow | Resource will be updated in-place |
-/+ | Yellow | Resource will be replaced (destroy then create) |
- | Red | Resource will be destroyed |
Example Plan Output
Terraform will perform the following actions:
+ aws_instance.web
ami: "ami-0c55b159cbfafe1f0"
instance_type: "t3.medium"
tags.Name: "production-web"
~ aws_security_group.web
ingress.0.cidr_blocks: ["10.0.0.0/16"] => ["10.0.0.0/8"]
- aws_s3_bucket.old_logs
Plan: 1 to add, 1 to change, 1 to destroy.
Gating Requirements
Deployment requires these checks to pass:
| Requirement | Why |
|---|---|
| Files exist | Nothing to deploy without Terraform code |
| Validation passed | Catch syntax errors before running plan |
| Pushed to GitHub | Version control changes before deployment |
| AWS integration | Valid credentials to access AWS APIs |
Deployment Features
ops0 provides comprehensive deployment capabilities to safely manage infrastructure changes:
Validation
Validate Terraform syntax and configuration before deployment
Policy Checking
Enforce security, compliance, and cost policies
Cost Estimation
Estimate monthly costs and set budget limits
Terraform Outputs
After a successful apply, view output values defined in your code.
Defining Outputs
output "api_endpoint" {
description = "API Gateway endpoint URL"
value = aws_apigatewayv2_api.main.api_endpoint
}
output "database_endpoint" {
description = "RDS cluster endpoint"
value = aws_rds_cluster.main.endpoint
sensitive = true
}
output "bucket_name" {
description = "S3 bucket for uploads"
value = aws_s3_bucket.uploads.id
}
Viewing Outputs
Click Outputs in the toolbar to see all output values:
| Output | Value |
|---|---|
api_endpoint | https://abc123.execute-api.us-east-1.amazonaws.com |
database_endpoint | •••••••• (sensitive) |
bucket_name | myapp-uploads-prod |
Output Actions
| Action | Description |
|---|---|
| Copy | Copy value to clipboard |
| Reveal | Show sensitive values (requires permission) |
| Refresh | Re-fetch outputs from state |
Approval Workflow
If an approval policy is attached to the project:
Auto Plan
Plan runs automatically after clicking Deploy
Awaiting Approval
Apply waits for designated approver
Review
Approver reviews plan, cost estimate, and policy results
Decision
Approver clicks Approve or Reject
Apply
Apply executes after approval
Deployment Logs
View real-time Terraform output during deployment:
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.31.0...
aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 2s [id=vpc-0abc123def456]
aws_subnet.public[0]: Creating...
aws_subnet.public[1]: Creating...
aws_subnet.public[0]: Creation complete after 1s
aws_subnet.public[1]: Creation complete after 1s
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Log Actions
| Action | Description |
|---|---|
| Download | Save logs as text file |
| Search | Filter log output |
| Auto-scroll | Follow new output in real-time |
Cancel Deployment
If a deployment is in progress, click Cancel to interrupt.
Canceling mid-apply may leave resources partially created. The state file will reflect what was actually created. Run plan again to see current status.
Destroy Resources
Click Destroy to delete all resources managed by the project.
Destroy permanently deletes all resources in the state file. This cannot be undone. You must type the project name to confirm destruction.
Destroy Checklist
Before destroying:
- Download any data from S3 buckets
- Export RDS snapshots if needed
- Verify no other systems depend on these resources
- Confirm with team members
Example: Deploying an Application Stack
Initial Deployment
main.tf
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "production"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
}
resource "aws_instance" "app" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.medium"
subnet_id = module.vpc.private_subnets[0]
tags = {
Name = "production-app"
}
}
resource "aws_db_instance" "main" {
identifier = "production-db"
engine = "postgres"
engine_version = "15.4"
instance_class = "db.t3.medium"
allocated_storage = 20
storage_encrypted = true
db_subnet_group_name = module.vpc.database_subnet_group_name
vpc_security_group_ids = [aws_security_group.db.id]
skip_final_snapshot = false
final_snapshot_identifier = "production-db-final"
}
outputs.tf
output "vpc_id" {
description = "VPC ID"
value = module.vpc.vpc_id
}
output "app_private_ip" {
description = "Application server private IP"
value = aws_instance.app.private_ip
}
output "database_endpoint" {
description = "Database connection endpoint"
value = aws_db_instance.main.endpoint
sensitive = true
}
Deployment Result
Plan:
+ module.vpc.aws_vpc.this
+ module.vpc.aws_subnet.private[0]
+ module.vpc.aws_subnet.private[1]
+ module.vpc.aws_subnet.public[0]
+ module.vpc.aws_subnet.public[1]
+ module.vpc.aws_nat_gateway.this
+ aws_instance.app
+ aws_db_instance.main
+ aws_security_group.db
Plan: 9 to add, 0 to change, 0 to destroy.
Cost Estimate:
Monthly Cost Estimate
─────────────────────────────────────
NAT Gateway $32.00/mo
EC2 t3.medium $30.00/mo
RDS db.t3.medium $49.00/mo
RDS Storage (20GB) $2.30/mo
─────────────────────────────────────
Total: $113.30/mo
Outputs After Apply:
vpc_id = "vpc-0abc123def456"
app_private_ip = "10.0.1.47"
database_endpoint = (sensitive value)
Deployment States
Every deployment progresses through a series of states from creation to completion.
State Flow
Pending
Deployment created but not yet started. Queued for execution.
Planning
Running terraform plan to preview changes.
Planned
Plan completed successfully. Ready for apply or awaiting approval.
Awaiting Approval
Deployment requires manual approval before applying changes. Approvers review the plan, cost estimate, and policy results.
Applying
Running terraform apply to create/update/destroy resources.
Completed
All changes successfully applied. Infrastructure is updated.
Error States
| State | Meaning |
|---|---|
| Failed | Plan or apply stage encountered an error |
| Policy Blocked | Changes violate a blocking policy |
| Cancelled | User cancelled the deployment mid-execution |
Checking Deployment Status
View the current state in the deployment panel:
- Status badge - Color-coded indicator (green = running, blue = completed, red = failed)
- Progress indicators - Visual progress for plan and apply stages
- Duration - Time elapsed since deployment started
- Error messages - Detailed error information if deployment failed
Deployment History
View all past deployments for a project, including successful applies, failed attempts, and destroy operations.
Accessing History
Open your project
Navigate to the IaC project.
Click deployment dropdown
Find the deployment selector in the project toolbar.
View past deployments
All deployments are listed chronologically with status indicators.
Deployment Information
Each deployment in history shows:
| Field | Description |
|---|---|
| Deployment # | Sequential numbering (#1, #2, #3...) |
| Type | Deploy or Destroy |
| Status | Completed, Failed, or Cancelled |
| Timestamp | When the deployment was created |
| Duration | Total execution time |
| User | Who triggered the deployment |
| Summary | Resources added, changed, destroyed |
Viewing Deployment Details
Click any deployment to see:
Plan Summary
Detailed breakdown of additions, changes, and destructions (+3, ~2, -1)
Cost Impact
Previous: $200.00 → New: $262.50 (+31.2%)
Resource Changes
Full list of resources created, updated, or destroyed with plan output
Metadata
Cloud provider, region, integration used, and error messages
Comparing Deployments
Use deployment history to:
Track Evolution
See how your infrastructure changed over time.
Debug Issues
Compare a failed deployment to the last successful one.
Audit Changes
Review who deployed what and when.
Cost Tracking
Monitor cost changes across deployments.
Real-Time Deployment Logs
Watch Terraform execution in real-time with live-streamed logs during plan and apply stages.
Log Display Features
Auto-Scroll
- Logs automatically scroll to show the latest output
- Disable auto-scroll to review earlier output without jumping
Collapsible Stages
- Plan and Apply outputs are shown in separate, expandable sections
- Collapse completed stages to focus on active work
Duration Tracking
- Each stage shows elapsed time
- Total deployment duration displayed at completion
Status Indicators
- Running stages pulse with progress animation
- Completed stages show checkmark or error icon
- Failed stages highlight error messages in red
Log Streaming
Logs stream in real-time using Server-Sent Events (SSE):
- Updates every ~500ms during active execution
- Shows
terraform init,terraform plan, andterraform applyoutput - Displays provider downloads and plugin initialization
- Shows resource creation/update/destroy progress
Log Output Example
[Plan Stage - Running]
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.31.0...
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
~ update in-place
- destroy
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {
+ ami = "ami-0c55b159cbfafe1f0"
+ instance_type = "t3.medium"
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
[Plan Stage - Completed in 8.2s]
[Apply Stage - Running]
aws_instance.web: Creating...
aws_instance.web: Still creating... [10s elapsed]
aws_instance.web: Still creating... [20s elapsed]
aws_instance.web: Creation complete after 24s [id=i-0abc123def456]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
[Apply Stage - Completed in 25.1s]
Currently, log search and filtering are not available. To find specific output, use your browser's find function (Ctrl+F or Cmd+F).
Troubleshooting Deployments
Plan fails immediately
Common causes:
- Invalid syntax - Check Terraform validate output for errors
- Missing provider - Ensure provider block is configured
- Invalid credentials - Verify cloud integration is connected
- State lock - Another deployment may be running
Solution: Review the plan output error message for specific line numbers and error details.
Apply fails mid-execution
Symptoms: Some resources created, then deployment fails.
What happens:
- State file reflects resources that were successfully created
- Partially created resources remain in your cloud account
- You can re-run the deployment to continue where it left off
Recovery steps:
- Review apply output to see which resource failed
- Fix the error in your Terraform code (or cloud provider)
- Re-deploy - Terraform will skip successfully created resources
Deployment stuck in "Planning" state
Check:
- Deployment logs for hung operations
- Cloud provider API status (AWS, GCP, Azure)
- Network connectivity from ops0 to cloud provider APIs
Solution: Wait 5-10 minutes. If still stuck, contact support to investigate.
Cost estimate shows $0
Possible causes:
- Resources don't have pricing data (new/preview services)
- Resources are free tier eligible
- Cost estimation service temporarily unavailable
Note: Cost estimates are best-effort. Always verify costs in your cloud provider's billing console.