如何通过Terraform传递YAML参数给CloudFormation实现Databrew规则集自定义
实现方案:通过Terraform传递动态规则集到CloudFormation Databrew Ruleset
问题背景
使用Terraform部署CloudFormation栈创建Glue Databrew资源,当前通过遍历数据源列表生成多个栈实例,需要将AWS::DataBrew::Ruleset的Rules部分提取为Terraform参数,实现每个数据源对应独立规则集,同时确认CloudFormation对复杂类型参数的支持能力。
步骤1:调整CloudFormation模板
CloudFormation支持Json类型参数传递复杂结构,需先在模板中声明参数并解析为对象数组:
修改后的完整CloudFormation模板片段
Parameters: # 保留原有参数(Bucket、DataSetKey等) RuleSetName: Type: String Rules: Type: Json Description: 数据源对应的DataBrew质量规则集 Resources: DataBrewDataQualityRuleset: Type: AWS::DataBrew::Ruleset Properties: Name: !Ref RuleSetName Description: Data Quality ruleset Rules: !FromJson !Ref Rules # 将Json字符串解析为规则数组 TargetArn: !Sub SomeArn
说明:
!FromJson是CloudFormation内置函数,用于将Json字符串转换为可识别的对象/数组结构,解决直接!Ref返回字符串无法匹配Rules字段类型的问题。
步骤2:扩展Terraform数据源变量
在Terraform变量data_sources中为每个数据源添加rules字段,存储该数据源专属的规则结构:
Terraform变量定义示例
variable "data_sources" { type = map(object({ stack_name = string job_name = string # 新增rules字段,定义当前数据源的规则集 rules = list(object({ Name = string Disabled = bool CheckExpression = string SubstitutionMap = list(object({ ValueReference = string Value = string })) ColumnSelectors = list(object({ Regex = string })) })) })) description = "数据源列表及对应规则集" }
数据源配置示例
data_sources = { source1 = { stack_name = "source1-datacheck" job_name = "source1-profile" rules = [ { Name = "Check columns for missing values" Disabled = false CheckExpression = "AGG(MISSING_VALUES_PERCENTAGE) == :val1" SubstitutionMap = [ { ValueReference = ":val1" Value = "0" } ] ColumnSelectors = [ { Regex = ".*" } ] } ] }, source2 = { stack_name = "source2-datacheck" job_name = "source2-profile" rules = [ { Name = "Check group value validity" Disabled = false CheckExpression = ":col IN :list" SubstitutionMap = [ { ValueReference = ":col" Value = "`group`" }, { ValueReference = ":list" Value = "[\"Value1\", \"Value2\"]" } ] ColumnSelectors = [] } ] } }
步骤3:更新Terraform CloudFormation资源
在aws_cloudformation_stack的parameters中添加Rules参数,通过jsonencode将Terraform的规则列表转换为合法的Json字符串:
修改后的Terraform资源代码
resource "aws_cloudformation_stack" "databrew_jobs" { for_each = var.data_sources name = "datachecks-${each.value.stack_name}" parameters = { Bucket = "test_bucket" DataSetKey = "raw/${each.value.job_name}" DataSetName = "dataset-${each.value.stack_name}" RuleSetName = "ruleset-${each.value.stack_name}" JobName = "profile-job-${each.value.stack_name}" DataSourceName = each.value.stack_name JobResultKey = "databrew-results/${each.value.job_name}" RoleArn = iam_role_test.arn # 传递规则集:将Terraform对象转换为Json字符串 Rules = jsonencode(each.value.rules) } template_body = file("${path.module}/databrew-job.yaml") }
关键注意事项
- Json格式合法性:
jsonencode会自动处理转义字符(如双引号),确保传递给CloudFormation的参数是标准Json字符串。 - 规则结构匹配:Terraform中定义的
rules结构必须与AWS::DataBrew::Ruleset的Rules字段要求完全一致,避免CloudFormation栈创建失败。 - 测试验证:可先通过
terraform console执行jsonencode(var.data_sources["source1"].rules),检查生成的Json字符串是否符合预期。
内容的提问来源于stack exchange,提问作者Meyer Cohen
相关产品推荐
相关产品推荐

