hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.71k stars 9.07k forks source link

aws_secretsmanager_secret_version uses old data? #7630

Open jeroenjacobs79 opened 5 years ago

jeroenjacobs79 commented 5 years ago

Community Note

Terraform Version

Terraform v0.11.11

Affected Resource(s)

Terraform Configuration Files

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. For
# security, you can also encrypt the files using our GPG public key: https://keybase.io/hashicorp

module/getSecrets/*.tf:

variable "aws_region" {
  description = "AWS region to use"
  default = "us-east-1"
}

variable "aws_profile" {
  description = "AWS profile to use (if any)"
  default = ""
}

variable "secret_id" {
  description = "Specifies the secret containing the version that you want to retrieve. You can specify either the Amazon Resource Name (ARN) or the friendly name of the secret."
}

variable "version_id" {
  description = "Specifies the unique identifier of the version of the secret that you want to retrieve. Overrides version_stage"
  default = ""
}

variable "version_stage" {
  description = "Specifies the secret version that you want to retrieve by the staging label attached to the version. Defaults to AWSCURRENT"
  default = "AWSCURRENT"
}

data "aws_secretsmanager_secret_version" "this" {
  secret_id     = "${var.secret_id}"
  version_stage = "${var.version_stage}"
  version_id    = "${var.version_id}"
}

data "external" "this" {
  program = ["echo", "${data.aws_secretsmanager_secret_version.this.secret_string}"]
}

output "secret_map" {
  value = "${data.external.this.result}"
}

Next, we call this module like this:

locals {
        username_rds_cicd = "${module.secretsmanager-concourse.secret_map["username_cicd"]}"
    password_rds_cicd = "${module.secretsmanager-concourse.secret_map["password_cicd"]}"
}

At a certain time, we renamed the secrets, and we modified the tf code as follows:

locals {
        username_rds_cicd = "${module.secretsmanager-concourse.secret_map["username_rds"]}"
    password_rds_cicd = "${module.secretsmanager-concourse.secret_map["password_rds"]}"
}

Debug Output

NA

Panic Output

NA

Expected Behavior

We expected that the new secrets should be retrieved, instead of the old ones.

Actual Behavior

TerraForm complains about the old not being available, and does not use the new variables:

Error: Error asking for user input: 2 error(s) occurred:

* local.username_rds_cicd: local.username_rds_cicd: key "username_rds" does not exist in map module.secretsmanager-concourse.secret_map in:

${module.secretsmanager-concourse.secret_map["username_rds"]}
* local.password_rds_cicd: local.password_rds_cicd: key "password_rds" does not exist in map module.secretsmanager-concourse.secret_map in:

${module.secretsmanager-concourse.secret_map["password_rds"]}

Steps to Reproduce

Apply TF code listed above.

  1. terraform apply

Important Factoids

References

gtirloni commented 5 years ago

I'm having the same problem in terraform 0.12.7 and terraform-provider-aws 0.25.0

The data in the state file is the old value when terraform first created the secret (using a random value). We've updated the secret through the AWS console but the value in the state isn't refreshed.

It seems the old version ID is tagged with "AWSCURRENT" incorrectly.

$ aws secretsmanager list-secret-version-ids --secret-id 'arn:aws:secretsmanager:us-east-1:0123456789:secret:some_name.OTHER_NAME-abcdef'
{
    "Versions": [
        {
            "VersionId": "0E1D08D5-B66D-4E56-8E51-52B95E176498",
            "VersionStages": [
                "AWSPREVIOUS"
            ],
            "LastAccessedDate": 1566864000.0,
            "CreatedDate": 1565090264.523
        },
        {
            "VersionId": "4207d837-a9cb-433a-a197-32b62b666abc",
            "VersionStages": [
                "AWSCURRENT"
            ],
            "LastAccessedDate": 1566864000.0,
            "CreatedDate": 1566927582.297
        }
    ],
    "ARN": "arn:aws:secretsmanager:us-east-1:0123456789:secret:some_name.OTHER_NAME-abcdef",
    "Name": "some_name.OTHER_NAME"
}

State:

{
    "arn": "arn:aws:secretsmanager:us-east-1:0123456789:secret:some_name.OTHER_NAME-abcdef",
    "id": "arn:aws:secretsmanager:us-east-1:0123456789:secret:some_name.OTHER_NAME-abcdef|0E1D08D5-B66D-4E56-8E51-52B95E176498",
    "secret_binary": "",
    "secret_id": "arn:aws:secretsmanager:us-east-1:0123456789:secret:some_name.OTHER_NAME-abcdef",
    "secret_string": "oldsecretvalue",
    "version_id": "0E1D08D5-B66D-4E56-8E51-52B95E176498",
    "version_stages": [
        "AWSCURRENT"
    ]
}

My reading of resourceAwsSecretsManagerSecretVersionRead() is that it gets the version ID from the resource's ID and that is never updated, apparently.

I tried to remove the secret version from state and import it again while specifying the correct Version ID (the one tagged with AWSCURRENT):

$ terraform state rm aws_secretsmanager_secret_version.default
$ terraform import aws_secretsmanager_secret_version.default 'arn:aws:secretsmanager:us-east-1:0123456789:secret:some_name.OTHER_NAME-abcdef|REPLACE_VERSION_ID_HERE'

But the next plan just shows that the resource has to be recreated because it wants to remove the "AWSCURRENT" stage.

Just to clarify, our workflow is currently as follows:

  1. Use Terraform to create the secret with a random value
  2. Update the secret directly through the AWS console (the secret isn't in the code)
  3. Use the updated values in other places in the infrastructure
github-actions[bot] commented 2 years ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

jsteinich commented 2 years ago

I run into this with the same workflow mentioned by @gtirloni when having secrets backing sns mobile push applications.

x00066949 commented 2 years ago

I am facing the same issue where the secret string was updated outside of terraform and as a result, the Statefile refuses to run the apply because the version id in the state file doesn't match the current version id if the secret string