# Automate Deployments

Source: https://docs.ops0.com/docs/how-to/automate-deployments

Schedule Terraform deployments, create approval workflows, and set up automated pipelines for infrastructure changes.

---

## Scenario

Your team wants to:
- Automatically deploy changes to staging every night
- Require manager approval before production deployments
- Trigger deployments when PRs are merged
- Get notifications when deployments complete or fail

---

## Prerequisites

- IaC project with Terraform code

- Slack integration (for notifications and approvals)

---

## Option 1: Scheduled Deployments

Deploy automatically on a schedule (e.g., nightly staging updates).

### Create a Scheduled Workflow

1. Click **Workflows** in the sidebar

2. Click **+ New Workflow**

3. Name it: `nightly-staging-deploy`

### Configure the Trigger

Select **Schedule** trigger and set the cron expression:

| Schedule | Cron Expression |
|----------|-----------------|
| Every night at 2 AM | `0 2 * * *` |
| Every Monday at 9 AM | `0 9 * * 1` |
| Every hour | `0 * * * *` |
| First of month | `0 0 1 * *` |

### Add Workflow Steps

```
┌───────────────────────────────────────────────────────────────┐
│  Trigger: Schedule (Daily at 2 AM UTC)                        │
└───────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Step 1: Terraform Plan                                       │
│  Project: staging-infrastructure                              │
│  Action: Plan                                                 │
└───────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Step 2: Terraform Apply                                      │
│  Project: staging-infrastructure                              │
│  Action: Apply                                                │
│  Condition: Only if plan has changes                          │
└───────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Step 3: Notify Slack                                         │
│  Channel: #infrastructure                                     │
│  Message: "Staging deployment complete: {{ result }}"         │
└───────────────────────────────────────────────────────────────┘
```

Click **Save & Enable** to activate the workflow.

---

## Option 2: Approval Workflows

Require human approval before deploying to production.

### Create an Approval Workflow

1. Create a new workflow: `production-deploy`

2. Set trigger to **Manual** or **GitHub PR Merged**

### Workflow with Approval Step

```
┌───────────────────────────────────────────────────────────────┐
│  Trigger: Manual or GitHub (PR merged to main)                │
└───────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Step 1: Terraform Plan                                       │
│  Project: production-infrastructure                           │
└───────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Step 2: Request Approval                                     │
│  Approvers: @platform-team                                    │
│  Notify via: Slack #prod-approvals                            │
│  Timeout: 4 hours                                             │
│  Include: Plan output, cost estimate                          │
└───────────────────────────────────────────────────────────────┘
                              │
                    ┌─────────┴─────────┐
                    │                   │
                    ▼                   ▼
              Approved             Rejected/Timeout
                    │                   │
                    ▼                   ▼
┌──────────────────────┐    ┌──────────────────────┐
│  Step 3: Apply       │    │  Notify: Deployment  │
│                      │    │  cancelled           │
└──────────────────────┘    └──────────────────────┘
                    │
                    ▼
┌───────────────────────────────────────────────────────────────┐
│  Step 4: Notify Success                                       │
│  Channel: #infrastructure                                     │
└───────────────────────────────────────────────────────────────┘
```

### Approval Request in Slack

When the workflow reaches the approval step:

ops0 Bot in #prod-approvals

Production Deployment Approval Required

**Project:** production-infrastructure

**Requested by:** jane@company.com

**Changes:** 2 to add, 1 to change, 0 to destroy

**Cost Impact:** +$45.00/month

Approve

Reject

View Plan

---

## Option 3: Event-Driven Deployments

Deploy automatically when specific events occur.

### Available Triggers

| Trigger | Use Case |
|---------|----------|
| **GitHub PR Merged** | Deploy when code reaches main branch |
| **Webhook** | Trigger from external systems (CI/CD, Slack) |
| **Manual** | On-demand deployment button |
| **Another Workflow** | Chain workflows together |
| **Drift Detected** | Auto-remediate when drift is found |

### Example: Deploy on PR Merge

```
┌───────────────────────────────────────────────────────────────┐
│  Trigger: GitHub                                              │
│  Event: Pull Request Merged                                   │
│  Branch: main                                                 │
│  Path Filter: terraform/**                                    │
└───────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Condition: Check Environment                                 │
│  If: PR labels contain "production"                           │
│      → Go to Production Deploy Path                           │
│  Else:                                                        │
│      → Go to Staging Deploy Path                              │
└───────────────────────────────────────────────────────────────┘
```

---

## Configuring Notifications

Add notifications to any workflow step:

### Slack Notifications

1. Add a **Slack Notification** step

2. Select channel: `#infrastructure`

3. Customize message with variables:

### Available Variables

| Variable | Value |
|----------|-------|
| `{{ workflow.name }}` | Name of the workflow |
| `{{ trigger.user }}` | Who triggered (or "scheduled") |
| `{{ steps.plan.changes }}` | Number of changes in plan |
| `{{ steps.apply.status }}` | Success/Failed |
| `{{ steps.apply.duration }}` | How long apply took |
| `{{ project.name }}` | Project name |

### Example Message Template

```
{{ workflow.name }} completed!

Triggered by: {{ trigger.user }}
Project: {{ project.name }}
Status: {{ steps.apply.status }}
Changes: {{ steps.plan.changes }}
Duration: {{ steps.apply.duration }}

View details: {{ workflow.url }}
```

---

## Monitoring Workflow Runs

### View Execution History

1. Click **Workflows** > select your workflow

2. Click **Runs** tab

3. Click on any run to see step-by-step logs

### Run Status

| Status | Meaning |
|--------|---------|
| **Running** | Currently executing |
| **Waiting** | Waiting for approval |
| **Succeeded** | All steps completed successfully |
| **Failed** | A step failed (click for details) |
| **Cancelled** | Manually stopped or timeout |

---

## Best Practices

Always Plan Before Apply

Even in automated workflows, run plan first. Use conditions to skip apply if no changes.

Use Approvals for Production

Automated staging deploys are fine. Production should have a human checkpoint.

Set Timeouts

Don't let workflows hang forever. Set approval timeouts and step timeouts.

Notify on Failure

Add a notification step that runs on failure so someone knows to investigate.

---

## Next Steps

[Workflow Steps All available step types and configurations](https://docs.ops0.com/docs/workflows/steps)
[Trigger Types Schedule, webhook, and event triggers](https://docs.ops0.com/docs/workflows/triggers)
