温馨提示:本文翻译自stackoverflow.com,查看原文请点击:devops - Best practices when using Terraform
devops terraform

devops - 使用Terraform的最佳做法

发布于 2020-04-08 09:59:37

我正在将我们的基础架构转换为terraform。实际管理terraform文件和状态的最佳实践是什么?我意识到它是作为代码的基础结构,我将.tf文件提交到git中,但是我也提交tfstate吗?那应该像S3一样吗?我希望最终由CI来管理所有这一切,但是这牵扯很大,需要我弄清楚文件的移动部分。

我真的只是想看看外面的人如何在生产中实际利用这种东西

查看更多

提问者
Marc Young
被浏览
100
10.7k 2019-02-27 22:29

我还处于将现有的AWS基础架构迁移到Terraform的状态,因此将在我开发时力求更新答案。

我一直严重依赖于官方的Terraform 示例和多次试验和错误来充实我不确定的区域。

.tfstate 档案

Terraform配置可用于在不同的基础架构上预配许多盒子,每个盒子可能具有不同的状态。由于它也可以由多个人运行,因此该状态应位于集中位置(如S3),而不是 git。

查看Terraform可以确认这一点.gitignore

开发者控制

我们的目标是为开发人员提供对基础架构的更多控制,同时保持完整的审核(git日志)和健全性检查更改(拉动请求)的能力。考虑到这一点,我旨在实现的新基础架构工作流程是:

  1. 常见AMI的基础,包括可重用的模块,例如puppet。
  2. DevOps使用Terraform提供的核心基础架构。
  3. 开发人员根据需要更改Git中的Terraform配置(实例数;新的VPC;添加区域/可用区等)。
  4. 推送了Git配置,并提交了一个提取请求,以供DevOps小组的成员进行检查。
  5. 如果批准,则将Webhook调用到CI以进行构建和部署(不确定当前如何对多个环境进行分区)

编辑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公钥的区域级别;最后,在我们的环境中(devstgprod等)是我们的VPC设置,例如创建和对等连接等存储。

旁注:如您所见,在保留terraform.tfstategit的基础上,我违背了自己的建议这是临时措施,直到我移至S3为止,但由于我是目前唯一的开发人员,因此适合我。

下一步

这仍然是一个手动过程,尚未在Jenkins中使用,但是我们正在移植一个相当大的,复杂的基础结构,到目前为止还算不错。就像我说的那样,错误很少,但是进展顺利!

编辑2-变更

自从我写了这个初步答案以来已经过去了将近一年,Terraform和我自己的状态都发生了重大变化。我现在处于使用Terraform来管理Azure群集的新位置,而Terraform现在已开始v0.10.7

人们一再告诉我的状态应该不会在Git中去-他们是正确的。我们将此作为与两个人的团队的临时措施,该团队依靠开发人员的沟通和纪律。通过一个更大的分布式团队,我们现在可以利用DynamoDB提供的锁定来充分利用S3中的远程状态理想情况下,此工具将迁移到领事,因为它是削减跨云提供商的v1.0。

模组

以前,我们创建并使用了内部模块。情况仍然如此,但是随着Terraform注册中心的出现和发展,我们尝试至少以此为基础。

档案结构

新职位的分类法要简单得多,只有两个infx环境- devprod每个模块都有自己的变量和输出,可重复使用上面创建的模块。remote_state供应商还有助于在环境之间共享创建的资源的输出。我们的方案是将不同Azure资源组中的子域设置为全局管理的TLD。

├── main.tf
├── dev
│   ├── main.tf
│   ├── output.tf
│   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

规划

再次面对分布式团队的额外挑战,我们现在始终保存terraform plan命令的输出我们可以检查并知道将运行什么,而不会在planapply阶段之间进行某些更改(尽管锁定对此有所帮助)。请记住删除该计划文件,因为它可能包含纯文本“秘密”变量。

总体而言,我们对Terraform感到非常满意,并继续通过添加的新功能来学习和改进。