Deploy Terraform code to create, update, or destroy infrastructure. View real-time plan output, cost estimates, and resource outputs.
Check syntax errors before deployment
Sync code to GitHub for version control
Preview what will be created, updated, or destroyed
Check plan output, cost estimate, and policy compliance
Create or update resources in AWS
Preview changes without applying
Execute the planned changes
Delete all managed resources
Deploy specific resources only using -target
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 |
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.
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 |
ops0 provides comprehensive deployment capabilities to safely manage infrastructure changes:
Validate Terraform syntax and configuration before deployment
Enforce security, compliance, and cost policies
Estimate monthly costs and set budget limits
After a successful apply, view output values defined in your code.
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
}
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 |
| Action | Description |
|---|---|
| Copy | Copy value to clipboard |
| Reveal | Show sensitive values (requires permission) |
| Refresh | Re-fetch outputs from state |
Deploy only specific resources instead of the entire project. Useful when you need to fix a single resource without touching the rest of your infrastructure.
When clicking Deploy, expand Advanced Options and enter the resource address in the Target Resources field:
aws_instance.web
module.vpc.aws_subnet.public[0]
aws_security_group.db
Multiple targets can be specified — each on its own line.
| Scenario | Example Target |
|---|---|
| Fix a broken security group | aws_security_group.web |
| Recreate a single instance | aws_instance.app |
| Update one subnet | module.vpc.aws_subnet.private[0] |
| Rebuild a module | module.database |
Targeted deployments can leave your state inconsistent with your code. After a targeted apply, run a full plan to verify the overall state matches your configuration.
Deployments can require manual approval before the apply stage executes. Approvals are configured at the policy level and applied per project.
Attach a policy with approval requirements to your project via IaC → Project Settings → Policies. Once attached, all deployments for that project will require approval.
After clicking Deploy, the plan stage executes automatically.
Apply is held. Designated approvers are notified via configured alert channels (email, Slack).
The approver opens the deployment and reviews:
Approver clicks Approve to proceed or Reject to cancel. A rejection reason can be provided.
After approval, the apply stage runs immediately.
| State | Meaning |
|---|---|
| Awaiting Approval | Plan complete, waiting for approver |
| Approved | Approver approved — apply will run |
| Rejected | Approver rejected — deployment cancelled |
Users with the iac:approve permission on the project can approve deployments. Org admins can always approve.
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.
| Action | Description |
|---|---|
| Download | Save logs as text file |
| Search | Filter log output |
| Auto-scroll | Follow new output in real-time |
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.
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.
Before destroying:
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
}
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)
Every deployment progresses through a series of states from creation to completion.
Deployment created but not yet started. Queued for execution.
Running terraform plan to preview changes.
Plan completed successfully. Ready for apply or awaiting approval.
Deployment requires manual approval before applying changes. Approvers review the plan, cost estimate, and policy results.
Running terraform apply to create/update/destroy resources.
All changes successfully applied. Infrastructure is updated.
| State | Meaning |
|---|---|
| Failed | Plan or apply stage encountered an error |
| Policy Blocked | Changes violate a blocking policy |
| Cancelled | User cancelled the deployment mid-execution |
View the current state in the deployment panel:
View all past deployments for a project, including successful applies, failed attempts, and destroy operations.
Navigate to the IaC project.
Find the deployment selector in the project toolbar.
All deployments are listed chronologically with status indicators.
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 |
Click any deployment to see:
Detailed breakdown of additions, changes, and destructions (+3, ~2, -1)
Previous: $200.00 → New: $262.50 (+31.2%)
Full list of resources created, updated, or destroyed with plan output
Cloud provider, region, integration used, and error messages
Use deployment history to:
See how your infrastructure changed over time.
Compare a failed deployment to the last successful one.
Review who deployed what and when.
Monitor cost changes across deployments.
Watch Terraform execution in real-time with live-streamed logs during plan and apply stages.
Auto-Scroll
Collapsible Stages
Duration Tracking
Status Indicators
Logs stream in real-time using Server-Sent Events (SSE):
terraform init, terraform plan, and terraform apply output[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).
Common causes:
Solution: Review the plan output error message for specific line numbers and error details.
Symptoms: Some resources created, then deployment fails.
What happens:
Recovery steps:
Check:
Solution: Wait 5-10 minutes. If still stuck, contact support to investigate.
Possible causes:
Note: Cost estimates are best-effort. Always verify costs in your cloud provider's billing console.