[英]Terraform S3 Bucket Object's etag keeps updating on each apply
我正在将 AWS Lambda 代码作为 zip 文件上传到 S3 存储桶中。
我为 S3 存储桶 object 声明了一个资源:
resource "aws_s3_bucket_object" "source-code-object" {
bucket = "${aws_s3_bucket.my-bucket.id}"
key = "source-code.zip"
source = "lambda_source_code/source-code.zip"
etag = "${base64sha256(file("lambda_source_code/source-code.zip"))}"
}
我的代码中还有一个数据声明为 zip:
data "archive_file" "source-code-zip" {
type = "zip"
source_file = "${path.module}/lambda_source_code/run.py"
output_path = "${path.module}/lambda_source_code/source-code.zip"
}
terraform apply
output 不断向我显示对 hash 的更改:
~ aws_s3_bucket_object.source-code-object
etag: "old_hash" => "new_hash"
即使我的源代码中没有任何更改。 为什么会出现这种行为? 我看过类似的帖子,其中 Lambdas 的源代码不断变化,但我的 Lambdas 实际上并没有每次都更新(上次更新时间在控制台中检查)。 然而,它看起来像一个新的 S3 bucket object 被上传到每个apply
。
Zip归档默认包含元数据,例如时间戳,这导致散列不同,即使源文件不是。 手动构建存档时,可以使用--no-extra
或-X
标志来避免这种情况。 我不确定Terraform是否支持这个标志。
从zip手册页:
-X
不要保存额外的文件属性(OS / 2上的扩展属性,Unix上的uid / gid和文件时间)。 zip格式使用额外字段来包含每个条目的附加信息。 一些额外字段特定于特定系统,而其他字段适用于所有系统。 通常,当zip从现有存档中读取条目时,它会读取它知道的额外字段,删除其余字段,并添加适用于该系统的额外字段。 使用-X,zip会删除所有旧字段,并且只包含Unicode和Zip64额外字段(目前这两个额外字段无法禁用)。
否定此选项-X-包括所有默认的额外字段,但也会复制任何无法识别的额外字段。
为防止每次应用更新,使用新的aws_s3_object
资源,您可以使用output_base64sha256
属性引用。
aws_s3_bucket_object 数据源已弃用,将在未来版本中删除,请改用 aws_s3_object。 将添加新功能和修复程序的地方。
data "archive_file" "source-code-zip" {
type = "zip"
source_file = "${path.module}/lambda_source_code/run.py"
output_path = "${path.module}/lambda_source_code/source-code.zip"
}
resource "aws_s3_object" "source-code-object" {
bucket = aws_s3_bucket.my-bucket.id
key = "source-code.zip"
# we can also reference `output_path` from `archive_file`
# so as not to repeat the path
source = data.archive_file.source-code-zip.output_path
source_hash = data.archive_file.source-code-zip.output_base64sha256
}
正如@Matt F 指出的那样, output_base64sha256
具有处理使用 KMS 加密的 s3 对象的额外好处。
默认情况下,您的 S3 存储桶可能使用 KMS 密钥来应用加密。 以这种方式配置时, etag
不是文件内容 (doc ) 的 MD5。
由 PUT 对象、POST 对象或复制操作或通过 AWS 管理控制台创建并由 SSE-C 或 SSE-KMS 加密的对象具有不是其对象数据的 MD5 摘要的 ETag。
在不知道它们的散列实现的情况下,没有办法预先计算 terraform 的值并使其成为一个稳定的计划。
相反,您应该使用source_hash
属性来解决此限制。
我将etag
替换为source_hash
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object#source_hash最后得到:
No changes. Your infrastructure matches the configuration.
hash 存储在 tf state 而不是 aws 中。 就像它在文档中说的那样:
Triggers updates like etag but useful to address etag encryption limitations. Set using filemd5("path/to/source") (Terraform 0.11.12 or later). (The value is only stored in state and not saved by AWS.)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.