continuous-integration - 使用 Terraform 时的最佳实践

标签 continuous-integration terraform

关闭。这个问题是opinion-based .它目前不接受答案。












想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.

去年关闭。



Improve this question




我正在将我们的基础设施转换为 terraform。
实际管理 terraform 文件和状态的最佳实践是什么?
我意识到它是基础设施即代码,我会将我的 .tf 文件提交到 git 中,但是我也提交 tfstate 吗?它应该位于像 S3 这样的地方吗?我最终希望 CI 能够管理所有这些,但这远远不够,需要我找出文件的移动部分。

我真的只是想看看那里的人们如何在生产中实际使用这种类型的东西

最佳答案

我也处于将现有的 AWS 基础设施迁移到 Terraform 的状态,因此我的目标是在我开发时更新答案。

我一直非常依赖官方的 Terraform examples以及多次反复试验来充实我一直不确定的领域。

.tfstate文件

Terraform 配置可用于在不同的基础设施上配置许多盒子,每个盒子可以有不同的状态。因为它也可以由多人运行,所以这个状态应该在一个集中的位置(比如 S3)而不是 git。

这可以通过查看 Terraform .gitignore 来确认.

开发者控制

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

  • 包含可重用模块的常见 AMI 的基础基础,例如傀儡。
  • DevOps 使用 Terraform 提供的核心基础设施。
  • 开发人员根据需要更改 Git 中的 Terraform 配置(实例数量;新 VPC;添加区域/可用区等)。
  • 已推送 Git 配置并提交拉取请求以供 DevOps 小队成员进行完整性检查。
  • 如果获得批准,调用 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.tfstate在 git 中。这是我搬到 S3 之前的临时措施,但适合我,因为我目前是唯一的开发人员。

    下一步

    这仍然是一个手动过程,在 Jenkins 中还没有,但我们正在移植一个相当大、复杂的基础设施,到目前为止一切顺利。就像我说的,错误很少,但进展顺利!

    编辑 2 - 更改

    我写这个最初的答案已经快一年了,Terraform 和我自己的状态都发生了显着变化。我现在在一个使用 Terraform 管理 Azure 集群的新职位上,Terraform 现在是 v0.10.7 .

    国家

    人们一再告诉我 state 不应该进入 Git - 他们是正确的。我们将其用作依赖于开发人员沟通和纪律的两人团队的临时措施。有了更大的分布式团队,我们现在可以通过 locking 充分利用 S3 中的远程状态由 DynamoDB 提供。理想情况下,这将迁移到 consul 现在它是 v1.0 以减少跨云提供商。

    模块

    之前我们创建并使用了内部模块。情况仍然如此,但随着 Terraform registry 的出现和增长我们尝试至少将这些用作基础。

    文件结构

    新职位的分类要简单得多,只有两个 infx 环境 - devprod .每个都有自己的变量和输出,重复使用我们上面创建的模块。 remote_state provider 还有助于在环境之间共享创建资源的输出。我们的方案是将不同 Azure 资源组中的子域分配到全局托管 TLD。
    ├── main.tf
    ├── dev
    │   ├── main.tf
    │   ├── output.tf
    │   └── variables.tf
    └── prod
        ├── main.tf
        ├── output.tf
        └── variables.tf
    

    规划

    再次面对分布式团队的额外挑战,我们现在总是保存 terraform plan 的输出。命令。我们可以检查并知道将要运行的内容,而不会有在 plan 之间发生一些变化的风险。和 apply阶段(尽管锁定有助于此)。请记住删除此计划文件,因为它可能包含纯文本“ secret ”变量。

    总的来说,我们对 Terraform 非常满意,并继续学习和改进添加的新功能。

    关于continuous-integration - 使用 Terraform 时的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33157516/

    相关文章:

    google-cloud-platform - Terraform 0.12 使用模板创建入口规则

    Maven:让 "mvn -Pjenkins"与 "mvn clean install pmd:pmd javadoc:aggregate"相同

    continuous-integration - CruiseControl(或任何其他 CI 工具)比编写良好的 (n)Ant 提供了什么?

    amazon-web-services - Github Actions 恢复/销毁 Terraform Plan 创建的 terraform AWS 基础设施

    Terraform(AWS 提供商)- Auto Scaling 组不会对启动模板更改生效

    amazon-web-services - 如何让 Terraform 等待 cloudinit 完成?

    terraform - 当我的 Terraform 模板中的元组为空时,如何获取默认值?

    rest - 通过提交 SHA1 获取构建状态

    ruby-on-rails - Ruby on Rails 的持续集成?

    node.js - 在 Docker 中使用 Yarn 从私有(private)注册表安装包