「Terraform模块不是为了炫技,是为了不把自己逼疯。」——每个被main.tf折磨过的运维工程师都懂这句话。
今天拆一个真实的AWS双层架构:Terraform搭基础设施,Ansible部署应用,Flask+MySQL跑业务。不是教程,是解剖——为什么每个文件必须存在,它们之间怎么勾肩搭背。
![]()
一图看懂:文件全家福
整个项目长这样:
app/ 放Flask应用和前端页面;terraform/ 用模块化方式造AWS资源;ansible/ 负责把代码搬到服务器上跑起来。三层分工明确,谁也别抢谁的活。
重点在terraform/modules/:vpc、ec2、security_group、rds、nat_gateway各自独立。不是过度设计,是血泪教训——把所有资源塞进一个main.tf,两周后你自己都看不懂。
Provider:告诉Terraform"我们在哪干活"
Terraform原生不认识AWS。provider.tf就干一件事:下载AWS插件(版本锁定6.x),并指定区域。
关键细节:region = var.region,而不是硬编码"us-east-1"。这样换区域只需要改变量,不用翻遍所有文件。
version = "~> 6.0" 是防御性编程——自动用小版本更新,但拒绝可能破坏性变更的主版本跳跃。
Backend:状态文件放哪,决定你能不能在团队里活
每次terraform apply都会生成state文件,记录"代码里的资源"和"真实AWS资源"的对应关系。默认存本地,单人玩没问题。
团队场景下,backend.tf把它丢进S3:use_lockfile = true防止两个人同时apply把状态搞炸,encrypt = true确保敏感信息不裸奔。
bucket和key需要你自己填——这是整个项目里少数几个必须手动配置的地方。
Variables:整个架构的控制面板
variables.tf是唯一的"配置入口"。设计很直白:vpc_cidr这种有默认值,可覆盖可不覆盖;ami_id、key_name、db_password没默认值,Terraform会强制你填。
db_password标记了sensitive = true,这是救命的设计——它不会出现在任何日志或plan输出里,避免密码泄露在CI/CD流水线里。
模块化的真实成本:多写文件,少掉头发
每个模块遵循三文件模式:main.tf写资源,variables.tf收参数,outputs.tf吐结果。表面看是文件膨胀,实际是认知减负。
想改安全组规则?去security_group模块,不用担心碰坏数据库。想换EC2规格?改ec2模块的变量,vpc和rds无感知。
这种"隔离"在故障排查时价值千金——2am被叫醒,你能快速定位问题在哪个模块,而不是在800行代码里大海捞针。
Ansible的角色:Terraform造完房子,它来搬家具
ansible/playbook.yml是入口,inventory.ini告诉它"服务器在哪",roles/app/tasks/main.yml写具体执行步骤:装依赖、拉代码、启服务。
这里有个微妙分工:Terraform管"有什么",Ansible管"跑什么"。不混在一起,是因为基础设施变更频率低,应用部署频率高——解耦后,改代码不用重新造服务器。
为什么这个架构值得抄
它回答了一个真实问题:小团队怎么在AWS上跑应用,而不被复杂度吞掉。
答案不是"用更简单的工具",而是"把复杂度关进模块"。每个文件只干一件事,每件事只在一处定义。当你需要扩容、换区域、或者交接给同事时,这种结构能省下数小时的上下文重建成本。
打开你的项目,看看有没有哪个文件超过200行。如果有,它可能正在偷偷消耗你的未来时间。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.