如何通过Terraform触发AWS CloudWatch Synthetics Canary脚本更新?
问题原因
Terraform 默认不会检测 zip_file 指定的本地文件内容变化,仅识别路径是否改变。你当前的 null_resource 用 timestamp() 会触发每次打包,但 Canary 资源因未感知到属性变化,所以不会更新。另外你的打包命令仅包含 node_modules,大概率漏掉了实际脚本文件,导致更新无效。
解决方案
1. 修正打包命令,包含完整脚本与依赖
确保打包命令把脚本所在的整个目录(比如包含脚本和依赖的 nodejs/)全部打包,而非仅打包依赖:
resource "null_resource" "script-zip" { provisioner "local-exec" { command = "zip -r ./recordedScript.zip nodejs/" working_dir = path.module } # 仅在源脚本或依赖变化时重新打包,替代无差别触发的 timestamp() triggers = { script_hash = filebase64sha256("${path.module}/nodejs/index.js") # 多脚本场景可合并哈希:join("", [filebase64sha256("${path.module}/nodejs/index.js"), filebase64sha256("${path.module}/nodejs/utils.js")]) deps_hash = filebase64sha256("${path.module}/nodejs/package-lock.json") # 依赖变动也触发打包 } }
2. 让 Terraform 感知 Canary 脚本变化
在 aws_synthetics_canary 资源中添加基于 zip 文件内容哈希的标签,让 Terraform 检测到内容变化时自动更新 Canary:
resource "aws_synthetics_canary" "canary" { name = var.synthetic-name artifact_s3_location = "s3://${aws_s3_bucket.synthetics-bucket.id}" execution_role_arn = aws_iam_role.synthetics_role.arn handler = var.handler zip_file = "${path.module}/recordedScript.zip" runtime_version = var.runtime-version start_canary = var.start-canary # 通过标签传递 zip 文件哈希,触发资源更新 tags = { ScriptHash = filebase64sha256("${path.module}/recordedScript.zip") } depends_on = [null_resource.script-zip] }
3. 验证更新逻辑
修改脚本或依赖后:
null_resource的triggers会检测到哈希变化,重新执行打包生成新的recordedScript.zipaws_synthetics_canary的tags.ScriptHash会因 zip 内容改变而更新,Terraform 识别到资源属性变化后,自动更新 Canary 脚本,无需销毁重建
补充说明
- 若不想用标签,部分资源支持
triggers块,但aws_synthetics_canary原生无此属性,用标签是最稳妥的方案 - 确保
handler参数正确指向 zip 内的脚本入口(比如index.handler,对应nodejs/index.js里的handler函数)
内容的提问来源于stack exchange,提问作者cloudy-cloud
相关产品推荐
相关产品推荐

