如何避免Terraform apply覆盖CloudFront被CD流水线修改的origin_path值
Terraform CloudFront资源origin_path被外部修改后避免apply回滚的方案
我有如下简单的Cloudfront配置:
resource "aws_cloudfront_distribution" "s3_distribution" { ... origin { domain_name = <bucket domain name> origin_id = <origin id> origin_path = /path/1 } ... }
执行terraform apply后会正常创建CloudFront分发,但创建完成后持续部署流水线会将origin_path从/path/1修改为/path/<another number>。
若我后续对该分发做任何变更后再次执行terraform apply,origin_path会被回滚为/path/1,导致环境故障,请问是否有方案可以避免该问题?
我期望的实现效果类似如下示例:
resource "aws_cloudfront_distribution" "s3_distribution" { ... origin { domain_name = <bucket domain name> origin_id = <origin id> origin_path = creationOnly("/path/1") } ... }
其中creationOnly表示origin_path仅在资源创建时按配置赋值,后续更新操作不会覆盖外部系统修改的实际值。
补充说明
我已知晓lifecycle规则是可行方案,但遗憾的是示例中使用的是单个资源,我实际的问题场景涉及模块调用。
解决方案
针对模块调用场景,你可以将lifecycle规则封装为模块的可配置参数,实现多实例兼容的「创建后忽略origin_path变更」能力,具体实现如下:
- 首先在CloudFront模块的
variables.tf中新增两个控制参数:
variable "ignore_origin_path_changes" { type = bool description = "是否忽略origin_path字段的变更,避免覆盖外部系统修改的值" default = false } variable "default_origin_path" { type = string description = "资源创建时使用的origin_path初始值" default = "/path/1" }
- 调整模块内CloudFront资源的配置,新增动态lifecycle规则:
resource "aws_cloudfront_distribution" "s3_distribution" { ... origin { domain_name = <bucket domain name> origin_id = <origin id> origin_path = var.default_origin_path } ... lifecycle { ignore_changes = var.ignore_origin_path_changes ? [ origin[0].origin_path ] : [] } }
如果你的模块支持配置多个origin,可以将忽略规则调整为匹配所有origin的origin_path:
lifecycle { ignore_changes = var.ignore_origin_path_changes ? [ origin[*].origin_path ] : [] }
- 调用模块时,给需要启用「创建后不覆盖origin_path」能力的实例传入对应参数即可:
module "cloudfront_dist" { source = "./modules/cloudfront" ... ignore_origin_path_changes = true default_origin_path = "/path/1" }
注意事项
- 该方案兼容Terraform 1.2及以上版本,不会破坏模块的通用性,其他不需要忽略origin_path的实例可以正常使用默认配置。
- 后续如果需要主动修改origin_path的值,只需临时将
ignore_origin_path_changes设为false,更新配置后执行apply即可,修改完成后再切回true即可恢复忽略逻辑。
内容的提问来源于stack exchange,提问作者Vitor Falcão
相关产品推荐
相关产品推荐

