Your First IaC Deployment
Create an IaC project, write Terraform, run a plan, get approval, and deploy — all from the ops0 editor.
Scenario
You want to deploy a new piece of infrastructure (an S3 bucket, EC2 instance, or any cloud resource) using Terraform through ops0, with a full audit trail and optional approval step.
Prerequisites
Step 1: Create a New IaC Project
my-first-project) and optional descriptionStep 2: Configure the State Backend
The state backend is where Terraform stores the record of what it has deployed. This is required before your first deployment.
AWS S3 backend (recommended for AWS):
| Field | Example |
|---|---|
| Bucket | my-terraform-state |
| Key | my-first-project/terraform.tfstate |
| Region | us-east-1 |
| DynamoDB Table | terraform-locks (optional, for state locking) |
ops0 generates the backend.tf block automatically from these values.
Step 3: Link Your Cloud Integration
This tells ops0 which cloud credentials to use when running terraform plan and terraform apply.
Step 4: Write Your Infrastructure Code
The project opens the Monaco editor — the same editor used in VS Code, with full Terraform HCL syntax highlighting, autocomplete, and validation.
You can write code manually or ask the AI assistant to generate it.
Manual — add a new file:
Click New File, name it main.tf, and write your Terraform:
resource "aws_s3_bucket" "example" {
bucket = "my-ops0-tutorial-bucket"
tags = {
Environment = "tutorial"
ManagedBy = "ops0"
}
}
resource "aws_s3_bucket_versioning" "example" {
bucket = aws_s3_bucket.example.id
versioning_configuration {
status = "Enabled"
}
}
AI-assisted — ask the assistant:
Type in the chat panel: "Create an S3 bucket with versioning enabled and a lifecycle rule that transitions objects to Glacier after 90 days" — the AI generates the code and adds it to the editor.
Step 5: Run a Plan
The plan shows what Terraform will create, modify, or destroy — before touching anything.
ops0 runs terraform init then terraform plan in the background. The output streams in real time:
Terraform will perform the following actions:
# aws_s3_bucket.example will be created
+ resource "aws_s3_bucket" "example" {
+ bucket = "my-ops0-tutorial-bucket"
+ tags = { "Environment" = "tutorial" }
}
# aws_s3_bucket_versioning.example will be created
+ resource "aws_s3_bucket_versioning" "example" {
+ bucket = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
Review the plan output carefully. Confirm that only the resources you expect are listed.
Step 6: Approve and Apply
After the plan completes, the deployment moves to Awaiting Approval.
The apply output shows Terraform creating each resource:
aws_s3_bucket.example: Creating...
aws_s3_bucket.example: Creation complete after 3s [id=my-ops0-tutorial-bucket]
aws_s3_bucket_versioning.example: Creating...
aws_s3_bucket_versioning.example: Creation complete after 1s
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Verification
After the apply completes:
- The deployment status shows Succeeded
- Go to your AWS console → S3 — the bucket exists
- Back in ops0, run another Plan — it should show 0 changes (state matches infrastructure)
A clean second plan confirms ops0 is accurately tracking the deployed state.
Next Steps
Troubleshooting
s3:GetObject, s3:PutObject, and s3:ListBucket on the state bucket.