在多个区域中可变地创建1个或多个AWS Bucket

时间:2020-08-05 14:14:46

标签: amazon-web-services terraform terraform-provider-aws

我正在寻找有关为单个环境中的多个环境和多个区域设置和管理存储桶和存储桶策略创建问题的建议和帮助。

我有4个AWS账户(dev,stg,prod1,prod2,这是prod1的副本)。在prod1中,我们有两个kubernetes集群aws-us-prod1和aws-eu-prod1。这两个集群彼此完全独立,它们仅为这些地区的客户提供服务。

我有一个在这两个不同的集群(aws-us-prod1和aws-eu-prod1)上运行的应用程序,它们需要将内容写入S3存储桶。但是,这两个集群共享一个AWS账户(prod1)。

我正在尝试编写一些terraform资源自动化来管理此操作,但我一直无法可变地控制存储桶放入的区域。latest doc显示有一个{{3} },但由于region attribute实施了提供程序的方式而无法使用。

我想做的是这样的:

variable "buckets" {
    type = map(string) # e.g. buckets='{"a-us-prod1": "us-west-2", "a-eu-prod1":"eu-west-2"}'
}

resource "aws_s3_bucket" "my_buckets" {
    for_each = var.buckets

    bucket = each.key
    region = each.value
}

resource "aws_s3_bucket_policy" "my_buckets_policy" {
    for_each = aws_s3_bucket.my_buckets
    bucket = each.value.id
    policy = ...
}

我尝试使用aws provider region attribute,但是您无法根据要迭代的变量的值以编程方式使用提供程序。组织此项目和资源以实现此目标的正确方法是什么?

我遇到的这些问题与此有关: multiple providers using aliases https://github.com/hashicorp/terraform/issues/3656

1 个答案:

答案 0 :(得分:2)

从2020年7月31日起,region属性刚刚从terraform-provider-aws v3.0.0中的s3_bucket中删除。在此之前,您可以为存储分区设置region,尊重,并且将在该选定区域中创建存储区。但这不是管理其他任何资源的方式,它可能就在那里,因为S3处于全局范围内,并且存储区在arn中没有区域。所有其他服务都使用提供程序本身的区域(应该如此)。

我建议为您可能要支持的所有不同区域创建不同的提供程序,然后根据其区域划分var.buckets,然后为每个区域创建一个resource "aws_s3_bucket" "this_region" { }

variable "buckets" {
    type = map(string) # e.g. buckets='{"a-us-prod1": "us-west-2", "a-eu-prod1":"eu-west-2"}'
}

provider "aws" {
    region = "eu-west-2"
    alias  = "eu-west-2"
}

locals {
    eu_west_2_buckets = [for name, region in var.buckets: name if region == "eu-west-2"]
}

resource "aws_s3_bucket" "eu_west_2_buckets" {
    count   = length(local.eu_west_2_buckets)
    bucket  = eu_west_2_buckets[count.index]
    provider = aws.eu-west-2
}

如果您只想推出与当前部署区域匹配的存储桶,则可以通过简单地更改存储桶过滤逻辑来实现:

variable "buckets" {
    type = map(string) # e.g. buckets='{"a-us-prod1": "us-west-2", "a-eu-prod1":"eu-west-2"}'
}

locals {
    buckets = [for name, region in var.buckets: name if region == data.aws_region.current.name]
}

data "aws_region" "current" { }

resource "aws_s3_bucket" "buckets" {
    count   = length(local.buckets)
    bucket  = buckets[count.index]
}