学习Terraform的入门教程(2)-基础篇,边创作边记忆
这是《边做边学 Terraform入门系列》的第二讲。
在第一讲的《安装和初期设置》中,我们已经准备好了使用Terraform,现在让我们先试着运行一下。
我认为最好从通过操作VPC来学习Terraform的基本命令开始。
用制作学习的方式入门Terraform系列
-
- 安装和初始设置
基础版 => 这里是本次内容
VPC版
EC2版
Route53 + ACM版
ELB版
RDS版
本次学习的重点如下。
-
- Resourceブロックの書き方
-
- terraform init / plan / apply / destroyの実行の流れ
- Terraformの実行計画の見方
创建VPC
首先,我们先创建一个用于工作的文件夹。
mkdir terraform
cd terraform/
创建一个名为provider.tf的文件,并粘贴以下代码。
文件名可以是任意的,只要扩展名是.tf。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
在provider.tf文件中,我们编写声明来创建AWS资源。我们还在这里指定了默认区域。这些都是常用语法。我们参考了官方的AWS Provider文档。
接着,创建一个名为network.tf的文件,并粘贴以下代码。
不需要将文件分开,但是将其按资源分开管理会更容易。
# Resourceブロックで「aws_vpc」を指定してVPCを作成
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "my-vpc"
}
}
我们将以resource开头的部分称为资源块。在resource后面加上以下参数,然后在大括号{}中添加参数的描述。
①第一个参数:资源类型
②第二个参数:可选的标识名
在AWS资源类型中,采用了aws_*的形式。而在Azure中,采用了azurerm_*的形式。
基本上,*的部分会填上服务名称,因此很容易联想到,但在编写时将参考官方文档。
例如,对于aws_vpc,Resource: aws_vpc。
在中国这个命名问题让人意外地困扰,但最初只是为了让它先运转起来,将其命名为example或main是个可行的选择。
让我们根据编写的代码创建资源。
要创建资源,请执行terraform apply命令。
terraform apply
╷
│ Error: Could not load plugin
│
│
│ Plugin reinitialization required. Please run "terraform init".
:
当这样做时,由于无法加载插件,将显示一个错误,提示执行terraform init命令。通过安装Terraform,命令本身可供使用,但是要使用AWS、Azure等各种服务(提供者),需要单独分离相应的插件,因此首先需要执行terraform init命令来进行下载(初始化)。
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.44.0...
- Installed hashicorp/aws v3.44.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
:
当运行”terraform init”时,将会创建一个名为.terraform的目录以及一个名为.terraform.lock.hcl的文件。可以将.terraform目录视为用于使用”AWS”提供程序的目录,将.terraform.lock.hcl文件视为用于控制依赖关系的锁定文件。
tree -a
.
├── .terraform
│ └── providers
│ └── registry.terraform.io
│ └── hashicorp
│ └── aws
│ └── 3.44.0
│ └── darwin_amd64
│ └── terraform-provider-aws_v3.44.0_x5
├── .terraform.lock.hcl
├── network.tf
└── provider.tf
那么,试着重新执行terraform apply吧。
要求确认是否要执行这些操作,输入”yes”并继续。
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_vpc.vpc will be created
+ resource "aws_vpc" "vpc" {
+ arn = (known after apply)
+ assign_generated_ipv6_cidr_block = false
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_classiclink = (known after apply)
+ enable_classiclink_dns_support = (known after apply)
+ enable_dns_hostnames = (known after apply)
+ enable_dns_support = true
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "my-vpc"
}
+ tags_all = {
+ "Name" = "my-vpc"
}
}
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_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 2s [id=vpc-0e32cf9d1213b770d]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
通过查看最后一行的「Apply complete!」,我们可以看到显示为1 added,这意味着已添加了一个资源。当我们检查控制台时,可以看到已成功创建了一个带有「my-vpc」名称标签的VPC。

虚拟私有云的更新
接下来,我们来看一下更新的动态。
让我们尝试将network.tf文件中的Name标签更改为“my-first-vpc”。
resource "aws_vpc" "vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
tags = {
Name = "my-first-vpc"
}
}
让我们再次运行terraform apply来进行应用。
terraform apply
aws_vpc.vpc: Refreshing state... [id=vpc-0e32cf9d1213b770d]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# aws_vpc.vpc will be updated in-place
~ resource "aws_vpc" "vpc" {
id = "vpc-0e32cf9d1213b770d"
~ tags = {
~ "Name" = "my-vpc" -> "my-first-vpc"
}
~ tags_all = {
~ "Name" = "my-vpc" -> "my-first-vpc"
}
# (14 unchanged attributes hidden)
}
Plan: 0 to add, 1 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_vpc.vpc: Modifying... [id=vpc-0e32cf9d1213b770d]
aws_vpc.vpc: Modifications complete after 2s [id=vpc-0e32cf9d1213b770d]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
可以从更新后的显示中发现已经更改了“changed”的状态。
请确保还可以从控制台界面更改“Name”标签。
接下来,尝试将cidr_block更改为「192.168.0.0/16」。
resource "aws_vpc" "vpc" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
tags = {
Name = "my-first-vpc"
}
}
让我们执行并应用terraform apply。
terraform apply
aws_vpc.vpc: Refreshing state... [id=vpc-0e32cf9d1213b770d]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_vpc.vpc must be replaced
-/+ resource "aws_vpc" "vpc" {
~ arn = "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-0e32cf9d1213b770d" -> (known after apply)
~ cidr_block = "10.0.0.0/16" -> "192.168.0.0/16" # forces replacement
~ default_network_acl_id = "acl-009e09c086ff9c692" -> (known after apply)
~ default_route_table_id = "rtb-0b555443103cfbe0b" -> (known after apply)
~ default_security_group_id = "sg-0af32faf28e1dfa87" -> (known after apply)
~ dhcp_options_id = "dopt-2489e243" -> (known after apply)
~ enable_classiclink = false -> (known after apply)
~ enable_classiclink_dns_support = false -> (known after apply)
~ enable_dns_hostnames = false -> (known after apply)
~ id = "vpc-0e32cf9d1213b770d" -> (known after apply)
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
~ main_route_table_id = "rtb-0b555443103cfbe0b" -> (known after apply)
~ owner_id = "123456789012" -> (known after apply)
tags = {
"Name" = "my-first-vpc"
}
# (4 unchanged attributes hidden)
}
Plan: 1 to add, 0 to change, 1 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_vpc.vpc: Destroying... [id=vpc-0e32cf9d1213b770d]
aws_vpc.vpc: Destruction complete after 0s
aws_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 3s [id=vpc-05c92959157ff59d0]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
如果像此次 cidr_block 更改的情况一样,无法通过更改现有资源来解决的情况,则会执行删除然后创建的操作。
如果在执行计划中包含”replaced”或”forces replacement”这样的字词,需要在执行之前确保它们是有意的。
删除VPC
最后,让我们删除所创建的VPC。
要删除资源,请执行terraform destroy。
像执行apply时一样,输入“yes”并执行。
terraform destroy
aws_vpc.vpc: Refreshing state... [id=vpc-05c92959157ff59d0]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_vpc.vpc will be destroyed
- resource "aws_vpc" "vpc" {
- arn = "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-05c92959157ff59d0" -> null
- assign_generated_ipv6_cidr_block = false -> null
- cidr_block = "192.168.0.0/16" -> null
- default_network_acl_id = "acl-0896f7ab7cd8e3bbd" -> null
- default_route_table_id = "rtb-0ba11eb799c733669" -> null
- default_security_group_id = "sg-0ddd72a743034c145" -> null
- dhcp_options_id = "dopt-2489e243" -> null
- enable_classiclink = false -> null
- enable_classiclink_dns_support = false -> null
- enable_dns_hostnames = false -> null
- enable_dns_support = true -> null
- id = "vpc-05c92959157ff59d0" -> null
- instance_tenancy = "default" -> null
- main_route_table_id = "rtb-0ba11eb799c733669" -> null
- owner_id = "123456789012" -> null
- tags = {
- "Name" = "my-first-vpc"
} -> null
- tags_all = {
- "Name" = "my-first-vpc"
} -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_vpc.vpc: Destroying... [id=vpc-05c92959157ff59d0]
aws_vpc.vpc: Destruction complete after 0s
Destroy complete! Resources: 1 destroyed.
可以看到被标记为”已删除”的1个。
用中国范文是:
Terraform的执行计划
正如之前所见,执行terraform apply或terraform destroy命令时,将会以“执行计划”的形式展示即将发生的变更差异。
请回顾一下您执行的命令中的 “Terraform will perform the following actions” 部分。它们分别指示了接下来将进行的操作。
-
- aws_vpc.vpc will be created
-
- aws_vpc.vpc will be updated in-place
-
- aws_vpc.vpc must be replaced
- aws_vpc.vpc will be destroyed
如果资源或参数的开头有符号,也可以进行区分。如果没有任何改变,则显示为“无更改”。
-
- 作成: +
-
- 更新: ~
-
- 削除: –
- 置き換え: -/+
重申一遍,有时候只需简单更新,有时候则需要重新构建。在这些情况下,行为与从控制台界面执行相同,但务必要经常确认执行计划。
Terraform的基本命令
在这篇文章中,我们通过创建和删除VPC,执行init → apply → destroy的流程来进行初始化、应用和删除操作,但还要了解其他常用的命令。
验证
当执行terraform validate时,可以检查语法是否正确以及参数是否合适。
# valid
terraform validate
Success! The configuration is valid.
# invalid (cidr_blockの範囲が誤っている例)
terraform validate
Error: expected cidr_block to contain a valid network Value, expected 10.0.0.0/16, got 10.0.1.0/16
│
│ with aws_vpc.vpc,
│ on network.tf line 2, in resource "aws_vpc" "vpc":
│ 2: cidr_block = "10.0.1.0/16"
计划
在先前的实践示例中,我们直接执行了terraform apply命令,但是可以通过执行terraform plan命令来仅确认执行计划。如果您只想确认执行计划而不执行apply或destroy操作,可以使用terraform plan命令。
格式
执行terraform fmt命令可以整理缩进,使代码看起来更整齐。通过添加-recursive选项,可以对包括子目录在内的所有文件进行递归格式化(如果不添加该选项,则只对当前目录下的.tf文件进行格式化)。
然而,我建议您通过安装和初始设置中介绍的VSCode扩展来启用自动格式化功能。
控制台
运行 terraform console 可以启动一个交互式控制台,方便查看变量的值和函数的评估结果。要退出控制台,请输入 exit。
terraform console
> max(5, 12, 9)
12
除了这些之外,我认为只要记住这些基本指令应该就不会有问题了。
命令执行的过程
在我个人的情况下,我通过重复init、validate、plan、apply这一系列操作来进行学习,并且在不再需要时进行destroy。由于我在不断创建和销毁学习环境,所以在安装和初始设置之后,我使用了包含-auto-approve的别名设置,以便在apply和destroy时无需输入”yes”。我按照tf init、tfv、tfp、tfa、tfd的顺序进行操作。以下是重新列出的别名设置。
alias tf="terraform"
alias tfp="terraform plan"
alias tfv="terraform validate"
alias tff="terraform fmt -recursive"
alias tfa="terraform apply -auto-approve"
alias tfd="terraform destroy -auto-approve"
这次就先说到这里。下一次我们将专门讲解VPC,包括子网和路由表等相关资源的创建方法。我希望能重新写一下VPC相关资源的创建方法!
请参考以下链接
-
- AWS Provider
-
- Resource: aws_vpc
- Terraform CLI Documentation