简体   繁体   中英

Terraform use output variable as an input in another resource

I had a output variable defined in a output.tf file as below:

output "cluster_arn" {
  description = "MSK Cluster ARN"
  value       = aws_msk_cluster.msk.arn
}
data "terraform_remote_state" "msk_vpc" {
  backend = "s3"
  count = var.use_msk_peering ? 1 : 0

  config = {
    bucket = "${var.env}-tf-state"
    key    = "${var.msk_peer_name}/${var.msk_peer_region}/msk/terraform.tfstate"
    region = "us-west-2"
  }
}

What I needed is to use this output as an input in an aws_iam_role_policy resource as I had requirement to limit the assess at specific cluster. What shall I do about it? I tried like this below but Terraform returned an error below.. Seems Terraform was not able to parse the output variable the way I expected.
MalformedPolicyDocument: Resource data.terraform_remote_state.msk_vpc[0].outputs.cluster_arn must be in ARN format or "*".

resource "aws_iam_role_policy" "msk_access" {
  name = "${element(split("-", var.product), 0)}-${var.env}-${var.region}-msk-access"
  role = module.instance_role.instance_role

  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "kafka:Describe*",
                "kafka:List*",
                "kafka:Get*"
            ],
            "Effect": "Allow",
            "Resource": "data.terraform_remote_state.msk_vpc[0].outputs.cluster_arn"              
        }
    ]
}
EOF

}
"Resource": "data.terraform_remote_state.msk_vpc[0].outputs.cluster_arn"

This line does not reference the variable itself, it just creates a string out of what is inside the quotes.

What you have to do is either remove the quotes:

"Resource": data.terraform_remote_state.msk_vpc[0].outputs.cluster_arn

or use string interpolation:

"Resource": "${data.terraform_remote_state.msk_vpc[0].outputs.cluster_arn}"

You could use Terraform's templatefile() function to do some variable interpolation with a JSON file. Something like:

data "terraform_remote_state" "msk_vpc" {
  backend = "s3"
  count   = var.use_msk_peering ? 1 : 0

  config = {
    bucket = "${var.env}-tf-state"
    key    = "${var.msk_peer_name}/${var.msk_peer_region}/msk/terraform.tfstate"
    region = "us-west-2"
  }
}

resource "aws_iam_role_policy" "msk_access" {
  name = "${element(split("-", var.product), 0)}-${var.env}-${var.region}-msk-access"
  role = module.instance_role.instance_role
  policy = templatefile("${path.module}/policy.json", {
    cluster_arn = data.terraform_remote_state.msk_vpc[0].outputs.cluster_arn
  })
}

With an accompanying policy.json that lives in your module root:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "kafka:Describe*",
        "kafka:List*",
        "kafka:Get*"
      ],
      "Effect": "Allow",
      "Resource": "${cluster_arn}"
    }
  ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM