Skip to content

Initialise Terraform Cloud credentials

Purpose: Establish Terraform Cloud authentication for Terraform/Terragrunt runs (cloud backend).
Owner: Platform operations
Trigger: First-time Terraform Cloud onboarding, token rotation, new workstation/runner bootstrap.
Impact: When using Terraform Cloud state, stacks cannot run without a valid token.
Severity: P2
Pre-reqs: Terraform CLI installed, network access to Terraform Cloud. Vault is optional (only needed if you want HyOps to persist the token into the runtime vault bundle).
Rollback strategy: Revoke token in Terraform Cloud, remove local Terraform credentials, and optionally remove the runtime vault entry.


Context

hyops init terraform-cloud:

  • Reads config from <root>/config/terraform-cloud.conf.
  • Finds a token in this order:
  • runtime vault bundle (<root>/vault/bootstrap.vault.env) when it exists and is decryptable
  • Terraform CLI credentials file (default: ~/.terraform.d/credentials.tfrc.json)
  • optionally runs terraform login when --with-cli-login is set
  • Always writes/updates the Terraform CLI credentials file (mode 0600).
  • Writes a readiness marker: <root>/meta/terraform-cloud.ready.json.
  • Only writes TFC_TOKEN into the runtime vault bundle when either:
  • the vault file already exists, or
  • you pass an explicit vault password source (--vault-password-file/--vault-password-command).
  • Does not create Terraform Cloud workspaces (workspace lifecycle is handled separately).
  • Allows hyops runner blueprint ... to project Terraform Cloud auth into the remote runner job automatically when a valid local runtime token or Terraform CLI credentials file exists.

Notes: - <root> is ~/.hybridops/envs/<env> when you pass --env <env> (recommended). - If you are running with local Terraform state (HYOPS_TERRAFORM_BACKEND_MODE=local), you can skip Terraform Cloud init.


Preconditions and safety checks

  • Confirm required tools exist:
    command -v terraform curl
    

Steps

1) Create config template (first run)
- Command:

hyops init terraform-cloud --env dev
- Expected result: - If config is missing, HyOps writes a template and exits with code 10. - HyOps prints the path to edit and the exact re-run command.

2) Populate config
- File: <root>/config/terraform-cloud.conf - Required: TFC_ORG - Optional: TFC_HOST (Terraform Enterprise), WORKSPACE_PREFIX, TFC_CREDENTIALS_FILE

3) Run init (workstation path)
- Option A (you already ran terraform login previously):

hyops init terraform-cloud --env dev
- Option B (allow HyOps to invoke terraform login):
hyops init terraform-cloud --env dev --with-cli-login

4) Optional: persist token into the runtime vault bundle
This is useful when you want HyOps to keep TFC_TOKEN alongside other per-environment secrets.

  • Prereq (once per workstation):

    hyops vault bootstrap
    hyops vault status-verbose
    

  • Then (explicitly request vault persistence for the environment):

    hyops init terraform-cloud --env dev --vault-password-command 'hyops vault password'
    

5) Optional: create/ensure Terraform Cloud workspaces headlessly (no GUI)
Use this when you want deterministic workspace creation before first terragrunt init/apply.

  • Direct workspace name:

    hyops tfc workspace-ensure platform-gcp-dev-org--gcp--project-factory-gcp-org-00-project-factory-v1-0 \
      --org hybridops-studio --execution-mode local
    

  • Derived workspace name (recommended, keeps dev/shared/... namespaces explicit):

    hyops tfc workspace-ensure \
      --org hybridops-studio --execution-mode local \
      --provider gcp \
      --module-ref org/gcp/project-factory \
      --pack-id gcp/org/00-project-factory@v1.0 \
      --env dev \
      --workspace-prefix hybridops
    

  • Shared environment example:

    hyops tfc workspace-ensure \
      --org hybridops-studio --execution-mode local \
      --provider proxmox \
      --module-ref platform/onprem/platform-vm \
      --pack-id onprem/proxmox/20-platform-vm@v1.0 \
      --env shared \
      --workspace-prefix hybridops
    


Verification

  • Readiness marker exists:

    cat ~/.hybridops/envs/dev/meta/terraform-cloud.ready.json
    

  • Terraform credentials file exists and is locked down:

    ls -la ~/.terraform.d/credentials.tfrc.json
    

  • Optional: verify a workspace exists and is configured without using the TFC GUI:

    hyops tfc workspace-ensure \
      --org hybridops-studio --execution-mode local \
      --provider gcp \
      --module-ref org/gcp/project-factory \
      --pack-id gcp/org/00-project-factory@v1.0 \
      --env dev \
      --workspace-prefix hybridops
    

  • Optional: confirm runner-dispatched jobs can reuse this init without a second remote login:

    hyops runner blueprint preflight --env dev \
      --runner-state-ref platform/linux/ops-runner#gcp_ops_runner_bootstrap \
      --file "$HOME/.hybridops/envs/dev/config/blueprints/gcp-ops-runner.yml"
    

  • If you enabled vault persistence, verify TFC_TOKEN is present in the vault bundle:

    ansible-vault view \
      --vault-password-file <(hyops vault password) \
      ~/.hybridops/envs/dev/vault/bootstrap.vault.env | grep '^TFC_TOKEN='
    


Troubleshooting

ERR: TFC_ORG is required

  • Fix: Set TFC_ORG in <root>/config/terraform-cloud.conf and re-run init.

ERR: Terraform Cloud token not available

  • Fix:
  • Run interactive login:
    terraform login app.terraform.io
    hyops init terraform-cloud --env dev
    
  • Or let HyOps run it:
    hyops init terraform-cloud --env dev --with-cli-login
    

runner remote hyops command failed with Terraform Cloud token hint

  • Cause: the selected runtime has no usable local Terraform Cloud auth for runner dispatch to project into the remote job.
  • Fix:
    hyops init terraform-cloud --env dev --with-cli-login
    
    Then re-run the runner-dispatched blueprint/module command.

ERR: terraform login requires a TTY

  • Cause: you ran with --with-cli-login in a non-interactive context.
  • Fix: run terraform login manually in an interactive shell, then re-run hyops init terraform-cloud.

WARN: vault persistence skipped: ...

  • Cause: you did not explicitly request vault persistence and no vault bundle exists yet under <root>/vault/.
  • Fix: re-run with an explicit vault password source:
    hyops init terraform-cloud --env dev --vault-password-command 'hyops vault password'
    

Terraform Cloud workspace binding mismatch for module state slot ...

  • Cause: the same HyOps module state slot (same module + state_instance) is now deriving a different Terraform Cloud workspace/backend than the prior successful run.
  • Common causes:
  • changed --env / context_id
  • changed WORKSPACE_PREFIX / name_prefix
  • changed TFC_ORG
  • switched backend mode (cloud vs local)
  • Fix (recommended): restore the original naming/backend inputs so the derived workspace matches the existing state slot.
  • Intentional migration only:
    HYOPS_ALLOW_BACKEND_BINDING_DRIFT=1 hyops apply --env <env> --module <module> --inputs <inputs.yml>
    
    Then import/reconcile Terraform resources before continuing normal operations.

workspace policy non-fatal (workspace_not_found): workspace not found (it may not be created yet)

  • Cause: Terragrunt workspace policy checked execution mode, but the workspace does not exist yet.
  • Fix (headless, no GUI):
    hyops tfc workspace-ensure \
      --org hybridops-studio --execution-mode local \
      --provider <provider> \
      --module-ref <module/ref> \
      --pack-id <provider/...@vX.Y> \
      --env <env> \
      --workspace-prefix hybridops
    
    Re-run the HyOps module/blueprint after workspace creation.

Post-actions and clean-up

  • Record the init run_id and evidence path from the command output.
  • If rotating tokens, revoke old tokens after verifying the new token works.

References