【问题标题】:Variably create 1 or more AWS Buckets across multiple regions跨多个区域可变地创建 1 个或多个 AWS 存储桶
【发布时间】:2020-11-25 17:51:19
【问题描述】:

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

我有 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 表明有一个 region attribute 但它没有'不起作用,因为提供程序是如何使用 aws provider 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 = ...
}

我尝试过使用multiple providers using aliases,但是您不能以编程方式根据您正在迭代的变量的值来使用提供程序。组织此项目和资源以完成此任务的正确方法是什么?

我遇到的这些问题与此有关: https://github.com/hashicorp/terraform/issues/3656 https://github.com/terraform-providers/terraform-provider-aws/issues/5999

【问题讨论】:

  • 我想同时对两个区域应用更改是否是个好主意。如果你要分开这些(也许你的目录结构会变成account/region/cluster 或类似的东西),那么它会变得更简单,并且还能最小化爆炸半径。

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


【解决方案1】:

region 属性刚刚从 2020 年 7 月 31 日起从 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]
}

【讨论】:

  • 如果我想独立运行这些基础设施更改,这种方法不允许我这样做。例如,如果我希望能够独立于eu-prod1 部署到us-prod1,我只需要规划和应用与相应区域相关的资源。那么我该如何处理呢?
  • @Jonathan 这是一个根本不同的要求,你的问题根本没有提到这个要求。但是您可以通过更改 lambdas 的过滤器逻辑来实现这一点,并将其添加到答案中。
  • @luk2303 非常感谢!这就是我一直在寻找的。太好了!
猜你喜欢
  • 1970-01-01
  • 2015-12-02
  • 2020-11-20
  • 2019-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
相关资源
最近更新 更多