试图将对象放入存储桶的间歇性Terraform故障

时间:2018-12-17 10:14:21

标签: amazon-web-services amazon-s3 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

如您在上面的日志中看到的,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"))}"
}

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

如何处理此类错误?我相信使用depends-on明确定义的依赖关系将不会提供比已经存在的隐式依赖关系更多的值。

1 个答案:

答案 0 :(得分:2)

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

相反,您应该使用depends_on或更好的方法来正确定义两个资源之间的依赖关系,例如,像这样在对象资源中引用存储桶资源的输出:

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"))}"
}

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