Skip to main content
Structure your YAML configs and CI workflows to handle multiple environments with shared base definitions and per-environment overrides.

File structure

Separate files per environment

The simplest approach — one file per environment:
devhelm.staging.yml
devhelm.production.yml
Each file is self-contained. Deploy the right file based on the branch or CI environment.

Base + environment files

Share common definitions in a base file and add environment-specific resources in separate files:
config/
  base.yml          # shared channels, policies, tags
  staging.yml       # staging-only monitors
  production.yml    # production-only monitors
Deploy with multiple -f flags:
devhelm deploy -f config/base.yml -f config/staging.yml --yes
Sections from all files are concatenated. Resource names must be disjoint across files — defining the same monitor name in two files is a validation error, not an override. There is no per-resource override merging; to vary a monitor between environments, use environment variables (below) or separate self-contained files. The one exception is defaults.monitors, which shallow-merges across files (later files win per field).

Using environment variables

Share a single file and vary behavior with environment variables:
monitors:
  - name: API Health
    type: HTTP
    config:
      url: ${API_URL}
      method: GET
    frequencySeconds: 300
Set different values in each CI environment:
# Staging
API_URL=https://staging-api.example.com devhelm deploy -f devhelm.yml --yes

# Production
API_URL=https://api.example.com devhelm deploy -f devhelm.yml --yes
${VAR} interpolation only works in string fields (URLs, tokens, names). Numeric fields like frequencySeconds cannot be interpolated — the value would arrive as a string and fail schema validation. To vary frequencies per environment, use separate files per environment.

GitHub Actions

Using environments

jobs:
  deploy:
    strategy:
      matrix:
        env: [staging, production]
    environment: ${{ matrix.env }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: devhelmhq/setup-devhelm@v1
        with:
          api-token: ${{ secrets.DEVHELM_API_TOKEN }}
      - run: devhelm deploy -f devhelm.${{ matrix.env }}.yml --yes

Sequential with approval

jobs:
  deploy-staging:
    environment: staging
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: devhelmhq/setup-devhelm@v1
        with:
          api-token: ${{ secrets.DEVHELM_API_TOKEN }}
      - run: devhelm deploy -f devhelm.staging.yml --yes

  deploy-production:
    needs: deploy-staging
    environment: production
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: devhelmhq/setup-devhelm@v1
        with:
          api-token: ${{ secrets.DEVHELM_API_TOKEN }}
      - run: devhelm deploy -f devhelm.production.yml --yes
Configure the production environment in GitHub Settings to require manual approval.

GitLab CI

.deploy-monitoring:
  image: node:20
  script:
    - npm install -g devhelm
    - devhelm validate devhelm.$CI_ENVIRONMENT_NAME.yml
    - devhelm deploy -f devhelm.$CI_ENVIRONMENT_NAME.yml --yes

deploy-staging:
  extends: .deploy-monitoring
  stage: deploy
  environment: staging
  only: [main]

deploy-production:
  extends: .deploy-monitoring
  stage: deploy
  environment: production
  when: manual
  only: [main]

Terraform

Use Terraform workspaces or separate state files:
terraform workspace select staging
terraform apply -var-file=staging.tfvars

terraform workspace select production
terraform apply -var-file=production.tfvars
Or use separate directories:
terraform/
  staging/
    main.tf
    terraform.tfvars
  production/
    main.tf
    terraform.tfvars

Best practices

  • Separate API tokens per environment for isolation
  • Deploy staging first, then promote to production
  • Use GitHub Environments or equivalent for approval gates on production
  • Pin CLI versions for reproducible builds across environments
  • Keep environment differences minimal — vary URLs and frequencies, not monitor structure

Next steps

GitHub Actions

Full setup-devhelm action reference.

Environments CLI

Manage environments from the command line.