10个Terraform最佳实践,以实现更好的基础设施配置
让我们谈谈在使用Terraform时应该遵循的一些最佳实践。
Terraform是一个非常受欢迎的开源工具,用于定义和提供完整的基础架构。
尽管Terraform于2014年推出,但该工具的使用已在全球范围内增长。越来越多的开发人员正在组织中部署基础架构。
如果您已经开始使用Terraform,则必须采用最佳实践来更好地提供生产基础架构。
如果您是新手,请查看此文章。
结构化
当您使用Terraform在一个大型的生产基础架构项目上工作时,您必须遵循适当的目录结构以应对项目中可能出现的复杂性。您应该为不同的目的使用单独的目录。
例如,如果您在开发、暂存和生产环境中使用terraform,请为每个环境单独创建目录。
yaoweibin@yaoweibin:~$ tree terraform_project/
terraform_project/
├── dev
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── modules
│ ├── ec2
│ │ ├── ec2.tf
│ │ └── main.tf
│ └── vpc
│ ├── main.tf
│ └── vpc.tf
├── prod
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── stg
├── main.tf
├── outputs.tf
└── variables.tf
6 directories, 13 files
甚至terraform配置也应该是分开的,因为经过一段时间后,增长中的基础架构的配置将变得复杂。
例如 – 您可以将所有的terraform代码(模块、资源、变量、输出)都写在main.tf
文件中,但是将变量和输出的terraform代码分开,使其更易于阅读和理解。
命名约定
在Terraform中使用命名约定可以使事物更容易理解。
例如,假设您想在项目中为不同的环境创建三个不同的工作区。因此,与其将它们命名为env1、env2、env3,您应该将它们称为dev、stage、prod。从名称本身就可以清楚地看出每个环境有三个不同的工作区。
类似的约定也应该适用于资源、变量、模块等。在Terraform中,资源名称应以提供程序名称开头,后跟下划线和其他详细信息。
例如,在AWS中创建用于路由表的terraform对象的资源名称将是aws_route_table
。
因此,如果您正确遵循命名约定,即使是复杂的代码,也更容易理解。
使用共享模块
强烈建议使用现有的官方Terraform模块。没有必要重新发明已经存在的模块。这样可以节省大量时间和痛苦。可用的模块在Terraform registry上有很多。根据需要更改现有模块。
此外,每个模块应该只关注基础架构的一个方面,例如创建一个AWS EC2 instance,设置MySQL数据库等。
例如,如果您想在terraform代码中使用AWS VPC,可以使用 – simple VPC
module "vpc_example_simple-vpc" {
source
= "terraform-aws-modules/vpc/aws//examples/simple-vpc"
version = "2.48.0"
}
最新版本
Terraform开发社区非常活跃,新功能的发布频率很高。建议始终使用最新版本的Terraform。您可以很容易地升级到最新版本。
如果您跳过多个主要版本,升级将变得非常复杂。
运行terraform -v
命令检查是否有新的更新。
yaoweibin@yaoweibin:〜$ terraform -v
Terraform v0.11.14
您的Terraform版本已过时! 最新版本
是0.12.0。 您可以通过从www.terraform.io/downloads.html下载来更新
备份系统状态
始终备份Terraform的状态文件。
这些文件跟踪基础架构的元数据和资源。 默认情况下,这些文件被称为terraform.tfstate
,存储在工作区目录中。
没有这些文件,Terraform将无法确定在基础架构上部署了哪些资源。 因此,备份状态文件是必不可少的。 默认情况下,将创建一个名为terraform.tfstate.backup
的文件,用于备份状态文件。
yaoweibin@yaoweibin:〜$ tree terraform_demo/
terraform_demo /
├── awsec2.tf
├── terraform.tfstate
└── terraform.tfstate.backup
0个目录,3个文件
如果要将备份状态文件存储到其他位置,请在terraform命令中使用-backup
标志并提供位置路径。
大多数情况下,将有多个开发人员在一个项目上工作。 因此,为了让他们能够访问状态文件,应将其存储在使用terraform_remote_state
数据源的远程位置。
以下示例将备份到S3。
data "terraform_remote_state" "vpc" {
backend = "s3"
config = {
bucket = “s3-terraform-bucket”
key = “vpc/terraform.tfstate"
region = “us-east-1”
}
}
锁定状态文件
可能会有多种情况,多个开发人员尝试同时运行terraform配置。 这可能导致terraform状态文件的损坏甚至数据丢失。 锁定机制有助于防止此类情况发生。 它确保在同一时间只有一个人正在运行terraform配置,没有冲突。
下面是一个锁定状态文件的示例,该文件位于使用DynamoDB的远程位置。
resource “aws_dynamodb_table” “terraform_state_lock” {
name = “terraform-locking”
read_capacity = 3
write_capacity = 3
hash_key = “LockingID”
attribute {
name = “LockingID”
type = “S”
}
}
terraform {
backend “s3” {
bucket = “s3-terraform-bucket”
key = “vpc/terraform.tfstate”
region = “us-east-2”
dynamodb_table = “terraform-locking”
}
}
当多个用户尝试访问状态文件时,将使用DynamoDB数据库名称和主键进行状态锁定和维护一致性。
注意:并非所有后端都支持锁定。
使用self变量
self
变量是一种特殊类型的变量,当在部署基础架构之前不知道变量的值时使用。
假设您想要使用实例的IP地址,该地址仅在terraform apply命令之后才被部署,因此在实例启动和运行之前您不知道IP地址。
在这种情况下,您将使用self.ipv4_address
作为自变量来获取实例的IP地址。 这些变量仅允许在terraform配置的连接和配置程序块上使用。
connection {
host = self.ipv4_address
type = "ssh"
user = var.users[2]
private_key = file(var.private_key_path)
}
最小化冲击半径
冲击半径是指如果事情没有按计划进行可能发生的损害程度。
例如,如果您将某些terraform配置部署到基础架构上并且配置未正确应用,那么对基础架构的损害程度将是多少。
所以,为了减小爆炸半径,建议一次只在基础设施上推送几个配置。因此,如果出现问题,对基础设施的损害将最小化,并且可以快速纠正。一次部署大量配置非常冒险。
使用var-file
在Terraform中,您可以创建一个带有 .tfvars
扩展名的文件,并使用-var-file
标志将此文件传递给terraform apply命令。这有助于传递那些您不想放在terraform配置代码中的变量。
始终建议通过-var-file在本地传递密码、密钥等变量,而不是将其保存在terraform配置或远程位置版本控制系统中。
例如,如果您想使用terraform启动一个ec2实例,可以使用-var-file传递访问密钥和秘密密钥
创建一个名为terraform.tfvars 的文件,并将密钥放入此文件中。
yaoweibin@yaoweibin:~$ gedit terraform.tfvars
access_key = "AKIATYWSDFYU5DUDJI5F"
secret_key = "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"
现在,在terraform命令中使用此var文件。
yaoweibin@yaoweibin:~$ terraform apply -var-file=/home/yaoweibin/terraform.tfvars
使用Docker
当您运行CI / CD流水线构建作业时,建议使用<link_7>
容器。Terraform提供了可以使用的官方Docker容器。如果您更改了<link_8>
服务器,可以轻松地将基础设施传递到容器中。
在将基础设施部署到生产环境之前,您还可以在非常容易部署的Docker容器上测试基础设施。通过结合使用Terraform和Docker,您可以获得可移植、可重用、可重复的基础设施。
结论
希望这些最佳实践能帮助您编写更好的Terraform配置。继续在您的terraform项目中实施这些实践,以获得更好的结果。