如何使用Open Policy Agent (OPA)的Rego规则检测Terraform代码中RDS密码的非法处理行为
用OPA Rego规则检测Terraform RDS密码来源
我来帮你搞定这个问题!要确保RDS实例的密码只能从AWS Secrets Manager获取,而非硬编码或其他未授权来源,我们可以编写针对性的OPA Rego规则来扫描Terraform计划。
完整的Rego规则
创建一个名为rds-password-check.rego的文件,内容如下:
package terraform.aws.security # 规则1:禁止硬编码RDS密码 deny[msg] { resource := input.resource_changes[_] resource.type == "aws_db_instance" resource.mode == "managed" password_val := resource.change.after.password # 识别硬编码字符串(非Terraform引用) not is_reference(password_val) is_string(password_val) msg := sprintf("RDS instance %q uses a hardcoded password. Retrieve credentials from AWS Secrets Manager via `local.db_creds.password` instead.", [resource.name]) } # 规则2:禁止使用非Secrets Manager来源的引用密码 deny[msg] { resource := input.resource_changes[_] resource.type == "aws_db_instance" resource.mode == "managed" # 提取引用的路径值 password_ref := resource.change.after.password.value # 只允许指定的Secrets Manager衍生引用 password_ref != "local.db_creds.password" msg := sprintf("RDS instance %q's password comes from an unapproved source: %q. Use `local.db_creds.password` (from AWS Secrets Manager) instead.", [resource.name, password_ref]) } # 辅助函数:判断是否为Terraform引用对象 is_reference(val) { val.type == "reference" }
规则说明
- 规则1:检查RDS实例的
password字段是否是硬编码的字符串(而非Terraform引用),如果是则触发错误。 - 规则2:检查密码的引用路径是否是你代码中指定的
local.db_creds.password(从Secrets Manager解码后的变量),如果引用了其他变量或路径则触发错误。 - 辅助函数
is_reference:用来识别Terraform计划中表示引用的对象(这类对象会带有type: "reference"属性)。
使用步骤
生成Terraform计划的JSON输出:
先执行Terraform计划并导出为OPA能处理的JSON格式:terraform plan -out=plan.tfplan terraform show -json plan.tfplan > plan.json用OPA执行规则检查:
运行以下命令,让OPA加载规则文件和计划JSON,输出违规结果:opa eval -i plan.json -d rds-password-check.rego "data.terraform.aws.security.deny"
测试场景示例
- ✅ 合规情况:当RDS密码设置为
password = local.db_creds.password时,OPA不会输出任何拒绝消息。 - ❌ 违规情况1:如果密码硬编码为
password = "my-weak-password",规则1会触发错误提示。 - ❌ 违规情况2:如果密码引用了其他变量比如
password = var.db_password,规则2会触发错误提示。
内容的提问来源于stack exchange,提问作者Biju




