4

I have a Terraform config that looks like this:

resource "random_string" "foo" {
  length = 31
  special = false
}

resource "aws_ssm_parameter" "bar" {
  name = "baz"
  type = "SecureString"
  value = random_string.foo.result
  lifecycle {
    ignore_changes = [value]
  }
}

The idea is that on the first terraform apply the bar resource will be stored in baz in SSM based on the value of foo, and then on subsequent calls to apply I'll be able to reference aws_ssm_parameter.bar.value, however what I see is that it works on the first run, stores the newly created random value, and then on subsequent runs aws_ssm_parameter.bar.value is empty.

If I create a aws_ssm_parameter data source that can pull the value correctly, but it doesn't work on the first apply when it doesn't exist yet. How can I modify this config so I can get the value stored in baz in SSM and work for creating the value in the same config?

Gordon Seidoh Worley
  • 7,839
  • 6
  • 45
  • 82
  • Have you tried storing the value in your state? – Matthew Schuchard May 05 '20 at 10:55
  • The odd thing is that when I pull state I actually see the value stored in there, but then when it gets used it's empty/null. – Gordon Seidoh Worley May 05 '20 at 15:34
  • 1
    Does the IAM user/role you are running Terraform as have access to use the `kms:Decrypt` action with the KMS key that this `SecureString` parameter is encrypted with? There's information on what is required [in the SSM documentation](https://docs.aws.amazon.com/kms/latest/developerguide/services-parameter-store.html#parameter-store-policies). – Martin Atkins May 05 '20 at 22:03
  • I checked and the role I'm using does have `kms:Decrypt`. – Gordon Seidoh Worley May 08 '20 at 21:32

2 Answers2

0

(Sorry not enough karma to comment)

To fix the chicken-egg problem, you could add depends_on = [aws_ssm_parameter.bar] to a data resource, but this introduces some awkwardness (especially if you need to call destroy often in your workflow). It's not particularly recommended (see here).

It doesn't really make sense that it's returning empty, though, so I wonder if you've hit a different bug. Does the value actually get posted to SSM (i.e. can you see it when you run aws ssm get-paramter ...)?

Edit- I just tested your example code above with:

output "bar" {
  value = aws_ssm_parameter.bar.value
}

and it seems to work fine. Maybe you need to update tf or plugins?

  • I thought about trying to add `depends_on` but didn't seem like it would help, but I can try. It does get posted to SSM correctly, the main issue is that on subsequent runs the value of the `bar` resource is empty while I can pull the value from an SSM data source for `baz`. – Gordon Seidoh Worley May 05 '20 at 17:34
  • I should add that I tried this and it didn't help, unfortunately. – Gordon Seidoh Worley May 08 '20 at 17:40
0

Oh, I forgot about this question, but turns out I did figure out the problem.

The issue was that I was creating the ssm parameter inside a module that was being used in another module. The problem was because I didn't output anything related to this parameter, so it seemed to get dropped from state by Terraform on subsequent replans after it was created. Exposing it as output on the module fixed the issue.

Gordon Seidoh Worley
  • 7,839
  • 6
  • 45
  • 82