Terraform:基础设施即代码的实用指南
1. 安全部署与状态锁定
使用 S3 后端和 DynamoDB 状态锁定,能确保 Terraform 部署安全且一致,即便在多人同时修改同一基础设施的团队环境中也是如此。
2. Terraform CLI 基础
Terraform 的核心是其命令行工具
terraform
。尽管有自动化工具可避免使用 CLI,但使用它能让我们获得很多有用的知识。下面介绍
terraform
命令的常见选项和工作流程。
3. 初始化工作环境
第一个要使用的子命令是
terraform init
。编写完
main.tf
文件的第一部分后,运行此命令可下载所需插件,并创建重要目录和辅助文件。
示例代码如下:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
运行
terraform init
命令:
admin@myhome:~$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.58.0...
- Installed hashicorp/aws v4.58.0 (signed by HashiCorp)
Terraform has been successfully initialized!
后端是存储
.tfstate
文件的区域,若未指定,文件将保存在本地目录的
terraform.tfstate
中。同时会创建
.terraform
子目录用于安装插件,还有
.terraform.lock.hcl
文件记录使用的提供者版本。
terraform init
是安全命令,可多次运行。
4. 规划变更
接下来是
terraform fmt
命令,它能根据最佳实践格式化
.tf
文件,提高代码可读性和可维护性。
运行示例:
admin@myhome:~$ terraform fmt
│ Error: Missing attribute separator
│
│ on main.tf line 4, in terraform:
│ 3: aws = {
│ 4: source = "hashicorp/aws" version = "~> 4.0"
│
│ Expected a newline or comma to mark the beginning of the next
attribute.
此命令能发现代码中的错误,如上述示例中,将两个属性写在一行,修改后如下:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
然后使用
terraform plan
命令构建行动计划,它会将基础设施的最后记录状态与目录中的代码进行比较,并准备步骤使它们匹配。
示例代码:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "vm_example" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "DevOpsGuideTerraformExample"
}
}
运行
terraform plan
:
admin@myhome:~$ terraform plan
Terraform used the selected providers to generate the following
execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# aws_instance.vm_example will be created
+ resource "aws_instance" "vm_example" {
+ ami = "ami-830c94e3"
...
+ tags = {
+ "Name" = "DevOpsGuideTerraformExample"
}
+ tags_all = {
+ "Name" = "DevOpsGuideTerraformExample"
}
+ tenancy = (known after apply)
...
+ vpc_security_group_ids = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
在计划中,以
+
开头的属性将被创建,以
-
开头的将被销毁,以
~
开头的将被修改。
5. 应用变更
使用
terraform apply
命令实施计划。如果
.tf
文件与
.tfstate
文件不同,或者实际运行的基础设施与
.tfstate
文件不同,该命令会尽力使实时基础设施与 Terraform 状态文件重新对齐。
运行示例:
admin@myhome:~$ terraform apply
Terraform used the selected providers to generate the following
execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# aws_instance.vm_example will be created
+ resource "aws_instance" "vm_example" {
+ ami = "ami-830c94e3"
...
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "DevOpsGuideTerraformExample"
}
+ tags_all = {
+ "Name" = "DevOpsGuideTerraformExample"
}
+ tenancy = (known after apply)
...
+ vpc_security_group_ids = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.vm_example: Creating...
aws_instance.vm_example: Still creating... [10s elapsed]
...
aws_instance.vm_example: Creation complete after 1m29s [id=i-0a8bee7070b7129e5]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
可以将
terraform plan
记录到文件中,然后将文件提供给
apply
步骤,避免再次创建计划。执行过程中有确认步骤,需输入
yes
才能继续。
6. 其他操作
-
销毁基础设施
:运行
terraform destroy可删除创建的所有基础设施。 -
查看步骤层次结构
:使用
terraform graph命令可打印步骤层次结构。
admin@myhome:~$ terraform graph
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] aws_instance.vm_example (expand)" [label = "aws_instance.vm_example", shape = "box"]
"[root] provider[\"registry.terraform.io/hashicorp/aws\"]" [label = "provider[\"registry.terraform.io/hashicorp/aws\"]", shape = "diamond"]
"[root] aws_instance.vm_example (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"]"
"[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)" -> "[root] aws_instance.vm_example (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)"
}
}
7. 修改 Terraform 状态
有几个有用的 CLI 命令可帮助修改状态文件中的资源:
-
Terraform state rm
:从状态中移除资源,适用于手动移除资源和 Terraform 代码,但资源仍存在于状态中的情况。
-
terraform state mv
:更改资源名称,可避免移除和创建新资源。
-
terraform taint
:强制重新创建资源。
8. 导入现有资源
使用
terraform import
命令可将现有资源添加到 Terraform 状态中,其语法如下:
terraform import [options] resource_in_code resource_identifier
参数说明:
-
resource_in_code
:Terraform 代码中资源的地址。
-
resource_identifier
:要导入资源的唯一标识符。
示例:
terraform import aws_s3_bucket.devopsy_bucket arn:aws:s3:::devopsy-bucket
并非所有资源都能导入,资源必须有唯一标识符,且受 Terraform 使用的提供者支持。
9. 工作区
Terraform 有工作区的概念,类似于状态的版本,可存储同一代码的不同状态。要使用工作区,需将状态文件存储在支持它们的后端。工作区可通过
${terraform.workspace}
序列在
.tf
文件中使用,结合条件表达式可创建不同环境。
操作命令:
-
terraform workspace list
:查看所有工作区并显示当前活动的工作区。
-
terraform workspace show
:仅显示当前工作区。
-
terraform workspace new
:创建新工作区。
-
terraform workspace switch
:切换工作区。
示例:
admin@myhome:~$ terraform workspace new testing
Created and switched to workspace "testing"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing
state
for this configuration.
admin@myhome:~$ terraform apply
...
不同工作区可创建不同类型的实例,示例代码:
resource "aws_instance" "vm_example" {
ami = "ami-830c94e3"
instance_type = terraform.workspace == "default" ? "t2.micro" : "t2.nano"
tags = {
Name = "DevOpsGuideTerraformExample"
}
}
通过
terraform plan
验证:
admin@myhome:~$ terraform workspace show
default
admin@myhome:~$ terraform plan | grep instance_type
+ instance_type = "t2.micro"
admin@myhome:~$ terraform workspace select testing
Switched to workspace "testing".
admin@myhome:~$ terraform plan | grep instance_type
+ instance_type = "t2.nano"
下面用 mermaid 流程图展示 Terraform 的基本工作流程:
graph LR
A[编写 .tf 文件] --> B[terraform init]
B --> C[terraform fmt]
C --> D[terraform plan]
D --> E{是否有变更?}
E -- 是 --> F[terraform apply]
E -- 否 --> G[结束]
F --> H[terraform destroy(可选)]
表格展示 Terraform 常见命令及其作用:
| 命令 | 作用 |
| — | — |
|
terraform init
| 初始化工作环境,下载插件和创建必要文件 |
|
terraform fmt
| 格式化
.tf
文件 |
|
terraform plan
| 构建行动计划 |
|
terraform apply
| 实施计划,变更基础设施 |
|
terraform destroy
| 删除创建的基础设施 |
|
terraform graph
| 查看步骤层次结构 |
|
terraform state rm
| 从状态中移除资源 |
|
terraform state mv
| 更改资源名称 |
|
terraform taint
| 强制重新创建资源 |
|
terraform import
| 导入现有资源 |
|
terraform workspace
| 管理工作区 |
以上就是 Terraform 的一些基本操作和概念,希望能帮助你更好地使用 Terraform 进行基础设施管理。
Terraform:基础设施即代码的实用指南
10. 深入理解工作区的优势
工作区在 Terraform 中扮演着重要的角色,它允许我们在同一套代码基础上管理不同的环境。以下是工作区带来的一些显著优势:
-
环境隔离
:不同的工作区拥有独立的状态文件,这意味着在一个工作区中进行的操作不会影响其他工作区。例如,在测试工作区进行资源创建和修改时,不会对生产工作区的资源产生任何干扰。
-
条件配置
:通过
terraform.workspace
变量,我们可以根据当前工作区的名称进行条件配置。如前面提到的,根据不同的工作区选择不同的实例类型,这在区分开发、测试和生产环境时非常有用。
-
资源复用
:使用相同的 Terraform 代码,通过不同的工作区可以在不同的环境中创建相似但又有细微差异的资源,避免了重复编写代码。
11. 工作区的实际应用场景
为了更好地理解工作区的应用,下面列举一些常见的实际场景:
-
开发与测试
:开发人员可以在开发工作区进行代码的编写和测试,而测试人员可以在测试工作区进行全面的测试。这样可以确保开发和测试过程相互独立,提高工作效率。
-
多区域部署
:如果需要在不同的地理区域部署相同的基础设施,可以为每个区域创建一个工作区。例如,为美国东部和西部区域分别创建工作区,根据不同的区域配置不同的网络和存储资源。
-
版本控制
:在进行版本升级或功能开发时,可以创建一个新的工作区进行测试。如果测试成功,可以将该工作区的配置应用到生产工作区;如果测试失败,可以直接删除该工作区,不会影响生产环境。
12. 工作区操作示例总结
为了方便大家回顾和操作,下面将工作区的常见操作进行总结:
| 操作 | 命令 | 示例 |
| — | — | — |
| 查看所有工作区及当前工作区 |
terraform workspace list
|
admin@myhome:~$ terraform workspace list
|
| 查看当前工作区 |
terraform workspace show
|
admin@myhome:~$ terraform workspace show
|
| 创建新工作区 |
terraform workspace new
|
admin@myhome:~$ terraform workspace new testing
|
| 切换工作区 |
terraform workspace switch
|
admin@myhome:~$ terraform workspace switch default
|
| 选择工作区 |
terraform workspace select
|
admin@myhome:~$ terraform workspace select testing
|
13. 结合工作区的代码优化
在前面的示例中,我们已经看到了如何根据工作区进行条件配置。下面进一步优化代码,使其更加灵活和可维护。
variable "instance_types" {
type = map(string)
default = {
default = "t2.micro"
testing = "t2.nano"
}
}
resource "aws_instance" "vm_example" {
ami = "ami-830c94e3"
instance_type = var.instance_types[terraform.workspace]
tags = {
Name = "DevOpsGuideTerraformExample"
}
}
通过定义一个变量
instance_types
,将不同工作区对应的实例类型存储在一个映射中。这样,当需要添加或修改工作区对应的实例类型时,只需要修改这个变量即可,提高了代码的可维护性。
14. 工作区状态文件管理
每个工作区都有自己独立的状态文件,这些文件存储在
terraform.tfstate.d
目录下,以工作区名称作为子目录。了解状态文件的存储位置和管理方式对于排查问题和备份非常重要。
以下是状态文件的存储结构示例:
.
├── main.tf
├── providers.tf
├── terraform.tfstate
├── terraform.tfstate.backup
└── terraform.tfstate.d
├── default
│ └── terraform.tfstate
└── testing
└── terraform.tfstate
在实际操作中,我们可以定期备份这些状态文件,以防止数据丢失。同时,在切换工作区时,要确保状态文件的正确加载和使用。
15. 总结与展望
通过本文的介绍,我们深入了解了 Terraform 的核心概念和常见操作,包括初始化工作环境、规划变更、应用变更、修改状态、导入现有资源以及使用工作区等。Terraform 作为一款强大的基础设施即代码工具,为我们提供了高效、安全和一致的基础设施管理方式。
在未来的工作中,我们可以进一步探索 Terraform 的高级功能,如模块的使用、远程状态存储和团队协作等。同时,结合其他工具和技术,如 CI/CD 流水线,实现基础设施的自动化部署和管理,提高工作效率和质量。
下面用 mermaid 流程图展示工作区的管理流程:
graph LR
A[查看工作区列表] --> B{选择操作}
B -- 创建新工作区 --> C[terraform workspace new]
B -- 切换工作区 --> D[terraform workspace switch]
B -- 查看当前工作区 --> E[terraform workspace show]
C --> F[在新工作区执行操作]
D --> F
F --> G[terraform plan]
G --> H{是否有变更?}
H -- 是 --> I[terraform apply]
H -- 否 --> J[结束]
I --> K[terraform destroy(可选)]
通过以上内容,我们对 Terraform 的工作区有了更深入的了解,希望这些知识能帮助你更好地管理和部署基础设施。
超级会员免费看
846

被折叠的 条评论
为什么被折叠?



