在Terraform中插入数据源名称

时间:2017-08-19 14:17:54

标签: amazon-web-services amazon-s3 interpolation terraform

我正在尝试编写一个terraform模块,用于将存储桶策略附加到AWS S3存储桶。这是代码:

input_list = [[0,0,0,'P'],[0,0,0,0],[0,'Q',0,0],[0,0,0,0]]

def find_position(input_list, element):
    index = 0
    for sublist in input_list:
        if element in sublist:
            return index
        index += 1
    return None

find_position(input_list, 'P')
OUT: 0

find_position(input_list, 'Q')
OUT: 2

我想在获取data "aws_iam_policy_document" "make_objects_public" { # if policy_name == <this-policy-name>, then generate policy count = "${var.policy_name == "make_objects_public" ? 1 : 0}" statement { ... } } resource "aws_s3_bucket_policy" "bucket_policy" { # if policy_name != "", then add the generated policy count = "${var.policy_name != "" ? 1 : 0}" bucket = "${var.bucket_name}" policy = "${data.aws_iam_policy_document.<policy-name-goes-here>.json}" } 生成的策略时插入policy_name变量。我尝试了很少的东西,但遗憾的是他们没有工作。这可能是地形吗?

我尝试了这些黑客:

aws_iam_policy_document

感谢。

1 个答案:

答案 0 :(得分:3)

不支持动态资源名称,因为Terraform必须在开始处理插值之前构造依赖图,因此这些关系必须是显式的。

这种设置的推荐方法是将系统分解为小模块,然后由调用模块一起使用,以产生所需的结果,而不会复制所有细节。

在这种特殊情况下,您可以将每个策略拆分为自己的可重用模块,然后再编写一个可重用模块,创建一个S3存储桶并将给定策略与之关联。然后,调用配置可以选择性地实例化一个适合其需求的策略模块以及通用S3存储桶模块,以创建所需的结果:

module "policy" {
  # policy-specific module; only contains the policy data source
  source = "../policies/make_objects_public"

  # (any other arguments the policy needs...)
}

module "s3_bucket" {
  # S3 bucket module creates a bucket and attaches a policy to it
  source = "../s3_bucket" # general resource for S3 buckets with attached policies

  name   = "example"
  policy = "${module.policy.policy_json}" # an output from the policy module above
}

除了避免动态资源选择的需要之外,这还通过将策略生成与S3存储桶创建分离来提高灵活性,并且原则上允许具有异常的调用模块需要跳过实例化策略模块完全直接使用aws_iam_policy_document

上述模式有点类似于the dependency injection technique,其中系统被分成小组件(在这种情况下为模块),然后根配置&#34;连线&#34;这些组件以适合特定用例的方式进行。这种方法与一般技术具有非常相似的优点和缺点。