关于配置 Terraform 的五条建议
Terraform

> 
> 本文介绍我使用 Terraform 五年之后吸取到的经验。
> 
> 
> 


![](/data/attachment/album/202211/02/220728ngg0kzjg0rldu0l7.jpg "Puzzle pieces coming together to form a computer screen")


使用 Terraform 五年的经历让我吸取到一些重要经验。无论团队大小、项目性质，有五条要点对于配置合乎逻辑且可用的 Terraform 平台至关重要。


### 1、了解你的目标受众


这一点似乎显而易见，但我也见过一些在这方面犯错的案例。当组织和规划 Terraform 的相关代码时，无论是将目录结构标准化还是确定命名规范，考虑目标受众是非常重要的。例如：你的团队是否会使用这些 Terraform 脚本和模块？你是否会向其他团队交接工作？你的团队是否会有新成员加入？你是否正在独自进行项目开发？你是否会半年或一年后仍然使用这些配置，还是会将它安排给别人？


这类问题会影响某些决策。理想情况下，无论如何都应该有 <ruby> <a href="https://www.terraform.io/docs/language/state/index.html">  远程状态 </a> <rt>  Remote State </rt></ruby> 和 <ruby> <a href="https://www.terraform.io/docs/language/state/locking.html">  状态锁定 </a> <rt>  State Locking </rt></ruby> 两种状态。远程状态确保你的笔记本电脑不是你的 Terraform 唯一运行的机器，状态锁定确保同一时刻只有一个人对基础设施进行修改操作。


命名规范应该对项目的最终拥有者有意义，而不是只对开发团队有意义。如果项目会转交给其他团队，应该确保他们对命名规范有发言权。如果代码由非技术的利益相关者或内部安全/ GCR 团队负责审查，应该确保他们会检查命名规范。另外，对于资源名称，为了让代码审查人员更仔细地进行检查，你应该使用资源标签，把有关的数据分类/隐私需求（高、中、低）标示出来。


### 2、重用，重用，重用


[Terraform 注册表](https://registry.terraform.io/) 为大多数普通用例提供了现成模块类库。我已经使用过 VPC 模块和安全模块中的大量功能，这些功能只需要提供相关的参数就能使用。使用不同的参数，简单调用这些模块对于处理大部分用例已经足够了。尽可能多地重用这些公共模块，可以避免大量且重复的编码、测试、检查、修复、重构等操作。


我也发现，基于使用或变更的频率划分模块和资源大有好处。例如，只使用一次的基础设施手脚架，例如 VPC 相关设置、安全模块、路由表、VPC 端点等，可以放在一起。但是像私有托管域条目、自动伸缩模块、目标模块、负载均衡器等，每次部署时都会变化，所以把这些与一次性的基础设施手脚架分离开来，会令代码检查更方便，调试更快速。


### 3、要明确，而非隐含


Terraform 代码中有一些常见的模式，它会导致设计中出现错误的假设。团队可以假设用来写代码的 Terraform 版本永远保持不变，外部模块不会变化，或它们使用的提供者不会变更。当这些外部依赖不可避免地发生变化时，就会导致一些难以发现的问题。


无论何处（包括主要的 Terraform 组、提供者组、功能模块组）都要确保定义是明确的。事先定义版本，可以确保依赖库是固定的，因此你可以在讨论、审查、测试后，明明白白地更新依赖关系。


### 4、自动化每一处，包括笔记本电脑、共享虚拟机、CI/CD。


在部署的各个阶段使用自动化方法，可以避免可能发生的问题。


在你提交代码前，使用 [Git 预提交钩子](https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6) 运行 `terraform fmt` 和 `terraform validate`。预提交钩子的作用是确保你的代码满足最低程度的格式和语法正确。把这个预提交文件检入到仓库，对你的团队成员都有好处。项目的第一步就进行质量控制相关的操作，它虽然表面上是小事一桩，但也很重要，能为项目节省大量时间。


一切现代化部署工具都有 CI 流程。当你向原始仓库推送代码时，可以使用它来运行 SAST 和单元测试工具。我写过一篇 [博客](https://notes.ayushsharma.in/2021/07/cloud-infrastructure-sast-terraform-checkov)，是关于使用 Checkov 测试 Terraform 代码的安全性和合规性，并为组织特定的惯例创建自定义检查。把这些单元测试工具加入到你的 CI 管道，可以改进代码质量和健壮性。


### 5、写个好的 README.md 文件


我们都认为 Terraform 代码是自文档化的。的确如此，但是只有当未来的团队已经了解你的公司的命名规范、开发指南、机密通信、圈内笑话，以及你的仓库内除有效的 Terraform 代码之外其他所有东西，才会如此。维护 `README.md` 文件是个好习惯，它能节省大量时间，而且团队成员要为自己向 README 文件提交的任何内容负责，这样也就确保团队成员的忠诚度。


你的 README 文件至少应该包含在你的工作环境下（Linux、 Windows、Mac 等等）初始化 Terraform 环境的步骤，包括 Terraform 的版本信息。它应当确定需要的依赖库（Checkov、 TerraGrunt 及其他依赖）和其版本，以及团队使用的方便的 Linux 别名（例如有人喜欢将 `terraform fmt` 简写为 `tff`）。最重要的是，需要确定分支和 PR 审核策略和流程、命名规范和资源标签的相关标准。


README 文件需要通过这样的检验：如果团队有新成员加入，能否告诉他们做什么以及如何正确地完成工作？如果不能，在后续的几个月内，你将面对的是无休止的标准和流程讨论会议。


### 结束语


这些就是我使用 Terraform 多年后，认为需要传授给大家的五条有用的建议。也欢迎你分享自己的最佳实践。




---


via: <https://opensource.com/article/21/8/terraform-tips>


作者：[Ayush Sharma](https://opensource.com/users/ayushsharma) 选题：[lujun9972](https://github.com/lujun9972) 译者：[cool-summer-021](https://github.com/cool-summer-021) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
Working with Terraform for over five years has taught me some key lessons. Five practices have been critical to having a logical and usable Terraform setup regardless of the size of the team or the nature of the project.

## 1. Know your target audience.

This one might seem obvious, but I've seen it go wrong several times. When organizing Terraform code, either standardizing the directory structure or defining naming conventions, it's vital to consider the intended audience. Will your team be using these Terraform scripts and modules? Are you handing the work over to another team? Will new people be joining your team sooner or later? Are you working on this project solo? Will you be using this setup in six months or a year, or will it be assigned to someone else?

Questions like these affect several decisions. Ideally, you should have [Remote State](https://www.terraform.io/docs/language/state/index.html) and [State Locking](https://www.terraform.io/docs/language/state/locking.html) in place regardless of the team size now or in the future. Remote State will ensure your laptop is not the only place your Terraform works, and State Locking will ensure that only one person at a time is changing the infrastructure.

The naming convention should make sense to the eventual owners of the project, not just the team that is writing the code. If the project is for another team, make sure they have a say in the naming convention. If non-technical stakeholders or internal security/GCR teams review the code, make sure they check the naming convention. In addition to resource names, you should leverage resource tags to highlight any data classification/privacy requirements (high, medium, low) for more careful examination by reviewers.

## 2. Reuse. Reuse. Reuse.

The [Terraform Registry](https://registry.terraform.io/) provides a library of ready-to-use modules for the most common use-cases. I've written about the extensive parameterization available in the VPC module and security groups. Simply calling modules with different parameters is enough to handle most, if not all, potential use cases. Reuse these shared modules as much as possible to avoid endless typing, testing, checking, fixing, and refactoring.

I've also found that separating modules and resources based on the frequency of use or change is beneficial. For example, infrastructure scaffolding used only once belongs together, such as setting up the VPC, security groups, routing tables, VPC endpoints, and so on. But things like private hosted zone entries, autoscaling groups, target groups, load balancers, etc., might change with every deployment, so separating these from the one-time scaffolding will make code reviews easier and debugging faster.

## 3. Be explicit rather than implicit.


There are common patterns to Terraform code that I have seen lead to incorrect assumptions baked into the design. Teams can assume that the Terraform version used to write the code today will never change, or the external modules won't change, or the providers they are using won't change. These lead to invisible issues a few weeks down the road when these external dependencies inevitably get updated.

Ensure you explicitly define versions everywhere possible: In the main Terraform block, in the provider block, in the module block, etc. Defining versions ensures that your dependent libraries stay frozen so that you can explicitly update dependencies when required after thorough discussions, reviews, and testing.

## 4. Automate everywhere. Your laptop. Your shared VM. Your CI/CD.

Leveraging automation at every stage of the deployment process can avoid future problems before they even arise.

Use [Git pre-commit hooks](https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6) to run `terraform fmt `

and `terraform validate`

before you commit your code. Pre-commit hooks ensure that code is, at a bare minimum, adequately formatted and syntactically correct. Check-in this pre-commit file to the repo, and everyone on your team can benefit from the same automation. This small but vital quality control at the first step of the process can achieve substantial time savings as your project progresses.

All modern deployment tools have CI processes. You can use these to run SAST and unit testing tools when pushing your code to origin. I've written on my blog about how [Checkov can test Terraform code for security and compliance and create custom checks](https://notes.ayushsharma.in/2021/07/cloud-infrastructure-sast-terraform-checkov) for organization-specific conventions. Add these unit testing tools to your CI pipeline to improve code quality and robustness.

## 5. Have an awesome README.md.

We all like to think that Terraform code is self-documenting. Sure it is, but only if your future team already knows your company's naming conventions and guidelines and secret handshakes and inside jokes and whatever else your repo contains besides valid Terraform code. Getting into the habit of having a good `README.md`

can be a huge time saver, and it keeps your team honest by holding them accountable for everything explicitly committed to in the README.

At a minimum, your README should contain the steps to initialize the right Terraform environment on your workstations (Linux, Windows, Mac, and so on), including the Terraform version to install. It should specify the required dependencies (Checkov, TerraGrunt, and others) with versions and any handy Linux aliases your team uses (some people like to define `tff`

as a short-hand for` terraform fmt`

). Most importantly, the branching and PR review strategy and process, naming conventions, and resource tagging standards should be specified.

The README should pass a simple test: if a new member joins your team tomorrow, is the README enough to teach them what to do and how to do it correctly? If not, you may find yourself hosting never-ending standards and process meetings repeatedly for the next few months.

## Wrap up

After many years of working with Terraform, these are my five best bits of wisdom to pass along. Feel free to share your own best practices below.

## Comments are closed.