Terraform创建S3/DynamoDB远程状态模块的state文件存储最佳实践咨询
Terraform S3远程状态存储"鸡和蛋"问题的行业最佳实践
首先明确:绝对不要把该state文件上传到Git仓库
哪怕这个state后续几乎不会修改,也不要违反规范上传Git:Terraform state文件默认会明文存储资源的敏感属性,比如S3桶的ARN、加密配置,甚至可能包含关联的AWS角色凭证片段,存在严重的安全泄露风险;同时Git没有状态锁机制,多人修改时很容易出现状态冲突、覆盖的问题。
目前行业主流的3种落地方案,可根据团队规模选择
- 方案1:本地加密存储+定期备份(适合10人以下小团队)
负责搭建底层基础设施的运维/平台工程师单独维护这份bootstrap代码,state文件存在本地,同时把加密后的state备份到企业内部的加密存储(比如内部NAS、AWS Secrets Manager),仅给授权人员开放解密权限。这个方案操作最简单,毕竟这个模块的修改频率极低,半年甚至一年都不会动一次,维护成本很低。 - 方案2:手动创建S3和DynamoDB资源,完全绕过Terraform管控(适合不需要严格IaC全链路管控的团队)
直接写个简易shell脚本,用aws s3 mb、aws dynamodb create-table等CLI命令手动创建状态存储资源,配置好版本控制、加密、访问权限之后,直接给所有业务Terraform模块用就行,完全不用Terraform管理这两个基础资源,自然就不存在对应的state需要处理的问题。这个方案缺点是这两个资源的变更没法走IaC流程,要修改的时候得手动操作,但胜在省事,很多创业团队都这么用。 - 方案3:状态分层迁移(中大型团队最佳实践)
这是目前最合规的方案,操作步骤也很简单:- 先写bootstrap模块的Terraform代码,只定义状态存储用的S3桶和DynamoDB锁表,先不配置remote_state
- 第一次运行
terraform apply,生成本地state文件,成功创建S3和DynamoDB资源 - 回到bootstrap模块的代码里,补全remote_state配置,指向刚创建的S3桶
- 运行
terraform init -migrate-state,按照提示确认迁移,就能把本地的bootstrap state直接迁移到刚建好的S3远程存储里,后续这个模块的state就和其他业务模块一样,受版本控制和锁保护,所有人都能正常访问。
通用注意事项
- 不管用哪种方案,状态桶都必须开启版本控制、服务端加密、桶策略禁止公网访问,DynamoDB锁表要配置最小权限访问策略,仅给Terraform操作角色开放读写权限
- 普通开发人员仅开放bootstrap状态的读权限即可,不要给写权限,避免误删底层存储资源
- 如果选方案3,第一次迁移状态的时候要确保没有其他人同时操作该模块,避免状态冲突
内容的提问来源于stack exchange,提问作者Sven
相关产品推荐
相关产品推荐

