简体   繁体   中英

Reference several aws_iam_policy_document data sources created with for_each in Terraform

I want to create multiple aws_iam_policy_document resources with for_each , to be later assumed by several roles, as follows:

# Policy to allow services to assume the role
data "aws_iam_policy_document" "this" {
  for_each           = var.lambda_configuration
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type = "Service"

      identifiers = [
        "lambda.amazonaws.com",
        "apigateway.amazonaws.com",
      ]
    }
  }
}

# IAM role for executing the Lambda function
resource "aws_iam_role" "this" {
  for_each           = var.lambda_configuration
  name               = "my_lambda_${each.key}_Executor_Role"
  description        = "Role for executing my_lambda-${each.key} function"
  assume_role_policy = data.aws_iam_policy_document.assume_role_policy_[each.key].json
}

How should I interpolate this

assume_role_policy = data.aws_iam_policy_document.assume_role_policy_[each.key].json

to make the correct matching with the roles?

The correct syntax:

data.aws_iam_policy_document.this[each.key].json

Note that this is not interpolation, as you mentioned in your question. It is just a value lookup. And I have no idea where you got assume_role_policy_ from, but that is not valid HCL syntax.

This seems like a good situation for Chaining for_each Between Resources , which (subjectively) tends to lead to a configuration where it's easier for an unfamiliar reader to follow the way data is flowing between the resources.

data "aws_iam_policy_document" "this" {
  for_each = var.lambda_configuration

  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type = "Service"

      identifiers = [
        "lambda.amazonaws.com",
        "apigateway.amazonaws.com",
      ]
    }
  }
}

# IAM role for executing the Lambda function
resource "aws_iam_role" "this" {
  for_each = data.aws_iam_policy_document.this

  name               = "my_lambda_${each.key}_Executor_Role"
  description        = "Role for executing my_lambda-${each.key} function"
  assume_role_policy = each.value.json
}

Using the first resource itself as the for_each for the second one means that the two will always have exactly the same keys (because a resource with for_each appears in expressions as a map of objects using the keys from the for_each map), and that each.value inside the second block refers to the corresponding instance of the first block.

This has essentially the same behavior as using the index operator to select an element from data.aws_iam_policy_document.this using each.key , but makes the relationship between these two resources a little more direct and so (again, subjectively) easier to read and maintain in future.

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