Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: provider erroneously assumes that an empty secret value indicates lack of access. #77

Closed
rtrox opened this issue Feb 18, 2024 · 1 comment · Fixed by #78
Closed

Comments

@rtrox
Copy link

rtrox commented Feb 18, 2024

When managing secrets, if terraform attempts to set a value for a secret that exists, but has an empty value (for example, when creating a resource for a new environment in an existing project), having a nil value for that secret leads the terraform provider to believe it doesn't have access to retrieve it, rather than correctly realizing the secret simply has an empty value.

Reproduction:

  1. Create a new environment in an existing project.
  2. Create a secret in an existing environment via terraform.
  3. Change the secret to point to the new project instead (note that when I did this, I had separate tokens for each of the two projects, with separate terraform configs).
  4. Run terraform apply.

Example of the error:

╷
│ Error: One or more secret fields are restricted: [raw computed]. You must use a service account or service token to manage these resources. Otherwise, Terraform cannot fetch these restricted secrets to check the validity of their state.
│
│   with doppler_secret.cnpg_backup_key_bitty,
│   on b2_bitty_cnpg_backup_bucket.tf line 12, in resource "doppler_secret" "cnpg_backup_key_bitty":
│   12: resource "doppler_secret" "cnpg_backup_key_bitty" {
│
╵

Remediations attempted:

  • Using a personal token
  • Upgrading to teams and using a service account

Successful remediation:
To fix this broken state, I had to set a bogus password value "asdf" through the UI, and then re-run terraform apply.

Provider Configs:

variable "doppler_token" {
  type = string
}

provider "doppler" {
  doppler_token = var.doppler_token
}

provider "doppler" {
  doppler_token = data.doppler_secrets.tf_read.map.DOPPLER_BITTY_WRITE_TOKEN
  alias         = "bty_write"
}

provider "doppler" {
  doppler_token = data.doppler_secrets.tf_read.map.DOPPLER_CHONGUS_WRITE_TOKEN
  alias         = "cho_write"
}

data "doppler_secrets" "tf_read" {
  project = "tf-at-home"
  config  = "prd"
}

relevant secret entry:

resource "doppler_secret" "cnpg_backup_key_bitty" {
  provider = doppler.bty_write
  project  = "k8s-at-home"
  config   = "bty"
  name     = "CNPG_BACKUP_BACKBLAZE_BUCKET"
  value = jsonencode({
    "application_key_id" = module.bb_bucket_k8s_bitty_rtrox_io_cnpg_backup.application_keys["k8s-bitty-rtrox-io-cnpg-backup"].application_key_id,
    "application_key"    = module.bb_bucket_k8s_bitty_rtrox_io_cnpg_backup.application_keys["k8s-bitty-rtrox-io-cnpg-backup"].application_key
    "endpoint"           = module.bb_bucket_k8s_bitty_rtrox_io_cnpg_backup.bucket.endpoint
    "bucket"             = module.bb_bucket_k8s_bitty_rtrox_io_cnpg_backup.bucket.bucket_name
  })
}

This is the relevant code, it seems to naively assume that a nil value means it doesn't have access:

nilFields := []string{}
if secret.Value.Raw == nil {
nilFields = append(nilFields, "raw")
}
if secret.Value.Computed == nil {
nilFields = append(nilFields, "computed")
}
if len(nilFields) > 0 {
return diag.FromErr(fmt.Errorf(
"One or more secret fields are restricted: %v. "+
"You must use a service account or service token to manage these resources. "+
"Otherwise, Terraform cannot fetch these restricted secrets to check the validity of their state.", nilFields))
}

@nmanoogian
Copy link
Member

Thanks for reporting this, @rtrox and I appreciate the detail! It looks like we're missing ForceNew flags for the doppler_secret resource. A doppler_secret can't be moved from one project or config to another, it must be deleted and recreated. We use null values in the fetch secrets API to indicate that a secret's value is restricted but we should never have attempted to fetch the secret if it doesn't exist.

I'll get the fix up shortly 👍 Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants