> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD Usage

> Automate deployments and resource management with the Control Plane CLI in CI/CD pipelines.

Use the Control Plane CLI in CI/CD pipelines to automate resource provisioning, image builds, and deployments.

## Overview

The CLI enables CI/CD workflows for:

* **Resource provisioning** - Apply GVC, workload, and infrastructure configurations
* **Image delivery** - Build and push container images to Control Plane
* **GitOps** - Maintain infrastructure as code in version control

## Quick start

<Steps>
  <Step title="Create a service account">
    Create a service account with appropriate permissions for your pipeline.

    See [Create a Service Account](#service-account-setup) for details.
  </Step>

  <Step title="Store credentials and context">
    Generate a key and store these environment variables in your CI/CD platform:

    * `CPLN_TOKEN` - The service account key (required)
    * `CPLN_ORG` - Your organization name (recommended)
    * `CPLN_GVC` - Your target GVC name (recommended)

    <Tip>
      Setting `CPLN_ORG` and `CPLN_GVC` as environment variables means you don't need to pass `--org` and `--gvc` flags with every command.
    </Tip>

    <Warning>
      Never print `CPLN_TOKEN` in logs or commit it to version control.
    </Warning>
  </Step>

  <Step title="Install the CLI">
    Install a pinned version of the CLI in your pipeline:

    <Tabs>
      <Tab title="npm">
        ```bash theme={null}
        npm install -g @controlplane/cli@<version>
        cpln --version
        ```
      </Tab>

      <Tab title="Binary">
        Download and extract the binary for your platform. See [Installation](/cli-reference/installation).
      </Tab>
    </Tabs>

    <Info>
      Pin the CLI version for reproducible builds.
    </Info>
  </Step>

  <Step title="Create a profile">
    Create a default profile in your pipeline:

    ```bash theme={null}
    cpln profile create ci --default
    ```

    <Tip>
      When `CPLN_TOKEN` is set as an environment variable, the CLI uses it automatically.
    </Tip>
  </Step>

  <Step title="Run pipeline commands">
    Execute CLI commands to build images and apply resources:

    ```bash theme={null}
    # Build and push image (optional)
    cpln image build --name <image-name>:<image-tag> --push

    # Apply resources
    cpln apply --file resources.yaml
    ```
  </Step>
</Steps>

## Service account setup

### Create the service account

<Tabs>
  <Tab title="Console">
    1. Navigate to **Org** → **Service Accounts**
    2. Click **Create**
    3. Enter a name (e.g., `ci-pipeline`)
    4. Assign to a group with appropriate permissions (e.g., `superusers` or a custom group)
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    cpln serviceaccount create --name ci-pipeline --description "CI/CD automation"
    ```

    Add to a group:

    ```bash theme={null}
    cpln group add-member <group-name> --serviceaccount ci-pipeline
    ```
  </Tab>
</Tabs>

### Generate a key

Create an authentication key for the service account:

<Tabs>
  <Tab title="Console">
    1. Open the service account you created
    2. Click the **Keys** link
    3. Enter a key description (e.g., `ci-pipeline-key`) and click **Add**
    4. Copy and download the generated key securely
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    cpln serviceaccount add-key ci-pipeline --description ci-pipeline-key
    ```

    Save the returned key securely.
  </Tab>
</Tabs>

Store the key in your CI/CD platform's secret manager as `CPLN_TOKEN`.

## Environment variables

Set these variables in your CI/CD platform:

### Required

* `CPLN_TOKEN` - Service account key (keep secret)

### Optional but recommended

* `CPLN_ORG` - Default organization
* `CPLN_GVC` - Default GVC

<CodeGroup>
  ```bash GitHub Actions theme={null}
  env:
    CPLN_TOKEN: ${{ secrets.CPLN_TOKEN }}
    CPLN_ORG: my-org
    CPLN_GVC: production
  ```

  ```bash GitLab CI theme={null}
  variables:
    CPLN_ORG: my-org
    CPLN_GVC: production
  ```

  ```bash CircleCI theme={null}
  environment:
    CPLN_ORG: my-org
    CPLN_GVC: production
  ```
</CodeGroup>

## Common pipeline workflows

### Build and push images

```bash theme={null}
# Build and push
cpln image build --name <image-name>:<image:tag> --push
```

### Apply resources (GitOps)

```bash theme={null}
# Apply a single file
cpln apply --file gvc.yaml

# Apply multiple files
cpln apply --file workload.yaml --file secret.yaml

# Apply from stdin
cat resource.yaml | cpln apply --file -
```

<AccordionGroup>
  <Accordion title="Resource ordering">
    Apply resources in dependency order:

    1. GVCs and policies first
    2. Secrets and identities next
    3. Workloads and domains last

    If a workload depends on a GVC, apply the GVC file before the workload file.
  </Accordion>

  <Accordion title="Multi-document YAML">
    Separate multiple resources with `---` in a single file:

    ```yaml theme={null}
    kind: gvc
    name: my-gvc
    ---
    kind: workload
    name: my-app
    ```

    Apply with:

    ```bash theme={null}
    cpln apply --file resources.yaml
    ```
  </Accordion>

  <Accordion title="Handling renames">
    Renaming a resource in YAML creates a new resource. The old resource must be deleted manually:

    ```bash theme={null}
    cpln <command> delete <old-name>
    ```
  </Accordion>
</AccordionGroup>

### Export existing resources

Export "known good" configurations as templates for GitOps:

<Tabs>
  <Tab title="Console">
    Use the **Export** action to download JSON or YAML.
  </Tab>

  <Tab title="CLI">
    ```bash bash theme={null}
    cpln gvc get <name> --output yaml-slim > gvc.yaml
    cpln workload get <name> --gvc <gvc> --output yaml-slim > workload.yaml
    cpln secret get <name> --output yaml-slim > secret.yaml
    ```
  </Tab>
</Tabs>

<Info>
  Use `json-slim` or `yaml-slim` to remove non-essential properties like IDs, versions, and timestamps. This gives you only what's necessary for applying the resource with `cpln apply`.
</Info>

## Platform-specific examples

Complete working examples for popular CI/CD platforms:

<CardGroup cols={2}>
  <Card title="GitHub Actions" icon="github" href="https://github.com/controlplane-com/github-actions-example-cli">
    Full workflow with build, push, and apply
  </Card>

  <Card title="GitLab CI" icon="gitlab" href="https://gitlab.com/controlplane-com/gitlab-pipeline-example-cli">
    Pipeline configuration for GitLab
  </Card>

  <Card title="Bitbucket Pipelines" icon="bitbucket" href="https://bitbucket.org/controlplane-com/bitbucket-pipeline-example-cli">
    Bitbucket pipeline with Docker build
  </Card>

  <Card title="CircleCI" icon="circle" href="https://github.com/controlplane-com/circle-ci-pipeline-example-cli">
    CircleCI config with multi-stage workflow
  </Card>

  <Card title="Google Cloud Build" icon="google" href="https://github.com/controlplane-com/google-cloud-build-example-cli">
    Cloud Build with Secret Manager
  </Card>
</CardGroup>

## Best practices

<AccordionGroup>
  <Accordion title="Pin the CLI version">
    Specify an exact CLI version for reproducible builds:

    ```bash theme={null}
    npm install -g @controlplane/cli@x.x.x
    ```

    Update the version explicitly when you want to adopt new features.
  </Accordion>

  <Accordion title="Use dedicated service accounts">
    Create separate service accounts for different environments:

    * `ci-dev` for development
    * `ci-staging` for staging
    * `ci-production` for production

    Assign each to groups with scoped permissions.
  </Accordion>

  <Accordion title="Store secrets securely">
    * Use your CI/CD platform's secret manager
    * Never commit tokens to version control
    * Rotate service account keys regularly
    * Avoid printing `CPLN_TOKEN` in logs
  </Accordion>

  <Accordion title="Test in non-production first">
    Apply changes to development or staging environments before production:

    ```bash theme={null}
    # Staging
    cpln apply --file resources.yaml --org staging

    # Production (after staging succeeds)
    cpln apply --file resources.yaml --org production
    ```
  </Accordion>

  <Accordion title="Use slim output for templates">
    Export resources with `yaml-slim` or `json-slim` to remove metadata:

    ```bash theme={null}
    cpln gvc get my-gvc --output yaml-slim > gvc.yaml
    ```

    This creates clean templates suitable for version control and `cpln apply`.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Authentication failures">
    1. Verify `CPLN_TOKEN` is set correctly in your CI/CD secrets
    2. Check the token hasn't expired or been revoked
    3. Ensure the service account has the required permissions
  </Accordion>

  <Accordion title="Wrong org or GVC">
    Verify that the `CPLN_ORG` and `CPLN_GVC` environment variables are set correctly.

    Or explicitly set org and GVC in commands:

    ```bash theme={null}
    cpln apply --file workload.yaml --org my-org --gvc my-gvc
    ```

    Or set in the profile:

    ```bash theme={null}
    cpln profile update ci --org my-org --gvc my-gvc
    ```
  </Accordion>
</AccordionGroup>

<Info>
  For more troubleshooting help, see the [Troubleshooting](/cli-reference/using-cli/troubleshooting) page.
</Info>

## Next steps

<CardGroup cols={2}>
  <Card title="Container Images" href="/cli-reference/ci-cd-development/container-image" icon="docker">
    Use the CLI inside container images
  </Card>

  <Card title="Profiles" href="/cli-reference/get-started/profiles" icon="user">
    Learn about profile management
  </Card>

  <Card title="cpln apply" href="/guides/cpln-apply" icon="code">
    GitOps resource management guide
  </Card>

  <Card title="Service Accounts" href="/guides/create-service-account" icon="key">
    Create and manage service accounts
  </Card>
</CardGroup>
