# Build Your First Workflow

Source: https://docs.ops0.com/docs/how-to/first-workflow

Build a workflow that runs a Terraform plan, waits for approval, applies the infrastructure, and notifies your team — all automated.

---

## Scenario

Your team deploys infrastructure changes manually today. You want to:
- Automate the plan → approve → apply sequence
- Require a human to review and approve the plan before anything is created
- Notify your Slack channel when the deployment completes

---

## Prerequisites

- An IaC project configured and ready to deploy

- Slack integration connected (optional — for the notification step)

---

## Step 1: Create the Workflow

1. Click **Workflows** in the left sidebar

2. Click **+ New Workflow**

3. Name it `Gated IaC Deployment`

4. Set **Trigger Type** to **Manual** for now (you can switch to GitHub or scheduled later)

5. Click **Create**

---

## Step 2: Add Step 1 — IaC Deploy (Plan Only)

1. In the workflow editor, click **Add Step**

2. Select **IaC Deploy** as the step type

Configure the step:

| Field | Value |
|-------|-------|
| **Step Name** | Plan Infrastructure |
| **Project** | Select your IaC project |
| **Execution Mode** | `plan_only` — runs `terraform plan` but does not apply |
| **Auto-Approve Plan** | Off |

Click **Save Step**.

---

## Step 3: Add Step 2 — Approval Gate

1. Click **Add Step** after Step 1

2. Select **Approval** as the step type

Configure the step:

| Field | Value |
|-------|-------|
| **Step Name** | Review Plan |
| **Message** | `Review the Terraform plan output from the previous step. Approve to proceed with apply.` |
| **Approvers** | Add email addresses of engineers who should approve |

Click **Save Step**.

The workflow will pause here and send a notification to the approvers. It waits until someone approves or rejects before continuing.

---

## Step 4: Add Step 3 — IaC Deploy (Apply)

1. Click **Add Step** after the Approval step

2. Select **IaC Deploy**

Configure the step:

| Field | Value |
|-------|-------|
| **Step Name** | Apply Infrastructure |
| **Project** | Same IaC project as Step 1 |
| **Execution Mode** | `plan_and_apply` |
| **Auto-Approve Plan** | On (we already reviewed it in the approval step) |

Click **Save Step**.

---

## Step 5: Add Step 4 — Slack Notification

1. Click **Add Step** after the Apply step

2. Select **Notification**

Configure the step:

| Field | Value |
|-------|-------|
| **Step Name** | Notify Team |
| **Channel** | Slack |
| **Message** | `Deployment complete: {{ workflow.name }} #{{ execution.number }} — Status: {{ previousStep.status }}` |

Click **Save Step**.

---

## Your Completed Workflow

The visual pipeline now shows 4 steps connected in sequence:

```
[Plan Infrastructure] → [Review Plan] → [Apply Infrastructure] → [Notify Team]
      IaC Plan           Approval Gate       IaC Apply             Slack
```

---

## Step 6: Run the Workflow

1. Click **Run** in the workflow toolbar

2. Confirm — the workflow execution starts

Watch the execution progress in real time:

```
Workflow Execution #1: Gated IaC Deployment
──────────────────────────────────────────

  ✓  Step 1: Plan Infrastructure    SUCCEEDED  (42s)
              5 resources to add, 0 to change

  ⏳  Step 2: Review Plan           WAITING FOR APPROVAL
              Approvers notified: alice@company.com

  ...  Step 3: Apply Infrastructure  PENDING
  ...  Step 4: Notify Team           PENDING
```

---

## Step 7: Approve the Plan

The approver receives an email or in-app notification. They:

1. Open the workflow execution
2. Review the plan output from Step 1
3. Click **Approve** (or **Reject** to stop the workflow)

After approval, the workflow continues automatically:

```
  ✓  Step 1: Plan Infrastructure    SUCCEEDED  (42s)
  ✓  Step 2: Review Plan            APPROVED by alice@company.com  (3m 12s)
  ✓  Step 3: Apply Infrastructure   SUCCEEDED  (1m 55s)
              5 resources added
  ✓  Step 4: Notify Team            SUCCEEDED  (3s)
              Slack message sent to #deployments

Workflow Execution #1: SUCCESS  Total: 5m 32s
```

---

## Setting Up Automatic Triggers

Once you've tested the manual workflow, switch to automatic triggers.

**On GitHub PR merge:**

1. Edit the workflow
2. Set Trigger Type to **GitHub**
3. Select your repository and branch (e.g. `main`)
4. The workflow runs automatically every time a PR is merged

**On schedule:**

1. Set Trigger Type to **Scheduled**
2. Enter a cron expression (e.g. `0 2 * * 1` = every Monday at 2am)

---

## Next Steps

[All step types → Shell commands, HTTP requests, Kubernetes deploys, conditions, and more](https://docs.ops0.com/docs/workflows/steps)
[Configure triggers → GitHub events, cron schedules, webhooks, and manual triggers](https://docs.ops0.com/docs/workflows/triggers)

---

## Troubleshooting

Workflow stuck at Approval step

Approvers must have an ops0 account. Check that the email addresses entered match valid organization members. The approver can also approve directly from the Workflows page without needing the email link.

Step 3 (Apply) fails after approval

Ensure the IaC project still has valid cloud credentials. If credentials rotated between the plan and apply steps, re-link the integration. The plan output from Step 1 is re-evaluated at apply time.

Slack notification not sent

Check that your Slack integration is connected in Settings → Integrations → Alerts. Verify the webhook URL is valid by testing it from the integration settings page.
