如何有条件地创建 S3 存储桶

How do I conditionally create an S3 bucket

有没有一种方法可以对存储桶(可能创建并存储在不同的状态文件中)使用 terraform 数据调用,然后在数据中没有任何内容的情况下,通过设置计数来创建资源?

我一直在做一些实验并不断得到以下结果:

Error: Failed getting S3 bucket (example_random_bucket_name): NotFound: Not Found
        status code: 404, request id: <ID here>, host id: <host ID here>

要测试的示例代码(已根据生成此错误的原始代码进行了修改):

variable "bucket_name" {
  default = "example_random_bucket_name"
}

data "aws_s3_bucket" "new" {
  bucket = var.bucket_name
}

resource "aws_s3_bucket" "s3_bucket" {
  count = try(1, data.aws_s3_bucket.new.id == "" ? 1 : 0 )
  bucket = var.bucket_name
}

我觉得我应该得到一个空结果而不是生成错误,但事实并非如此。

遗憾的是你不能这样做data sources 必须存在,否则会出错。 TF 中没有构建方式来检查资源是否存在。从某种意义上说,资源可能存在也可能不存在。

如果您需要这样的功能,您必须使用 External Data Source 自行编程。或者可能更简单,提供一个输入变量 bucket_exist,以便您在应用期间显式设置它。

Terraform 是一个理想状态系统,因此您只能描述您想要的结果,而不能 steps/conditions 到达那里。

如果 Terraform did 允许您根据是否已经存在同名的桶来决定是否声明一个桶,您将创建一个永远无法收敛的配置:on第一个 运行,它将不存在,因此您的配置将声明它。但是在第二个 运行,存储桶将存在,因此您的配置将不再声明它,因此 Terraform 将计划销毁它。在第三个运行时,它会建议重新创建它,依此类推。

相反,作为系统设计的一部分,您必须决定哪个 Terraform 配置(或其他系统)负责管理每个对象:

  • 如果您决定特定的 Terraform 配置负责管理此 S3 存储桶,那么您可以使用 无条件 aws_s3_bucket 资源声明它。
  • 如果您决定应该由其他系统来管理存储桶,那么您将编写配置以从其他地方以某种方式了解存储桶名称,例如通过输入变量或使用 aws_s3_bucket 数据源.

数据源被设计为以这种方式失败。

但是,如果您使用来自外部配置的状态文件,则可以根据 s3 存储桶是否由该状态管理并在 [=11] 中使用它,在外部状态中声明一个 output =] 资源作为条件。

例如,外部状态的输出将为空字符串(非托管)或任何 属性 对您有用的值。布尔是另一种选择。从此配置中删除数据源并根据输出向资源添加条件。

如果任何此类变通办法使您的配置复杂化或简化,则由您决定。