cloudposse / terraform-aws-ecs-container-definition

Terraform module to generate well-formed JSON documents (container definitions) that are passed to the aws_ecs_task_definition Terraform resource
https://cloudposse.com/accelerate
Apache License 2.0
339 stars 244 forks source link

[BUG] - Sensitive values causing error in Terraform apply #109

Closed ghost closed 3 years ago

ghost commented 3 years ago

Dear all,

I came across this error in terraform 0.14.3. I believe it has something to do with it here.

https://www.terraform.io/upgrade-guides/0-14.html#sensitive-values-in-plan-output

Error: Error in function call

  on .terraform/modules/prizor-chatbot-campaign-worker/main.tf line 6, in locals:
   6:   env_vars_as_map      = zipmap(local.env_vars_keys, local.env_vars_values)
    |----------------
    | local.env_vars_keys is (sensitive value)
    | local.env_vars_values is (sensitive value)

Call to function "zipmap" failed: panic in function implementation: value is
marked, so must be unmarked first
mikedizon commented 3 years ago

@0xdutra i'm having the same issue. what was the fix?

jhole89 commented 3 years ago

Same here, @0xdutra did you find a workaround?

ghost commented 3 years ago

@jhole89 unfortunately not yet, I'm using 0.13.5 :/

jhole89 commented 3 years ago

@0xdutra @mikedizon I managed to use a workaround via secretsmanager (TF v0.14.3, AWS provider v3.24.0, cloudposse/ecs-container-definition v0.46.1).

When previously I had the value stored in the environment block (causing the panic), you can avoid this by moving the value into secretsmanager and passing this arn to the secrets block - but you need to give the execution_role_arn permission to access this, e.g.:

resource "aws_secretsmanager_secret" "foo" {
  name  = "sensitive_foo"
}

resource "aws_secretsmanager_secret_version" "foo" {
  secret_id     = aws_secretsmanager_secret.foo.id
  secret_string = "I am the sensitive value - I most likely come from some other terraform resource"
}

module "container_definition" {
  source  = "cloudposse/ecs-container-definition/aws"
  version = "0.46.1"

  ...
  ...

  environment = []
  secrets = [
    {
      name : "MY_ENVAR_KEY",
      valueFrom : aws_secretsmanager_secret.foo.arn
    },
  ]
}

data "aws_iam_policy_document" "allow_secrets_access" {     // <-- Attach this to your ecs_execution_role
  statement {
    actions = [
      "secretsmanager:GetSecretValue",
    ]
    resources = [
      aws_secretsmanager_secret.foo.arn,
    ]
  }
}

An additional note is that if you use kms to securely store secrets, you'd also need to give "kms:Decrypt", "kms:DescribeKey", "kms:GenerateDataKey" to the kms key used for the secret to the ecs_execution_role, something like:

data "aws_iam_policy_document" "allow_kms" {
  statement {
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:GenerateDataKey",
    ]
    resources = [
      aws_kms_key.sensitive_foo.arn,
    ]
  }