尝试将对象放入存储桶时出现间歇性 Terraform 故障

aut*_*ter 1 amazon-s3 amazon-web-services terraform terraform-provider-aws

我看到间歇性的 Terraform 故障在我看来就像是 Terraform 本身内部的竞争条件:

21:31:37 aws_s3_bucket.jar: Creation complete after 1s 
(ID: automatictester.co.uk-my-bucket)
...
21:31:38 * aws_s3_bucket_object.jar: Error putting object in S3 bucket
(automatictester.co.uk-my-bucket): NoSuchBucket: The specified bucket 
does not exist
Run Code Online (Sandbox Code Playgroud)

正如您在上面的日志中看到的那样,TF 首先声称它在 21:31:37 创建了一个存储桶,然后说它不能将对象放入该存储桶中,因为它在 21:31:38 不存在。

上述错误背后的代码:

resource "aws_s3_bucket" "jar" {
  bucket               = "${var.s3_bucket_jar}"
  acl                  = "private"
}
...
resource "aws_s3_bucket_object" "jar" {
  bucket               = "${var.s3_bucket_jar}"
  key                  = "my.jar"
  source               = "${path.module}/../target/my.jar"
  etag                 = "${md5(file("${path.module}/../target/my.jar"))}"
}
Run Code Online (Sandbox Code Playgroud)

显然,这两者之间定义了一种隐式依赖关系,因此我想到的失败的唯一原因是 Amazon S3 的最终一致性。

如何处理此类错误?我相信显式定义的依赖depends-on不会为已经存在的隐式依赖提供任何价值。

yda*_*coR 6

Terraform 在那里根本看不到任何依赖项排序,因此几乎可以肯定地尝试同时执行相同的 2 个操作,并且几乎在存储桶创建的同时创建对象失败。

相反,您应该通过使用depends_on或更好地引用对象资源中存储桶资源的输出来正确定义 2 个资源之间的依赖关系,如下所示:

resource "aws_s3_bucket" "jar" {
  bucket = "${var.s3_bucket_jar}"
  acl    = "private"
}

resource "aws_s3_bucket_object" "jar" {
  bucket = "${aws_s3_bucket.jar.bucket}"
  key    = "my.jar"
  source = "${path.module}/../target/my.jar"
  etag   = "${md5(file("${path.module}/../target/my.jar"))}"
}
Run Code Online (Sandbox Code Playgroud)

Terraform 现在知道它需要等待 S3 存储桶创建并返回,然后才能尝试在存储桶中创建 S3 对象。