Skip to content

Remote State and Secrets

Chris Panagiotidis edited this page Jun 13, 2026 · 2 revisions

Remote State And Secrets

Terraform state and GitHub secrets are high-value assets. Treat them as sensitive even in a lab.

State and secrets flow

Source:

Backend Model

The repo uses the AzureRM backend pattern:

  • Storage account holds state.
  • Blob container holds tfstate files.
  • Each environment uses a separate state key.
  • Backend values are supplied in CI.

State key pattern:

<environment>.terraform.tfstate

Examples:

  • cheap-lab.terraform.tfstate
  • lab.terraform.tfstate
  • dev.terraform.tfstate
  • prod.terraform.tfstate

Required State Secrets

Secret Purpose
TF_STATE_RG Resource group containing the state storage account
TF_STATE_SA State storage account name

Authentication uses Azure OIDC secrets:

  • AZURE_CLIENT_ID
  • AZURE_TENANT_ID
  • AZURE_SUBSCRIPTION_ID

State Backup

The state backup action runs before apply and destroy.

Source: .github/actions/state-backup

Behavior:

  • Authenticates with Azure OIDC.
  • Creates backup container before copying state.
  • Skips first-run backup when the source state does not exist yet.
  • Uses Azure RBAC login mode rather than embedding storage keys.

State Storage Hardening

Recommended storage account controls:

  • Disable public blob access.
  • Require HTTPS.
  • Enable versioning.
  • Enable soft delete for blobs.
  • Enable delete retention.
  • Use RBAC rather than account keys where possible.
  • Limit storage account network access.
  • Consider private endpoint for state storage in production-like setups.
  • Monitor state storage access logs.

State File Handling

Do not download, commit, paste, or attach state files to issues. If state must be inspected:

  1. Use a secure workstation.
  2. Limit access to the smallest group possible.
  3. Redact values before sharing observations.
  4. Prefer resource IDs and field names over raw state snippets.
  5. Delete local copies after the review.

Secret Handling Rules

Never put these in committed files:

  • Azure client secrets
  • Service principal passwords
  • VM admin passwords
  • SSH private keys
  • Storage account keys
  • SAS tokens
  • Terraform state
  • .tfplan files containing sensitive values
  • .terraform local provider/cache directories

CI scans:

Local Development

For local validation without Azure state:

terraform init -backend=false
terraform validate

For a real local plan against remote state, configure backend values carefully and do not commit generated backend config files.

Incident Response

If a secret is committed:

  1. Revoke the secret immediately.
  2. Remove it from current code.
  3. Rotate related credentials.
  4. Review GitHub secret scan results.
  5. Consider repository history cleanup only after rotation.
  6. Review access logs for abuse.

Do not rely on deleting a commit as the only mitigation.

Clone this wiki locally