Skip to content

Init annex: GCP

Status: Stable (Public)
Version: 1.0

This annex defines GCP-specific requirements and outputs for hyops init gcp.

Global rules are defined in hyops init contract.

1. Config

Default config path:

  • <root>/config/gcp.conf

Config format is line-oriented KEY=value.

1.1 Required keys (non-secret)

  • GCP_PROJECT_ID
    GCP project identifier used for provisioning operations and runtime defaults. This is a runtime bootstrap value, not the preferred long-term source of workload/project intent for state-driven module composition.

  • GCP_REGION
    Default region used by Terraform stacks.

1.2 Optional keys (non-secret)

  • GCP_TERRAFORM_SA_EMAIL (recommended)
    Service account email used as the impersonation target for Terraform (recommended pattern). If unset, interactive init MAY skip impersonation validation (bootstrap-friendly).

  • GCP_ADC_QUOTA_PROJECT_ID (optional)
    Sets ADC quota project via gcloud auth application-default set-quota-project.

  • GCP_TFVARS_OUT (optional)
    Override credentials tfvars output path.

  • GCP_SSH_PUBLIC_KEY (optional)
    Non-secret SSH public key persisted into <root>/meta/gcp.ready.json for runner and GCE VM bootstrap flows. If unset, init SHOULD try to discover ~/.ssh/id_ed25519.pub or ~/.ssh/id_rsa.pub.

2. Vault keys

Default vault path:

  • <root>/vault/bootstrap.vault.env

This init target does not require vault keys by default.

In CI or governed environments, secrets should be provided via standard GCP auth mechanisms (ADC) and/or the runner secret store.

3. Behaviour

3.1 Interactive mode

When interactive flows are permitted (--with-cli-login), the implementation MAY invoke:

  • gcloud auth login (user auth)
  • gcloud auth application-default login (ADC)

If interactive flows are not permitted, init MUST fail fast with guidance.

3.2 Non-interactive mode

When --non-interactive is set:

  • interactive prompts MUST NOT be used
  • init MUST validate that:
  • gcloud is available
  • ADC is available
  • impersonation works for GCP_TERRAFORM_SA_EMAIL (therefore the key MUST be set in non-interactive mode)

3.3 Credential validation

Validation MUST confirm:

  • gcloud auth application-default print-access-token succeeds
  • gcloud auth print-access-token --impersonate-service-account=<...> succeeds when GCP_TERRAFORM_SA_EMAIL is set

If GCP_TERRAFORM_SA_EMAIL is not explicitly set and HyOps only auto-derives a service account from org/gcp/project-factory state, init MAY downgrade back to direct ADC when impersonation validation fails. This keeps env refreshes and non-secret readiness metadata updates possible without forcing impersonation adoption.

4. Outputs

4.1 Credentials tfvars

Default path:

  • <root>/credentials/gcp.credentials.tfvars

The file MUST be mode 0600.

The tfvars file MUST include:

  • project_id
  • region
  • impersonate_service_account (may be empty during bootstrap; required for non-interactive validation)

Downstream modules MAY override or ignore project_id when they consume an authoritative upstream state contract (for example project_state_ref: org/gcp/project-factory).

4.2 Readiness marker

When available, the readiness marker SHOULD include:

  • context.ssh_public_key

This allows GCP VM modules and runner blueprints to consume a public key from init metadata instead of embedding it into shipped blueprint files.

When a module or blueprint uses ssh_keys_from_init: true, it SHOULD NOT also pass explicit ssh_keys. Those inputs are treated as mutually exclusive so the SSH key source of truth remains unambiguous.

Default path:

  • <root>/meta/gcp.ready.json

The marker MUST reflect status=ready only when:

  • validation succeeds, and
  • the credentials tfvars file is written successfully.

4.3 Evidence

Evidence MUST be written under:

  • <root>/logs/init/gcp/<run_id>/

Evidence MUST NOT include access tokens.

5. Failure semantics

  • If interactive authentication is required and fails, init MUST fail with exit code 20.
  • If credentials file writing fails, init MUST fail with exit code 30.