跳转至

Ch 25 环境参数与 tfvars 模型

项目第 1 年 · 核心建设期——参数模型


本章你将学到

  • 环境级参数文件与按服务拆分 tfvars 策略(含 glue-all.tfvars / dev-all.tfvars 真实片段)
  • 运行时配置 vs 部署参数的边界
  • 后端配置多环境隔离(含 dev/prod.tfbackend HCL)

25.1 环境级参数文件与按服务拆分策略

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
 subgraph tfvars模型["业务仓的 tfvars 模型"]
 ALL["env-all.tfvars<br/>全局环境参数"]
 GLUE@{ icon: "logos:aws-glue", form: "rounded", label: "glue-all.tfvars<br/>Glue Job 参数", pos: "b", h: 40 }
 LAMBDA@{ icon: "logos:aws-lambda", form: "rounded", label: lambda-all.tfvars<br/>Lambda 参数, pos: "b", h: 40 }
 SF[step-functions-all.tfvars<br/>状态机参数]
 EB[eventbridge-all.tfvars<br/>调度规则]
 S3@{ icon: "logos:aws-s3", form: "rounded", label: s3-all.tfvars<br/>S3 资源, pos: "b", h: 40 }
 RS@{ icon: "logos:aws-redshift", form: "rounded", label: redshift-all.tfvars<br/>Redshift 参数, pos: "b", h: 40 }
 IAM@{ icon: "logos:aws-iam", form: "rounded", label: iam-all.tfvars<br/>IAM 资源, pos: "b", h: 40 }
 end
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class ALL,EB,GLUE,IAM,LAMBDA,RS,S3,SF bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 25-1 环境级参数文件与按服务拆分策略

文件 内容 变更频率
{env}-all.tfvars 环境级全局参数(region/account_id/通用前缀) 极低
glue-all.tfvars Glue Job 定义(脚本路径/DPU/超时)
lambda-all.tfvars Lambda 定义(运行时/内存/超时)
step-functions-all.tfvars 状态机定义
eventbridge-all.tfvars 调度规则(cron 表达式)
redshift-all.tfvars Redshift Schema/表/权限

表 25-1 环境级参数文件与按服务拆分策略

glue-all.tfvars 的真实片段长这样——每个 Glue Job 一组参数,脚本路径用版本化 S3 路径,调度用 cron 表达式:

# 示意:business-domain-ma/glue-all.tfvars —— Glue Job 定义(dev 环境)
glue_jobs = {
  ma_doctor_master = {
    script_location = "s3://ap-aurora-cdp-tooling-dev-cn-north-1/glue/v1.2.3/doctor.py"
    max_dpus        = 6
    timeout         = 45                                    # 分钟
    schedule        = "cron(0 16 * * ? *)"                  # UTC 16:00 = 北京次日 00:00
    extra_py_files  = "s3://ap-aurora-cdp-tooling-dev-cn-north-1/glue/aurora_cdp_common_utils-1.2.3-py3-none-any.whl"
  }
  ma_hospital_master = {
    script_location = "s3://ap-aurora-cdp-tooling-dev-cn-north-1/glue/v1.2.3/hospital.py"
    max_dpus        = 4
    timeout         = 30
    schedule        = "cron(0 17 * * ? *)"                  # 核心意图:错峰避免源库压力叠加
    extra_py_files  = "s3://ap-aurora-cdp-tooling-dev-cn-north-1/glue/aurora_cdp_common_utils-1.2.3-py3-none-any.whl"
  }
}

{env}-all.tfvars 承载环境级全局参数,所有服务 tfvars 共享:

# 示意:business-domain-ma/dev-all.tfvars —— 环境级全局参数
environment = "dev"
region      = "cn-north-1"
account_id  = "123456789012"
prefix      = "ap-aurora-cdp"                               # 核心意图:统一命名前缀
cost_center = "ma-domain"

按服务拆分的好处

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
 subgraph 拆分价值["按服务拆分 tfvars 的价值"]
 V1[变更检测精准<br/>只改 glue tfvars 只触发 Glue CI]
 V2[ 文件大小可控<br/>避免单个 tfvars 过大]
 V3[ 职责清晰<br/>改调度的人只看 eventbridge tfvars]
 end
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class V1,V2,V3 bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 25-2 按服务拆分的好处

引申

按服务拆分 tfvars 是"变更检测驱动 CI"的基础——CI 通过 git diff 检测哪些 tfvars 变了,只对变更的服务执行 Terraform plan/apply。这比"每次都 plan 全部"快得多。


25.2 运行时配置 vs 部署参数的边界

这是 Ch 11 核心设计决策在 tfvars 层的体现:

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
 subgraph 边界划分["参数边界划分"]
 TF@{ icon: "devicon:terraform", form: "rounded", label: "Terraform tfvars<br/>部署参数<br/>“在哪跑”", pos: "b", h: 40 }
 DDB@{ icon: "logos:aws-dynamodb", form: "rounded", label: "DynamoDB 配置<br/>运行时配置<br/>“做什么”", pos: "b", h: 40 }
 end

 TF --> T1[环境/账号/Region]
 TF --> T2[脚本版本/路径]
 TF --> T3[IAM Role/DPU/超时]
 TF --> T4[cron 调度表达式]

 DDB --> D1[源连接/字段映射]
 DDB --> D2[加载模式/合并策略]
 DDB --> D3[质量规则/脱敏规则]
 DDB --> D4[目标 Schema/Table]
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class D1,D2,D3,D4,DDB,T1,T2,T3,T4,TF bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 25-3 运行时配置 vs 部署参数的边界

维度 Terraform tfvars DynamoDB 配置
回答 "在哪跑、用什么资源" "做什么、怎么处理"
变更方式 Terraform plan/apply 配置发布流(热更新)
生效时机 部署时 运行时
审批 需 plan review 配置发布审批

表 25-2 运行时配置 vs 部署参数的边界

Trade-off

边界划分的关键判据是"这个参数变更是否需要重建 AWS 资源"。如果需要(如改 DPU、改 IAM)→ Terraform;如果不需要(如改字段映射、改加载模式)→ DynamoDB。错误地把运行时配置放进 Terraform 会导致"改个字段映射也要走 Terraform apply"的沉重流程。


25.3 后端配置多环境隔离

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
 subgraph tfbackend["每环境独立 tfbackend"]
 DEV_BE[dev.tfbackend<br/>key: dev/terraform.tfstate]
 QA_BE[qa.tfbackend<br/>key: qa/terraform.tfstate]
 PROD_BE[prod.tfbackend<br/>key: prod/terraform.tfstate]
 end
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class DEV_BE,PROD_BE,QA_BE bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 25-4 后端配置多环境隔离

每个环境有独立的 tfbackend 文件,指向 S3 上不同 key 的 state 文件。这实现了 state 的物理隔离——一个环境的 state 损坏不影响其他环境。

这里有一个我在 Ch 21 提过但值得在此深化的细节——dev 和 prod 用的是独立的 S3 桶,不是同一个桶的不同 key。最初我用"同桶不同 key"(tfstate-bucket/dev/tfstate-bucket/prod/),看起来够隔离。但第二年发生了一件事让我改成了独立桶:dev 环境的一个 CI 脚本误删了整个 tfstate 桶(aws s3 rm --recursive 少了 --exclude),连 prod 的 state 也一起删了——因为它们在同一个桶里。从那以后我坚持"dev 和 prod 的 state 存独立桶"——dev 桶炸了碰不到 prod 桶。桶级隔离比 key 级隔离更强——一个 aws s3 rm 命令误删桶时,只影响一个环境。这个教训让我对"隔离强度"有了更深的理解:key 级隔离防的是"逻辑混淆",桶级隔离防的是"物理误删"——后者更危险,必须更强隔离。

# 示意:dev.tfbackend —— DEV 环境 state 后端配置
bucket         = "ap-aurora-cdp-tfstate-dev-cn-north-1"
key            = "dev/terraform.tfstate"                     # 核心意图:每环境独立 key,物理隔离
region         = "cn-north-1"
dynamodb_table = "ap-aurora-cdp-tflock-dev"                  # DynamoDB 锁,防并发 apply
encrypt        = true
# 示意:prod.tfbackend —— PROD 环境 state 后端(独立桶 + 独立锁表)
bucket         = "ap-aurora-cdp-tfstate-prod-cn-north-1"
key            = "prod/terraform.tfstate"
region         = "cn-north-1"
dynamodb_table = "ap-aurora-cdp-tflock-prod"
encrypt        = true

注意 dev 和 prod 的 bucket 名不同——独立桶,不是一个桶的两个 key。DynamoDB 锁表也是独立的(tflock-dev vs tflock-prod),防止一个环境的 lock 故障影响另一个环境。隔离要从桶到锁表全面独立,不能只隔 state 文件


本章小结

  • tfvars 按服务拆分:{env}-all.tfvars 全局 + 按服务(glue/lambda/sf/eb/...)拆分——支持精准变更检测;含 glue-all.tfvars 真实片段(版本化脚本路径/cron/依赖包)
  • 运行时配置(DynamoDB)vs 部署参数(Terraform)边界:需重建资源的 → Terraform,运行时可热更的 → DynamoDB
  • 每环境独立 tfbackend(含 HCL 示意:独立桶 + 独立 key + DynamoDB 锁),state 物理隔离

下一章

Ch 26 Step Functions 模板注入 —— 参数管好了,状态机模板怎么参数化?接下来看模板注入设计。

评论