我正在将我们的基础架构转换为terraform。实际管理terraform文件和状态的最佳实践是什么?我意识到它是作为代码的基础结构,我将.tf文件提交到git中,但是我也提交tfstate吗?那应该像S3一样吗?我希望最终由CI来管理所有这一切,但是这牵扯很大,需要我弄清楚文件的移动部分。
我真的只是想看看外面的人如何在生产中实际利用这种东西
我还处于将现有的AWS基础架构迁移到Terraform的状态,因此将在我开发时力求更新答案。
我一直严重依赖于官方的Terraform 示例和多次试验和错误来充实我不确定的区域。
.tfstate
档案
Terraform配置可用于在不同的基础架构上预配许多盒子,每个盒子可能具有不同的状态。由于它也可以由多个人运行,因此该状态应位于集中位置(如S3),而不是 git。
查看Terraform可以确认这一点.gitignore
。
开发者控制
我们的目标是为开发人员提供对基础架构的更多控制,同时保持完整的审核(git日志)和健全性检查更改(拉动请求)的能力。考虑到这一点,我旨在实现的新基础架构工作流程是:
编辑1-更新当前状态
自从开始回答以来,我已经写了很多TF代码,对我们的处境感到更加自在。我们在此过程中遇到了严重的错误和限制,但是我接受这是使用新的,快速变化的软件的特征。
布局
我们拥有一个复杂的AWS基础架构,其中包含多个VPC,每个VPC都具有多个子网。轻松管理此问题的关键是定义一个灵活的分类法,其中涵盖了区域,环境,服务和所有者,我们可以使用它们来组织基础结构代码(terraform和puppet)。
模组
下一步是创建一个git存储库来存储我们的Terraform模块。模块的顶级目录结构如下所示:
tree -L 1 .
结果:
├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates
每个设置一些合理的默认值,但将它们公开为可以被我们的“胶水”覆盖的变量。
胶
我们拥有第二个存储库,glue
该存储库利用了上述模块。根据我们的分类文件进行了布局:
.
├── README.md
├── clientA
│ ├── eu-west-1
│ │ └── dev
│ └── us-east-1
│ └── dev
├── clientB
│ ├── eu-west-1
│ │ ├── dev
│ │ ├── ec2-keys.tf
│ │ ├── prod
│ │ └── terraform.tfstate
│ ├── iam.tf
│ ├── terraform.tfstate
│ └── terraform.tfstate.backup
└── clientC
├── eu-west-1
│ ├── aws.tf
│ ├── dev
│ ├── iam-roles.tf
│ ├── ec2-keys.tf
│ ├── prod
│ ├── stg
│ └── terraform.tfstate
└── iam.tf
在客户端级别内,我们具有特定于AWS账户的.tf
文件,这些文件提供了全局资源(例如IAM角色);接下来是具有EC2 SSH公钥的区域级别;最后,在我们的环境中(dev
,stg
,prod
等)是我们的VPC设置,例如创建和对等连接等存储。
旁注:如您所见,在保留terraform.tfstate
git的基础上,我违背了自己的建议。这是临时措施,直到我移至S3为止,但由于我是目前唯一的开发人员,因此适合我。
下一步
这仍然是一个手动过程,尚未在Jenkins中使用,但是我们正在移植一个相当大的,复杂的基础结构,到目前为止还算不错。就像我说的那样,错误很少,但是进展顺利!
编辑2-变更
自从我写了这个初步答案以来已经过去了将近一年,Terraform和我自己的状态都发生了重大变化。我现在处于使用Terraform来管理Azure群集的新位置,而Terraform现在已开始v0.10.7
。
州
人们一再告诉我的状态应该不会在Git中去-他们是正确的。我们将此作为与两个人的团队的临时措施,该团队依靠开发人员的沟通和纪律。通过一个更大的分布式团队,我们现在可以利用DynamoDB提供的锁定来充分利用S3中的远程状态。理想情况下,此工具将迁移到领事,因为它是削减跨云提供商的v1.0。
模组
以前,我们创建并使用了内部模块。情况仍然如此,但是随着Terraform注册中心的出现和发展,我们尝试至少以此为基础。
档案结构
新职位的分类法要简单得多,只有两个infx环境- dev
和prod
。每个模块都有自己的变量和输出,可重复使用上面创建的模块。该remote_state
供应商还有助于在环境之间共享创建的资源的输出。我们的方案是将不同Azure资源组中的子域设置为全局管理的TLD。
├── main.tf
├── dev
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf
规划
再次面对分布式团队的额外挑战,我们现在始终保存terraform plan
命令的输出。我们可以检查并知道将运行什么,而不会在plan
和apply
阶段之间进行某些更改(尽管锁定对此有所帮助)。请记住删除该计划文件,因为它可能包含纯文本“秘密”变量。
总体而言,我们对Terraform感到非常满意,并继续通过添加的新功能来学习和改进。
自从这个答案以来,您有运气吗?您的看起来很像我要去做,但您可能会比我走得更远。
我很好奇为什么您认为tfstate文件不应该存储在git中?仅仅是因为旧状态不值得保存,还是还有其他问题?
@agbodike-作为单个开发人员或非常小的团队的一部分工作时,只要定期提交并推动tfstate以避免冲突,就可以将其保留在git中。我的下一步是根据S3中的远程状态文档进行设置(该操作还说:“由于它是合并冲突的常见来源,因此使团队中的Terraform的工作变得复杂。远程状态有助于缓解这些问题。”) 。尽管与大多数事情一样,良好的团队沟通可以帮助缓解大多数/所有问题,无论采取何种策略保持状态:-)
@ the0ther-恐怕我的主存储库是专有的,但是我目前正在开发一个个人存储库,我将在不久的将来公开使用该存储库。
Git仓库@Ewan有运气吗?我很想看看你在做什么。