0

我想应用以下 Terraformaws_iam_policy_document数据源

  statement {
    sid= "DeleteTmpTable"
    actions = [
      "glue:DeleteTable",
    ]

    resources = [
    "arn:aws:glue:eu-west-1:${data.aws_caller_identity.current.account_id}:table/compan-${terraform.workspace}/*_[0-9]+",
    "arn:aws:glue:eu-west-1:${data.aws_caller_identity.current.account_id}:database/company-${terraform.workspace}",
    "arn:aws:glue:eu-west-1:${data.aws_caller_identity.current.account_id}:catalog"
    ]
  }

所以我只能允许 Glue Delete Table 对像这样的表,table_name_454044243243但像这样的表table_name_blablabla不应该是可删除的。

但我找不到有关可用正则表达式的任何信息。

4

1 回答 1

0

这更像是 AWS IAM 限制,而不是 Terraform 限制。IAM 允许使用多字符通配符 ( *) 或单字符通配符 ( ?),但不允许使用任意正则表达式。

虽然Terraform 支持正则表达式,但这对您没有帮助,因为您需要创建一个不支持的 IAM 策略。

您可以做的一种选择是使用 Terraform 插入受 IAM 策略影响的资源,因此 IAM 策略将逐字列出所有受影响的资源,而不是作为正则表达式或通配符匹配。

如果您使用 Terraform 创建 AWS Glue 表,那么您可以执行以下操作:

variable "tables" {
  default = [
    "table_name_454044243243",
    "table_name_454044243244",
    # ...
  ]
}

resource "aws_glue_catalog_table" "example" {
  for_each      = toset(tables)
  name          = each.key
  database_name = "MyCatalogDatabase"
}

data "aws_iam_policy_document" "example" {
  statement {
    sid= "DeleteTmpTable"

    actions = [
      "glue:DeleteTable",
    ]

    resources = values(aws_glue_catalog_table.example)[*].arn
  }
}

如果您没有使用 Terraform 创建 Glue 表,那么另一种选择是使用外部数据源来使用 AWS CLI 进行封装并获取 Glue 表,该AWS CLI 支持通过正则表达式与--expression参数Boto 3 的get_tables方法进行匹配。未经测试的示例可能如下所示:

data "external" "example" {
  program = ["python", "${path.module}/example-get-tables.py"]

  query = {
    database_name = "MyCatalogDatabase"
    expression    = "compan-${terraform.workspace}/*_[0-9]+"
  }
}

data "aws_iam_policy_document" "example" {
  statement {
    sid= "DeleteTmpTable"

    actions = [
      "glue:DeleteTable",
    ]

    resources = data.external.example.tables
  }
}
#!/usr/bin/env python3
import json
import sys

import boto3

glue_client = boto3.client('glue')
query = json.loads(sys.stdin)

response = glue_client.get_tables(
    DatabaseName=query["database_name"],
    Expression=query["expression"]
)

tables = [table["name"] for table in response["TableList"]]
print(json.dumps("tables": tables))

如果失败了,我强烈建议您更好地命名您的资源,以便您可以*在 IAM 策略中使用通配符匹配,如果您可以控制表的创建方式,即使它只是前缀或后缀。

于 2019-12-17T18:08:18.633 回答