Terraform-provider-aws: Avoid storing aws_ssm_parameter SecureStrings in terraform state

Created on 21 Feb 2018  路  4Comments  路  Source: hashicorp/terraform-provider-aws

I was trying to use the AWS Parameter Store as a way to safely store sensitive data such as passwords, api keys, etc. Creating a parameter of type Secure String looked like a good way to handle this kind of data.

For this work an aws_ssm_resource has been defined using a variable to fill the parameter value, in order to avoid storing it on the VCS:

resource "aws_ssm_parameter" "secret" {
  lifecycle {
    ignore_changes = ["value"]
  }

  type = "SecureString"
  name = "secret"
  value = "${var.secret}"
}

Unfortunately, with that definition the secret value leaks out to the terraform state too, so the sensitive information gets duplicated (as pointed out in the documentation)

Is there any way to avoid such a situation? I was wondering whether saving the value property to the terraform state is strictly required.

question servicssm

Most helpful comment

I'm planing on writing a custom provider plugin to address this issue - a resource representing an SSM parameter without the value attribute at all.

If there's enough interest, I can open a PR here to hopefully add such a feature to the official AWS provider plugin. But ultimately it's up to Hashicorp to decide if they want it.

All 4 comments

I am trying to solve this problem as well and was thinking to go a similar route.

Storing your state in an encrypted backend (ex: S3) would probably solve the issue for you to avoid having those values lying around in the open or committed to VCS if you are currently storing state there.

We're experiencing this as well and as a workaround, you can use a null_resource and local-exec within a module. Kind of hacky since you have to define count = 0 to actually remove the resource - which is a limitation of destroying provisioners at the moment.

Our usecase is to set a "defaut" value in the Paramater Store using Terraform. And then manually update the value from the console to the real secret.

module/main.tf

variable "name"   { default = "/test/terraform/inline" }
variable "type"   { default = "SecureString" }
variable "value"  { default = "default" }
variable "create" { default = true }

resource "null_resource" "ssm_test" {

  count = "${var.create}"
  triggers {
    value_change = "${var.value}"
  }

  provisioner "local-exec" {
    command = "aws ssm put-parameter --name '${var.name}' --value '${var.value}' --type ${var.type} --overwrite"
  }

  provisioner "local-exec" {
    when = "destroy"
    command = "aws ssm delete-parameter --name '${var.name}'"
  }
}

Usage:

// set "create = false" to destroy resource
module "db_password" {
  source = "module"
  name = "/test/terraform/module"
  type = "SecureString"
  value = "default password 2"
  create = true
}

We store our terraform templates in GH, passing the value of password to the module without being encrypted is a security breach. Is there anyway we could pass encrypted data and terraform could decrypt it during the apply ?

I'm planing on writing a custom provider plugin to address this issue - a resource representing an SSM parameter without the value attribute at all.

If there's enough interest, I can open a PR here to hopefully add such a feature to the official AWS provider plugin. But ultimately it's up to Hashicorp to decide if they want it.

Was this page helpful?
0 / 5 - 0 ratings