> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ctrlplane.dev/llms.txt
> Use this file to discover all available pages before exploring further.
# Quickstart
> Set up deployment orchestration with environment promotion and verification in 15 minutes.
This guide walks you through setting up a complete deployment pipeline with
staging â production promotion and automated verification. By the end, you'll
have a working example of Ctrlplane's core capabilities.
## What You'll Build
```mermaid theme={null}
flowchart LR
CI["CI (build)"] --> Staging
subgraph Staging["Staging"]
direction TB
S1["Deploy"] --> S2["Verify"]
end
Staging --> Production
subgraph Production["Production"]
direction TB
P0["Approval"] --> P1["Deploy"] --> P2["Verify"]
end
```
* **Deployment** with automatic version creation from CI
* **Two environments** (staging, production) with resource selectors
* **Verification** that checks deployment health before promotion
* **Approval policy** requiring sign-off for production
## Prerequisites
* Ctrlplane account ([app.ctrlplane.dev](https://app.ctrlplane.dev) or
[self-hosted](./installation))
* API key (Settings â API Keys)
* GitHub repository with CI workflow
## Step 1: Create a System
A system groups related deployments. This is typically a product, platform, or
bounded context.
```hcl Terraform theme={null}
resource "ctrlplane_system" "quickstart" {
name = "Tutorial Quickstart"
description = "A tutorial on how to use Ctrlplane found in the Quickstart guide."
}
```
## Step 2: Register Resources
Resources are your deployment targets. In production, you'd sync these from
Kubernetes or cloud providers. For this quickstart, we'll create them manually.
```yaml YAML theme={null}
# ctrlc apply -f resource.yaml
---
type: Resource
identifier: tutorial-quickstart-resource-staging
kind: KubernetesCluster
name: quickstart-staging-cluster
version: tutorial/quickstart/v1
metadata:
tutorial: quickstart
environment: staging
region: us-east-1
config:
number: 1
string: "one"
boolean: true
array:
- one
- two
- three
---
type: Resource
identifier: tutorial-quickstart-resource-production
kind: KubernetesCluster
name: quickstart-production-cluster
version: tutorial/quickstart/v1
metadata:
tutorial: quickstart
environment: production
region: us-east-1
config:
number: 1
string: "one"
boolean: true
array:
- one
- two
- three
```
```hcl Terraform theme={null}
resource "ctrlplane_resource" "quickstart_staging" {
identifier = "tutorial-quickstart-resource-staging"
kind = "KubernetesCluster"
name = "quickstart-staging-cluster"
version = "tutorial/quickstart/v1"
metadata = {
tutorial = "quickstart"
environment = "staging"
region = "us-east-1"
}
config = {
number = 1
string = "one"
boolean = true
array = ["one", "two", "three"]
}
}
resource "ctrlplane_resource" "quickstart_production" {
identifier = "tutorial-quickstart-resource-production"
kind = "KubernetesCluster"
name = "quickstart-production-cluster"
version = "tutorial/quickstart/v1"
metadata = {
tutorial = "quickstart"
environment = "production"
region = "us-east-1"
}
config = {
number = 1
string = "one"
boolean = true
array = ["one", "two", "three"]
}
}
```
```bash theme={null}
ctrlc apply -f https://raw.githubusercontent.com/ctrlplanedev/ctrlplane/main/examples/quickstart/2-resources.yaml
```
## Step 3: Create Environments
Environments use selectors to dynamically match resources. When you add new
clusters with matching metadata, they're automatically included.
```hcl Terraform theme={null}
resource "ctrlplane_environment" "staging" {
name = "Staging"
description = "Pre-production validation"
resource_selector = "resource.metadata['environment'] == 'staging'"
}
resource "ctrlplane_environment" "production" {
name = "Production"
description = "Live production environment"
resource_selector = "resource.metadata['environment'] == 'production'"
}
```
## Step 4: Create a Job Agent
Job agents execute your deployments. We'll use a simple test runner, but
Ctrlplane supports GitHub Actions, Kubernetes jobs, ArgoCD, or custom agents.
```hcl Terraform theme={null}
resource "ctrlplane_job_agent" "quickstart" {
name = "Tutorial Quickstart Job Agent"
description = "A tutorial on how to use Ctrlplane found in the Quickstart guide."
test_runner {
sleep = "5s"
}
}
```
```bash theme={null}
ctrlc apply -f https://raw.githubusercontent.com/ctrlplanedev/ctrlplane/main/examples/quickstart/4-job-agent.yaml
```
## Step 5: Create a Deployment
A deployment represents your application. The job agent config tells Ctrlplane
how to trigger deployments.
```hcl Terraform theme={null}
# Production environment
resource "ctrlplane_deployment" "quickstart" {
name = "Tutorial Quickstart Deployment"
description = "A tutorial on how to use Ctrlplane found in the Quickstart guide."
job_agent {
id = ctrlplane_job_agent.quickstart.id
}
}
```
## Step 6: Add Deployment Workflow
Create `.github/workflows/deploy.yml` in your repository:
```yaml theme={null}
name: Deploy
on:
workflow_dispatch:
inputs:
job_id:
description: "Ctrlplane Job ID"
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get deployment context
uses: ctrlplanedev/get-job-inputs@v1
id: job
with:
job_id: ${{ inputs.job_id }}
api_key: ${{ secrets.CTRLPLANE_API_KEY }}
- name: Deploy to Kubernetes
run: |
echo "Deploying ${{ steps.job.outputs.version_tag }}"
echo "Environment: ${{ steps.job.outputs.environment_name }}"
echo "Cluster: ${{ steps.job.outputs.resource_identifier }}"
# Your deployment logic here
# kubectl set image deployment/api-gateway \
# api-gateway=${{ steps.job.outputs.version_tag }}
```
Add `CTRLPLANE_API_KEY` to your repository secrets.
## Step 7: Integrate CI Build
Add version creation to your build workflow (`.github/workflows/build.yml`):
```yaml theme={null}
- name: Install Ctrlplane CLI
uses: ctrlplanedev/cli@main
with:
api_key: ${{ secrets.CTRLPLANE_API_KEY }}
- name: Create deployment version
if: github.ref == 'refs/heads/main'
run: |
ctrlc api upsert version \
--workspace \
--deployment ${{ secrets.CTRLPLANE_DEPLOYMENT_ID }} \
--tag ${{ github.sha }} \
--name "${{ github.sha::7 }}" \
--metadata github/owner=${{ github.repository_owner }} \
--metadata github/repo=${{ github.event.repository.name }} \
--metadata git/sha=${{ github.sha }} \
--metadata git/branch=${{ github.ref_name }} \
--metadata github/run-number=${{ github.run_number }} \
--metadata github/run-id=${{ github.run_id }} \
--metadata github/run-attempt=${{ github.run_attempt }}
```
## Step 8: Add Production Approval
Create a policy requiring approval before production deployments
```hcl Terraform theme={null}
resource "ctrlplane_policy" "production_approval" {
name = "Production Approval Policy"
description = "Production Approval Policy"
selector {
environments = "environment.metadata['requires-approval'] == 'true'"
}
approval {
required = 1
}
}
```
## Step 9: Test the Pipeline
1. Push a commit to `main`
2. CI builds and creates a version in Ctrlplane
3. Ctrlplane creates releases for staging and production
4. Staging deployment executes immediately
5. Verification runs health checks
6. Production waits for approval
7. After approval, production deploys and verifies
View the pipeline in the Ctrlplane UI:
* **Deployments** â See version progression across environments
* **Releases** â Track release progression across environments
* **Jobs** â View execution details and logs
## What You've Built
â
**Deployment orchestration** with automatic environment progression\
â
**Resource inventory** with metadata-based environment selectors\
â
**Verification** ensuring deployment health before promotion\
â
**Policy gates** requiring approval for production
## Next Steps
Configure gradual rollouts, concurrency limits, and custom gates
Add Datadog metrics, custom HTTP checks, and more
Sync resources from Kubernetes, AWS, or custom providers
Deploy with GitHub Actions, ArgoCD, or custom agents
## Troubleshooting
**Jobs not being created:**
* Verify resource metadata matches environment selectors
* Check deployment has a job agent configured
* Review policy denials in the Releases view
**Verification failing:**
* Test the health endpoint manually
* Check the success condition syntax
* Review measurement data in the verification details
**GitHub workflow not triggering:**
* Ensure job agent type is `github`
* Verify workflow filename matches `jobAgentConfig`
* Check GitHub App permissions
Need help?
[GitHub Discussions](https://github.com/ctrlplanedev/ctrlplane/discussions)