Summary
Currently when running terraform destroy
or terraform apply
after removing 1password provider resources, Terraform destroys any secrets that it has created or imported into state. This behavior can be dangerous or unwanted in the case of a need to preserve secrets outside the Terraform lifecycle.
For example, it could be problematic to import a set of database credentials for use in Terraform only to have them deleted automatically at some point in the future.
It would be preferable to allow users the option to configure what action the Terraform provider takes when an outcome could be the deletion of secrets from 1password vaults.
Use cases
Scenario A:
A user needs to rename Terraform resources to follow a new naming convention (eg: fixing Terraform linting issues where resource names include -
), the resulting vault item title and content of the secret will remain unchanged once the refactoring is complete.
Prior to the terraform apply
, the vault item is imported into a new Terraform resource. While the terraform apply
is occuring, the password must remain available to other consumers of the secret (eg: k8s pods are configured to restart automatically when the secret changes), and thus cannot be removed and recreated.
Scenario B:
A specific vault contains secrets used in a CI/CD environment that validates infrastructure as code changes as part of the PR process. This vault is reused by all CI/CD runners which in turn import certain secrets into Terraform state, and thus must be available any time a PR is submitted or subsequent commits are pushed. Since these secrets are critical to the proper functioning of the CI/CD pipeline, they cannot be removed when terraform destroy
is called.
Proposed solution
Options exist globally for the 1password Terraform provider and within individual provider resources that control what happens in the case of a terraform destroy
or similarly destructive set of circumstances which would result in the deletion of critical 1password secrets.
Internally this might look like a check for the status of the bool at the time the API call is made and act or not act as appropriate. If the state is not to act, a warning should be logged to help users understand what the decision was and hint at why it was made.
Note that more appropriate / better names for these options are welcome.
Provider example:
provider "onepassword" {
url = "http://localhost:8080"
remove_secrets_from_vault_on_destroy = <bool>
}
Resource example:
resource "onepassword_item" "demo_login" {
vault = var.vault_id
remove_from_vault_on_destroy = <bool>
title = "Demo Terraform Login"
category = "password"
username = "demo-username"
password_recipe {
length = 40
symbols = false
}
Is there a workaround to accomplish this today?
The only way to currently solve for this problem today would be to manually remove the resources from Terraform state prior to a destructive action being taken.
This might not always be feasible due to policies around individual contributor rights or when using CI/CD automation tools such as Atlantis.
Additionally, depending on how many secrets are being managed via Terraform or how the code is arranged (eg: when using nested modules), it might be prohibitively complex to attempt manual state manipulation.
References & Prior Work
These are examples of an open issues in Terraform itself looking for ways to "leave resources in place when destroying", some of which are ancient:
These links are not examples of prior work, but they do relate to the problem at hand: