Skip to content

CI/CD with Other Platforms

The TF_TOKEN_* pattern works on any platform that can set environment variables. See the CI/CD overview for prerequisites and how authentication works.

Spacelift

Based on Spacelift's environment configuration documentation, compliance.tf tokens are configured as follows.

Store the Token

Per stack:

  1. Open your stack in Spacelift
  2. Go to Environment
  3. Click Add Variable
  4. Key: TF_TOKEN_soc2_compliance_tf
  5. Value: paste your token
  6. Check Secret

Organization-wide (recommended):

  1. Go to Contexts in your Spacelift account
  2. Create a new context (e.g., "compliance-tf-credentials")
  3. Add the environment variable TF_TOKEN_soc2_compliance_tf as a secret
  4. Attach the context to all relevant stacks

No Pipeline File Needed

Spacelift handles terraform init, plan, and apply automatically. Once the environment variable is available to the stack, module downloads from the compliance.tf registry work without further configuration.

Reference: Spacelift Contexts

Atlantis

Based on Atlantis server configuration documentation, compliance.tf tokens are configured at the server level.

Store the Token

Atlantis runs Terraform server-side, so the token is configured once on the Atlantis server, not per repository.

Set the environment variable in your Atlantis deployment:

docker-compose.yml (excerpt)
services:
  atlantis:
    image: ghcr.io/runatlantis/atlantis:latest
    environment:
      # compliance.tf registry authentication
      TF_TOKEN_soc2_compliance_tf: "${CTF_TOKEN}"
    # ... other configuration
atlantis-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: atlantis-ctf-token
type: Opaque
stringData:
  TF_TOKEN_soc2_compliance_tf: "ctf_YOUR_TOKEN_HERE"

Reference the secret in your Atlantis deployment's envFrom or env configuration.

Add TF_TOKEN_soc2_compliance_tf to your task definition's secrets block, referencing an AWS Secrets Manager or SSM Parameter Store value.

Optional: Custom Workflow

If you want to add a verification step, define a custom workflow in repos.yaml:

repos.yaml
repos:
  - id: /.*/
    workflow: compliance
workflows:
  compliance:
    plan:
      steps:
        - init
        - plan
    apply:
      steps:
        - apply

Reference: Atlantis custom workflows

env0

Based on env0's variable documentation, compliance.tf tokens are configured as follows.

Store the Token

  1. Go to Organization Settings > Variables (for organization-wide) or your project/environment variables
  2. Click Add Variable
  3. Type: Environment
  4. Key: TF_TOKEN_soc2_compliance_tf
  5. Value: paste your token
  6. Mark as Sensitive

Optional: Custom Flow

If you want to add a verification step, use a Custom Flow:

env0.yml
deploy:
  steps:
    planCommand:
      after:
        - name: Save Plan Output
          command: terraform show -json tfplan > plan.json

Reference: env0 Custom Flows

Jenkins

Store the Token

  1. Go to Manage Jenkins > Credentials
  2. Select the appropriate scope (global or folder)
  3. Click Add Credentials
  4. Kind: Secret text
  5. Secret: paste your token
  6. ID: ctf-token

Configure Your Pipeline

Jenkinsfile
pipeline {
    agent any
    tools {
        terraform 'terraform-1.9'
    }
    stages {
        stage('Init') {
            steps {
                withCredentials([string(credentialsId: 'ctf-token', variable: 'CTF_TOKEN')]) {
                    withEnv(["TF_TOKEN_soc2_compliance_tf=${CTF_TOKEN}"]) {
                        sh 'terraform init'
                    }
                }
            }
        }
        stage('Plan') {
            steps {
                withCredentials([string(credentialsId: 'ctf-token', variable: 'CTF_TOKEN')]) {
                    withEnv(["TF_TOKEN_soc2_compliance_tf=${CTF_TOKEN}"]) {
                        sh 'terraform plan -out=tfplan'
                    }
                }
            }
        }
        stage('Apply') {
            when {
                branch 'main'
            }
            steps {
                withCredentials([string(credentialsId: 'ctf-token', variable: 'CTF_TOKEN')]) {
                    withEnv(["TF_TOKEN_soc2_compliance_tf=${CTF_TOKEN}"]) {
                        sh 'terraform apply -auto-approve tfplan'
                    }
                }
            }
        }
    }
}

Reference: Jenkins credentials handling

CircleCI

Store the Token

Add CTF_TOKEN as an environment variable in your CircleCI project or in a shared context:

  1. Open your project in CircleCI
  2. Go to Project Settings > Environment Variables
  3. Click Add Environment Variable
  4. Name: CTF_TOKEN
  5. Value: paste your token
  1. Go to Organization Settings > Contexts
  2. Create a new context (e.g., compliance-tf)
  3. Add the environment variable CTF_TOKEN
  4. Reference the context in your workflow jobs

Configure Your Pipeline

.circleci/config.yml
version: 2.1

orbs:
  terraform: hashicorp/terraform@1.0

jobs:
  terraform-plan:
    docker:
      - image: hashicorp/terraform:1.12
    steps:
      - checkout
      - run:
          name: Terraform Init
          command: |
            export TF_TOKEN_soc2_compliance_tf="${CTF_TOKEN}"
            terraform init
      - run:
          name: Terraform Validate
          command: terraform validate
      - run:
          name: Terraform Plan
          command: |
            export TF_TOKEN_soc2_compliance_tf="${CTF_TOKEN}"
            terraform plan -out=tfplan
      - persist_to_workspace:
          root: .
          paths:
            - .

  terraform-apply:
    docker:
      - image: hashicorp/terraform:1.12
    steps:
      - attach_workspace:
          at: .
      - run:
          name: Terraform Apply
          command: |
            export TF_TOKEN_soc2_compliance_tf="${CTF_TOKEN}"
            terraform apply -auto-approve tfplan

workflows:
  infrastructure:
    jobs:
      - terraform-plan:
          context: compliance-tf
      - hold-apply:
          type: approval
          requires:
            - terraform-plan
          filters:
            branches:
              only: main
      - terraform-apply:
          context: compliance-tf
          requires:
            - hold-apply
          filters:
            branches:
              only: main

The hold-apply job is a built-in approval gate — the apply step will not run until a team member manually approves it in the CircleCI dashboard.

Reference: CircleCI contexts, CircleCI environment variables

Azure DevOps

Store the Token

Add CTF_TOKEN as a secret pipeline variable or in a shared variable group:

  1. Open your pipeline in Azure DevOps
  2. Click Edit > Variables
  3. Click New Variable
  4. Name: CTF_TOKEN
  5. Value: paste your token
  6. Check Keep this value secret
  1. Go to Pipelines > Library
  2. Click + Variable group
  3. Name the group (e.g., compliance-tf-credentials)
  4. Add CTF_TOKEN and mark it as secret
  5. Reference the group in any pipeline that needs registry access

Configure Your Pipeline

azure-pipelines.yml
trigger:
  branches:
    include:
      - main
      - feature/*

pool:
  vmImage: ubuntu-latest

variables:
  - group: compliance-tf-credentials

stages:
  - stage: Plan
    displayName: Terraform Plan
    jobs:
      - job: TerraformPlan
        steps:
          - task: TerraformInstaller@1
            displayName: Install Terraform
            inputs:
              terraformVersion: latest

          - script: |
              export TF_TOKEN_soc2_compliance_tf="$(CTF_TOKEN)"
              terraform init
            displayName: Terraform Init

          - script: terraform validate
            displayName: Terraform Validate

          - script: |
              export TF_TOKEN_soc2_compliance_tf="$(CTF_TOKEN)"
              terraform plan -out=tfplan
            displayName: Terraform Plan

          - publish: $(System.DefaultWorkingDirectory)/tfplan
            artifact: tfplan
            displayName: Publish Plan Artifact

  - stage: Apply
    displayName: Terraform Apply
    dependsOn: Plan
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: TerraformApply
        environment: production
        strategy:
          runOnce:
            deploy:
              steps:
                - download: current
                  artifact: tfplan

                - task: TerraformInstaller@1
                  displayName: Install Terraform
                  inputs:
                    terraformVersion: latest

                - script: |
                    export TF_TOKEN_soc2_compliance_tf="$(CTF_TOKEN)"
                    terraform init
                  displayName: Terraform Init

                - script: |
                    export TF_TOKEN_soc2_compliance_tf="$(CTF_TOKEN)"
                    terraform apply -auto-approve $(Pipeline.Workspace)/tfplan/tfplan
                  displayName: Terraform Apply

The Apply stage uses a deployment job targeting the production environment. Configure Approvals and checks on that environment to require manual approval before apply runs.

Reference: Azure DevOps variable groups, Azure DevOps environments

Generic / Other

The TF_TOKEN_* environment variable pattern works on any CI/CD platform that can set environment variables and run shell commands. This includes AWS CodeBuild, Buildkite, Drone, Harness, and Codefresh.

The Pattern

  1. Store your compliance.tf token as a secret in your CI/CD platform
  2. Expose it as an environment variable named TF_TOKEN_soc2_compliance_tf
  3. Run terraform init — Terraform picks up the token automatically
Generic pipeline script
# The CI/CD platform injects CTF_TOKEN from its secret store
export TF_TOKEN_soc2_compliance_tf="${CTF_TOKEN}"

terraform init
terraform validate
terraform plan -out=tfplan

Alternative: Dynamic .terraformrc

If your platform does not support environment variable names with underscores, you can write a credentials file dynamically:

Write and clean up .terraformrc
# Write credentials file (token comes from CI secret store)
cat > ~/.terraformrc <<EOF
credentials "soc2.compliance.tf" {
  token = "${CTF_TOKEN}"
}
EOF

terraform init
terraform plan -out=tfplan

# Clean up credentials file
rm -f ~/.terraformrc

Clean up credentials files

If you write a .terraformrc file dynamically, delete it at the end of the pipeline run. Do not leave credentials on shared build agents.