如何跨配置动态查询aws_cloudfront_origin_access_identity数据源?
场景说明
你在第一套Terraform配置中定义了OAI资源:
resource "aws_cloudfront_origin_access_identity" "example" { comment = "Some comment" }
需要在另一套独立配置中创建CloudFront分发,填充s3_origin_config块下的origin_access_identity字段,但无法直接跨配置引用OAI资源的属性。硬编码OAI ID的方式可维护性差,OAI重建后ID会发生变化,会导致配置失效,对应硬编码写法如下:
data "aws_cloudfront_origin_access_identity" "example" { id = "EDFDVDB123BHDS7" }
可用方案
以下三种方案都可以实现动态查询,不需要硬编码可变的OAI ID:
按唯一固定comment查询OAI
AWS官方Terraform provider的aws_cloudfront_origin_access_identity数据源原生支持通过comment字段筛选查询,你只需要给目标OAI设置全局唯一、不会随意变更的comment值,就能直接定位到对应OAI,不受OAI ID变化影响。注意:必须保证同AWS账号下没有其他OAI使用相同的comment,否则会因查询到多个匹配结果报错
配置示例:# 第一套创建OAI的配置,设置固定唯一comment resource "aws_cloudfront_origin_access_identity" "example" { comment = "prod-shared-s3-oai-2024" # 该值固定后不要随意修改 } # 第二套CloudFront配置中,按comment查询OAI data "aws_cloudfront_origin_access_identity" "example" { comment = "prod-shared-s3-oai-2024" } # 直接引用查询到的路径属性即可 resource "aws_cloudfront_distribution" "s3_distribution" { origin { domain_name = "abcd" origin_id = "foobar" s3_origin_config { origin_access_identity = data.aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path } } }通过Terraform远程状态共享属性
如果两套配置都由你维护,这是生产环境最稳妥的方案:将OAI的目标属性作为输出暴露在创建OAI的配置栈中,CloudFront配置栈直接读取远程状态文件的输出值,不需要依赖OAI的任何业务标识,也不会出现匹配冲突问题。
操作步骤:- 在OAI配置栈中定义输出项:
output "oai_cf_access_path" { value = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path }- 将OAI配置栈的状态存储在支持权限控制的远程后端(比如S3搭配DynamoDB的标准Terraform后端)
- 在CloudFront配置栈中通过
terraform_remote_state数据源读取输出:
data "terraform_remote_state" "oai_stack" { backend = "s3" config = { bucket = "your-terraform-state-bucket-name" key = "oai-stack/terraform.tfstate" region = "us-east-1" # 替换为状态桶实际所在区域 } } resource "aws_cloudfront_distribution" "s3_distribution" { origin { domain_name = "abcd" origin_id = "foobar" s3_origin_config { origin_access_identity = data.terraform_remote_state.oai_stack.outputs.oai_cf_access_path } } }通过AWS托管配置服务中转属性
如果不方便开放远程状态文件的读取权限,可以在OAI配置栈中将OAI的路径属性写入SSM Parameter Store(或Secrets Manager等其他配置存储服务),CloudFront配置栈读取对应配置项即可。
配置示例:- OAI配置栈中写入SSM参数:
resource "aws_ssm_parameter" "oai_access_path" { name = "/infra/shared/cf-oai/access-path" type = "String" value = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path }- CloudFront配置栈中读取SSM参数:
data "aws_ssm_parameter" "oai_access_path" { name = "/infra/shared/cf-oai/access-path" } resource "aws_cloudfront_distribution" "s3_distribution" { origin { domain_name = "abcd" origin_id = "foobar" s3_origin_config { origin_access_identity = data.aws_ssm_parameter.oai_access_path.value } } }
选型参考
- 测试、个人开发环境优先选按comment查询的方案,配置最简单,不需要额外创建其他资源
- 生产环境、多团队协作场景优先选远程状态共享或者SSM中转的方案,稳定性更高,不存在标识冲突风险
- 任何场景都不建议硬编码OAI ID,OAI意外重建后ID变更会直接导致CloudFront配置部署失败
内容的提问来源于stack exchange,提问作者LP13

