terraform-provider-stackgen

sg_secret (Resource)

Manages a secret in the StackGen Vault. Supports sharing with specific users/projects via shared_with or the entire tenant via share_with_tenant.

The resource stores descriptive fields (name, category, description) and actual credential values in sensitive metadata through Vault. Terraform plan/state files may contain those values; protect them.

AWS (subcategory = "aws")

Vault supports two authentication modes via metadata.auth_method:

If Vault-injected keys appear in state after apply for assume-role secrets, use lifecycle { ignore_changes = [metadata["external_id"]] }. See AWS credential rotation.

Other types (including GCP)

Use sg_vault_secret_metadata_keys to discover required metadata keys for each category/subcategory (including gcp). Integrations reference secrets by UUID via secret_ref_ids; they do not own auto-created token secrets such as <integration>-token unless you import those secrets into Terraform. Vault may replace or append duplicate metadata keys depending on the service version — confirm with Vault before rotating overlapping keys. For GCP impersonation, grant the StackGen bastion service account roles/iam.serviceAccountTokenCreator on the customer SA (ask your StackGen operator for the bastion email).

Example Usage

# When to use: Manage StackGen Vault secrets. Credential values in metadata
# also persist in Terraform state; secure state and plans. Create secrets before integrations
# that need secret_ref_ids, and before sg_remote_runner_secrets.
#
# Related: sg_guild_integration.secret_ref_ids, sg_credential_provider (OAuth),
# sg_remote_runner_secrets, data.sg_vault_aws_config (AWS assume-role helpers).
#
# Secret shared with a project (metadata may contain values; secure Terraform state).
resource "sg_project" "consumer" {
  name        = "secret-consumer"
  description = "Project that receives access to the secret."
}

resource "sg_secret" "example" {
  name        = "github-readonly-token"
  description = "Fine-grained PAT for repository reads."
  category    = "scm"
  subcategory = "github"

  shared_with = [sg_project.consumer.id]
}
# AWS cross-account secret (metadata only). Vault injects external_id — do not set it here.
# Use data.sg_vault_aws_config for IAM trust policy setup; see examples/data-sources/sg_vault_aws_config/.
resource "sg_secret" "aws" {
  name        = "prod-aws"
  description = "AWS cross-account read-only integration"
  category    = "CloudProvider"
  subcategory = "aws"
  org_id      = var.stackgen_project_id

  metadata = {
    auth_method  = "assume_role"
    aws_role_arn = var.aws_customer_role_arn # only field to change when rotating roles
    aws_region   = var.aws_region
  }
}

variable "stackgen_project_id" {
  type        = string
  description = "StackGen workspace (project) UUID."
}

variable "aws_customer_role_arn" {
  type        = string
  description = "Customer IAM role ARN Vault assumes (not the StackGen bastion role)."
}

variable "aws_region" {
  type        = string
  description = "Default AWS region for assume-role sessions."
}
# AWS secret using static IAM access keys (no bastion trust policy required).
resource "sg_secret" "aws_access_keys" {
  name        = "prod-aws-keys"
  description = "AWS integration via static IAM access keys"
  category    = "CloudProvider"
  subcategory = "aws"
  org_id      = var.stackgen_project_id

  metadata = {
    auth_method           = "access_keys"
    aws_access_key_id     = var.aws_access_key_id
    aws_secret_access_key = var.aws_secret_access_key
    aws_region            = var.aws_region
  }
}

variable "stackgen_project_id" {
  type        = string
  description = "StackGen workspace (project) UUID."
}

variable "aws_access_key_id" {
  type        = string
  description = "IAM access key ID."
  sensitive   = true
}

variable "aws_secret_access_key" {
  type        = string
  description = "IAM secret access key."
  sensitive   = true
}

variable "aws_region" {
  type        = string
  description = "Default AWS region for API calls."
}
# When to use: Store a GCP service-account credential in Vault for Guild integrations.
# Discover exact metadata keys with data.sg_vault_secret_metadata_keys (subcategory = "gcp").
# Impersonation: grant the StackGen bastion SA roles/iam.serviceAccountTokenCreator on the
# customer SA; ask your StackGen operator for the bastion email for your environment.
#
# Related: data.sg_vault_secret_metadata_keys, sg_guild_integration.secret_ref_ids

data "sg_vault_secret_metadata_keys" "gcp" {
  category    = "CloudProvider"
  subcategory = "gcp"
}

resource "sg_secret" "gcp" {
  name        = "prod-gcp"
  description = "GCP service account for StackGen integrations"
  category    = "CloudProvider"
  subcategory = "gcp"
  org_id      = var.stackgen_project_id

  # Keys must match Vault's supported metadata for subcategory=gcp.
  # Common pattern: service_account_json holds the SA key JSON string.
  metadata = {
    service_account_json = var.gcp_service_account_json
  }
}

variable "stackgen_project_id" {
  type        = string
  description = "StackGen workspace (project) UUID."
}

variable "gcp_service_account_json" {
  type        = string
  sensitive   = true
  description = "GCP service account key JSON. Prefer short-lived impersonation where possible."
}
# Same credential metadata, shared tenant-wide (mutually exclusive with shared_with).
resource "sg_secret" "org_wide" {
  name              = "shared-llm-config"
  description       = "Default LLM endpoint configuration for all teams."
  category          = "scm"
  subcategory       = "github"
  share_with_tenant = true
}

Import

Import an existing sg_secret using its secret UUID or name:

terraform import sg_secret.example '123e4567-e89b-12d3-a456-426614174000'

A secret name can also be used; the provider resolves it to the Vault ID.

Operational notes

Secret metadata may include credential values (including AWS access keys). Terraform state and saved plans can contain them even when output is marked sensitive; use encrypted, access-controlled state. For AWS assume-role secrets, Vault supplies external_id and rotation should change only aws_role_arn. Discover per-type keys with data.sg_vault_secret_metadata_keys. skip_connectivity_check opts out of Vault connectivity verification; only use it if a remote runner can reach the provider. external_secret_references = [] removes all references.

Schema

Required

Optional

Read-Only

Nested Schema for external_secret_references

Required:

Optional: