【AWS编】Terraform官方教程【中文翻译】
这是Terraform公式教程的日文翻译。
这是一个可以通过实际操作进行学习的教程。
在【AWS篇】中,我们将在实际的AWS环境中进行基础设施的构建、修改和删除。
感谢HashiCorp的教育团队同意发布此翻译。
-
- Infrastructure | Terraform | HashiCorp Developerl
- Change Infrastructure | Terraform | HashiCorp Developer
另外,当您注册HashiCorp Learn后,您将可以在仪表板上查看教程的进度等信息。
请在此处注册。登录 – HashiCorp Learn
※另外,HashiCorp 目前没有计划对文档进行本地化。
上一次的教程”准备和导入篇”在这里。
基建的建设

安装了Terraform,现在已经准备好创建基础架构2了。
在本教程中,我们将在亚马逊网络服务(AWS)上设置EC2实例。EC2是在AWS上启动的虚拟机,常用于基础架构项目中的组件。
前提条件 tí
为了完成这个教程,您需要满足以下条件。
Terraform CLI(1.2.0+)をインストールしていること
AWS CLIをインストールしていること
AWS accountと関連する認証情報でリソースが作成できる状態にあること
要使用IAM认证信息来对Terraform的AWS提供程序进行认证,需要设置环境变量AWS_ACCESS_KEY_ID。
$ export AWS_ACCESS_KEY_ID=
接下来,我们将设置秘钥。
$ export AWS_SECRET_ACCESS_KEY=
在本教程中,我们将设置可以在AWS免费使用配额中使用的资源。对于无法使用免费使用配额而产生的任何费用,我们概不负责。
创建设定
我们称之为Terraform配置文件,用于描述基础架构的内容。首先,我们创建配置文件并定义一个AWS EC2实例。
在Terraform中,配置必须在工作目录中创建。创建一个目录用于配置。
$ mkdir learn-terraform-aws-instance
进入已创建的目录中。
$ cd learn-terraform-aws-instance
创建文件并定义基础架构。
$ touch main.tf
请打开文本编辑器并打开main.tf文件,将以下配置粘贴并保存。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
设定这个选项后,您可以使用Terraform进行部署。让我们详细看看每个区块。
Terraform区块
terraform{}块中包含Terraform的配置。让我们来描述一下在Terraform中设置基础架构所需的提供者。每个提供者都有一个source属性,定义了任意的主机名、命名空间和提供者类型。默认情况下,Terraform会从Terraform存储库中安装提供者。在本教程的示例中,aws提供者的源代码定义为hashicorp/aws。这是registry.terraform.io/hashicorp/aws的简略写法。
在`required_providers`块中,您还可以限制提供程序的版本。虽然不需要指定`version`属性,但建议您指定`version`属性以限制提供程序的版本。通过这样做,您可以防止Terraform安装不适用于所创建配置的版本的提供程序而导致出现问题。如果不指定提供程序的版本,Terraform会在初始化过程中自动下载最新版本。
请查阅供应商源文件以获取更详细的信息。
只需要提供商
提供者区块用于设置特定的提供商。在本教程中,我们将设置AWS作为提供商。提供商指的是Terraform用于创建和管理资源所使用的插件。
在Terraform的配置中,您可以编写多个提供者块,以便从不同的提供者管理资源。此外,您还可以同时使用不同的提供者。例如,您可以将AWS EC2实例的IP地址传递给DataDog的监控资源。
资源 (zī
让我们使用”resource”块来定义基础设施的构成要素。资源可以是物理的,也可能是虚拟的,例如EC2实例,或者是逻辑资源,例如Heroku应用。
资源块中有两个字符串,在块的前面。分别称为资源类型和资源名称。在本教程中,资源类型是aws_instance,资源名称是app_server。资源类型的前缀与提供程序的资源名称相对应。在配置示例中,Terraform将使用aws提供程序来管理aws_instance。同时,资源类型和资源名称将为资源分配唯一的ID。例如,EC2实例的ID是aws_instance.app_server。
在资源块中,可以传递参数并通过参数来设置资源。这些参数可以包括机器的大小、磁盘镜像的名称、VPC的ID等。在提供者参考中,列出了每个资源所需的必要参数和可选参数的列表。在本教程中,我们将AMI ID设置为Ubuntu镜像,并将实例类型设置为t2.micro,针对EC2实例进行了配置。这是AWS免费套餐中可用的。您还可以设置标签并给实例命名。
初始化目录
在新建设置或从版本控制系统检出现有设置时,需要执行terraform init来初始化目录。
在初始化工作目录时,将会下载并安装在配置文件中定义的提供程序。本教程将安装AWS提供程序。
我们立即来初始化工作目录吧。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 4.16"...
- Installing hashicorp/aws v4.17.0...
- Installed hashicorp/aws v4.17.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!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Terraform 下载 aws 提供程序,并在当前工作目录中创建名为 .terraform 的隐藏目录,并在其中安装 aws 提供程序。执行 terraform init 命令后,将输出安装的提供程序的版本。Terraform 还会创建一个名为 .terraform.lock.hcl 的锁文件。该锁文件指定了要使用的提供程序的精确版本,因此可以在想要更新项目所使用的提供程序时进行控制。
设定的格式和验证
建议使用一致的格式来设置配置文件。运行terraform fmt会自动更新当前工作目录中的配置文件,并将其格式化为易读且一致的格式。
让我们尝试对设置进行格式化。如果有任何修改过的文件,该文件名将被输出。在下面这种情况下,由于设置文件已经正确格式化,所以Terraform不会输出任何内容。
$ terraform fmt
此外,您还可以通过执行terraform validate命令来确认配置的语法正确且一致。
请确认设置已启用。如上所示的设置示例是有效的,Terraform将返回成功消息。
$ terraform validate
Success! The configuration is valid.
基础设施建设
让我们执行terraform apply来应用配置。Terraform将产生类似以下的输出。此外,由于空间限制,部分内容已省略。
$ 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.app_server will be created
+ resource "aws_instance" "app_server" {
+ ami = "ami-830c94e3"
+ arn = (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:
在进行任何更改之前,Terraform会生成一个执行计划。执行计划是指描述Terraform将执行的操作,以更改基础架构以与配置文件匹配。
执行计划的格式类似于Git等diff格式。在上面的例子中,”+”旁边是aws_instance.app_server。这意味着Terraform将创建此资源。在下一行中,写着即将设置的属性。(known after apply)的位置意味着在创建资源之前还不知道的值。例如,AWS在创建时会为实例分配ARN(Amazon资源名称)。因此,只有在应用配置更改并且AWS提供商从AWS API返回值后,才能知道arn属性的值。
目前,Terraform已暂停变更并等待变更的批准才会继续运行。如果执行计划中存在错误或危险性,Terraform在对基础架构进行更改之前在此处中断是安全的。
在本例中,如果执行计划被接受,您需要在确认消息中键入“是”,然后继续操作。执行计划可能需要几分钟才能完成。这是因为Terraform会等待EC2实例可用。
Enter a value: yes
aws_instance.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Creation complete after 36s [id=i-01e03375ba238b384]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
我们可以使用Terraform来创建基础设施!在EC2控制台上,让我们试着寻找新的EC2实例。
状态检查 de
应用配置后,Terraform将数据写入名为terraform.tfstate的文件。Terraform将存储管理资源的ID和属性于此文件中。因此,之后可以更新或删除这些资源。
Terraform的状态文件是追踪受管理资源的唯一方式。此外,状态文件通常包含机密信息。因此,必须安全地存储状态文件,并限制只有可信赖的团队成员可以访问以管理基础架构。在生产环境中,建议使用Terraform Cloud或Terraform Enterprise将状态文件存储在远程。由于Terraform还支持其他几个远程后端,因此可以使用它们来存储和管理状态文件。
让我们运行 “terraform show” 命令来检查当前状态。
$ terraform show
# aws_instance.app_server:
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
arn = "arn:aws:ec2:us-west-2:561656980159:instance/i-01e03375ba238b384"
associate_public_ip_address = true
availability_zone = "us-west-2c"
cpu_core_count = 1
cpu_threads_per_core = 1
disable_api_termination = false
ebs_optimized = false
get_password_data = false
hibernation = false
id = "i-01e03375ba238b384"
instance_state = "running"
instance_type = "t2.micro"
ipv6_address_count = 0
ipv6_addresses = []
monitoring = false
primary_network_interface_id = "eni-068d850de6a4321b7"
private_dns = "ip-172-31-0-139.us-west-2.compute.internal"
private_ip = "172.31.0.139"
public_dns = "ec2-18-237-201-188.us-west-2.compute.amazonaws.com"
public_ip = "18.237.201.188"
secondary_private_ips = []
security_groups = [
"default",
]
source_dest_check = true
subnet_id = "subnet-31855d6c"
tags = {
"Name" = "ExampleAppServerInstance"
}
tenancy = "default"
vpc_security_group_ids = [
"sg-0edc8a5a",
]
credit_specification {
cpu_credits = "standard"
}
enclave_options {
enabled = false
}
metadata_options {
http_endpoint = "enabled"
http_put_response_hop_limit = 1
http_tokens = "optional"
}
root_block_device {
delete_on_termination = true
device_name = "/dev/sda1"
encrypted = false
iops = 0
tags = {}
throughput = 0
volume_id = "vol-031d56cc45ea4a245"
volume_size = 8
volume_type = "standard"
}
}
当Terraform创建这个EC2实例时,它也会从AWS提供商那里收集资源的元数据,并将其写入状态文件。在本教程的后续步骤中,我们将参考这些值来进行配置更改,并设置其他资源和输出值的配置。
手动的状态管理
使用Terraform时,有一个名为terraform state的内建命令用于进行详细的状态管理。尝试执行list子命令,以显示项目当前状态下的资源列表。
$ terraform state list
aws_instance.app_server
故障排除
如果在terraform validate中显示成功消息,但应用更改失败,则可能发生以下常见错误。
リージョンをus-west-2以外に設定している場合、amiも変更する必要があります。AMI IDはリージョンに固有のものだからです。Amazonのドキュメントに従って自身のリージョンに固有のAMI IDを選択し、main.tfにそのIDを記述しましょう。そしてterraform applyを再度実行してみてください。
正しいリージョンのAWSアカウントにデフォルトVPCがない場合、まずWeb UIでAWS VPCダッシュボードに移動し自身のリージョンにVPCを新しく作成し、サブネットとセキュリティ・グループをそのVPCに関連付けます。次に、セキュリティ・グループのID(vpc_security_group_ids)とサブネットのID(subnet_id)の引数をaws_instanceに加え、その値を新しいセキュリティ・グループとサブネットのものに書き換えます。
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
+ vpc_security_group_ids = ["sg-0077..."]
+ subnet_id = "subnet-923a..."
}
我们来修改并保存主要的`.tf`文件,然后再次执行`terraform apply`命令试试看。
请确保在阅读后续的教程时,不要忘记刚刚添加的更改。详情请阅读来自正在运行的AWS VPC的Amazon文档。
下一步
我们可以使用Terraform创建初始基础架构,然后进入下一个教程并对基础架构进行修改。
关于在此教程中提到的概念,更多信息请参考以下HashiCorp的文档。
-
- Terraformの設定言語についてはこちら。
-
- プロバイダーについて詳しくはこちら
Terraformの他の使用例についてはこちら
AWSの認証について詳しくはこちら
terraform stateコマンドやそのサブコマンドを用いた、状態ファイルからのリソースの変更などについてはこちら
基础设施的改变 (jī chǔ shè shī de

基础设施是一直不断变化的东西。Terraform在管理这种变化方面非常有用。当更改Terraform的配置时,Terraform会构建执行计划。该执行计划只会对需要更改的基础设施部分进行修改,以使其达到所期望的状态。
如果你在项目中使用Terraform,建议你使用版本控制系统来管理配置文件,并将状态存储在远程后端,如Terraform Cloud或Terraform Enterprise。
前提
Note: “前提条件” literally means “premise conditions” or “preliminary conditions.” However, the word “条件” (conditions) is redundant when used with “前提” (premise), so it can be omitted.
假设您已经完成上一教程,才能继续学习本教程。如果未完成,请按照以下步骤继续学习本教程。
-
- Terraform CLI(1.2.0+)とデフォルトのプロファイルに設定されたAWS CLIをインストールします。詳しい手順については前回のチュートリアルをご参照ください。
learn-terraform-aws-instanceという名前のディレクトリを作成し、以下の設定をmain.tfという名前で保存してください。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
- 作成した設定で初期化します。
$ terraform init
- 設定を適用させます。確認メッセージにはyesと答えましょう。
$ terraform apply
如果設定成功應用,您就能繼續進行教學。
设定
让我们更新实例的AMI。通过将当前的AMI ID替换为新的ID,即可修改main.tf文件中aws_instance.app_server资源的提供程序块。
resource "aws_instance" "app_server" {
- ami = "ami-830c94e3"
+ ami = "ami-08d70e59c07c61a3a"
instance_type = "t2.micro"
}
这将使AMI更改为Ubuntu 16.04 AMI。在AWS提供商中,您无法在创建实例后更改该实例的AMI。因此,Terraform会先删除旧实例,然后创建新实例。
应用变更
我们来重新运行terraform apply,看看在更改设置后,Terraform如何将此更改应用于现有资源。
$ terraform apply
aws_instance.app_server: Refreshing state... [id=i-01e03375ba238b384]
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_instance.app_server must be replaced
-/+ resource "aws_instance" "app_server" {
~ ami = "ami-830c94e3" -> "ami-08d70e59c07c61a3a" # forces replacement
~ arn = "arn:aws:ec2:us-west-2:561656980159:instance/i-01e03375ba238b384" -> (known after apply)
##...
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:
以”+”或”-“开头的行,更准确地说,意味着Terraform会删除资源然后重新创建,而不是直接覆盖更新资源。在Terraform中,可以直接覆盖更新某些属性。这样的变更行以”~”开头。然而,如果要更改EC2实例的AMI,则无法直接覆盖更新,必须重新创建实例。Terraform将执行这些操作。执行计划显示了Terraform执行的内容。
另外,实施计划中注明了AMI的更改会强制替换实例。根据这一信息,我们需要调整变更内容,并在必要时避免破坏性的更新。
执行计划是否继续进行,将再次显示确认消息。请键入“是”以执行。
Enter a value: yes
aws_instance.app_server: Destroying... [id=i-01e03375ba238b384]
aws_instance.app_server: Still destroying... [id=i-01e03375ba238b384, 10s elapsed]
aws_instance.app_server: Still destroying... [id=i-01e03375ba238b384, 20s elapsed]
aws_instance.app_server: Still destroying... [id=i-01e03375ba238b384, 30s elapsed]
aws_instance.app_server: Still destroying... [id=i-01e03375ba238b384, 40s elapsed]
aws_instance.app_server: Destruction complete after 42s
aws_instance.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Still creating... [40s elapsed]
aws_instance.app_server: Creation complete after 50s [id=i-0fd4a35969bd21710]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
按照执行计划的要求,先删除现有的实例,然后重新创建实例。再次执行`terraform show`命令,可以输出与此实例相关的新值。
基础设施的移除

当不再需要基础设施时,可能会考虑删除基础设施以减少安全风险和安全成本。例如,可能会从服务中删除生产环境,或者管理诸如构建和测试系统之类的工作环境。除了构建和更改基础设施,Terraform还可以删除和重新创建已管理的基础设施。
删除
执行terraform destroy可以结束Terraform项目中管理的资源。此命令与terraform apply完全相反,它会终止状态文件中指定的所有资源。此命令不会删除在其他环境中运行且未在当前Terraform项目中管理的资源。
让我们尝试删除已创建的资源。
$ terraform destroy
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_instance.app_server will be destroyed
- resource "aws_instance" "app_server" {
- ami = "ami-08d70e59c07c61a3a" -> null
- arn = "arn:aws:ec2:us-west-2:561656980159:instance/i-0fd4a35969bd21710" -> 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:
行頭的 ” – ” 表示该实例将被删除。与 apply 类似,Terraform 将显示执行计划,并在确认消息后进行修改。
请输入“是”以继续执行该计划,并尝试删除基础设施。
Enter a value: yes
aws_instance.app_server: Destroying... [id=i-0fd4a35969bd21710]
aws_instance.app_server: Still destroying... [id=i-0fd4a35969bd21710, 10s elapsed]
aws_instance.app_server: Still destroying... [id=i-0fd4a35969bd21710, 20s elapsed]
aws_instance.app_server: Still destroying... [id=i-0fd4a35969bd21710, 30s elapsed]
aws_instance.app_server: Destruction complete after 31s
Destroy complete! Resources: 1 destroyed.
与执行apply相同,Terraform决定删除资源的顺序。在这个例子中,Terraform确认没有依赖于单个实例,并删除了该实例。在涉及多个资源的复杂情况下,Terraform将根据依赖关系以适当的顺序删除资源。
定义输入变量

条件先决
一旦完成教程到这一步,你会在一个名为”learn-terraform-aws-instance”的目录中找到一个名为”main.tf”的文件,内容如下。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "app_server" {
ami = "ami-08d70e59c07c61a3a"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
请确认在learn-terraform-aws-instance目录中执行了terraform init命令,并且设置文件与上述内容匹配。
根据变量设定实例名
现在的设置中有硬编码的数值随处可见。通过使用Terraform变量,可以编写灵活且易于重用的设置。
我们可以添加一个变量,并定义实例名称。
创建一个名为variables.tf的文件,并添加一个新的定义instance_name变量的区块。
variable "instance_name" {
description = "Value of the Name tag for the EC2 instance"
type = string
default = "ExampleAppServerInstance"
}
让我们在main.tf中更新aws_instance资源块,尝试使用新变量。通过添加instance_name变量块,如果未声明值,则instance_name将默认为”ExampleAppServerInstance”。
resource "aws_instance" "app_server" {
ami = "ami-08d70e59c07c61a3a"
instance_type = "t2.micro"
tags = {
- Name = "ExampleAppServerInstance"
+ Name = var.instance_name
}
}
应用设置
请执行设置。在确认消息中回答”是”。
$ 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.app_server will be created
+ resource "aws_instance" "app_server" {
+ ami = "ami-08d70e59c07c61a3a"
+ arn = (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.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Still creating... [40s elapsed]
aws_instance.app_server: Creation complete after 50s [id=i-0bf954919ed765de1]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
让我们再次应用设置。这次我们将使用-var标志将值传递给变量,并覆盖默认的实例名称。Terraform将把实例的名称标签覆盖为新值。在确认消息中回答yes。
$ terraform apply -var "instance_name=YetAnotherName"
aws_instance.app_server: Refreshing state... [id=i-0bf954919ed765de1]
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_instance.app_server will be updated in-place
~ resource "aws_instance" "app_server" {
id = "i-0bf954919ed765de1"
~ tags = {
~ "Name" = "ExampleAppServerInstance" -> "YetAnotherName"
}
(26 unchanged attributes hidden)
(4 unchanged blocks 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_instance.app_server: Modifying... [id=i-0bf954919ed765de1]
aws_instance.app_server: Modifications complete after 7s [id=i-0bf954919ed765de1]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
如果在命令行中设置变量,该值不会被保存。Terraform支持多种方法来使用和设置变量,可以在执行命令时省去重复输入相同值的麻烦。有关详情,请参阅更详细的教程”使用变量自定义配置”。
查询数据的输出

如果您还没有完成前一个输入变量的定义,请先完成它。
最初的设置
由于已经完成了上一次的教程实践,现在有一个名为learn-terraform-aws-instance的目录,其中应该包含以下配置文件。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "app_server" {
ami = "ami-08d70e59c07c61a3a"
instance_type = "t2.micro"
tags = {
Name = var.instance_name
}
}
variable "instance_name" {
description = "Value of the Name tag for the EC2 instance"
type = string
default = "ExampleAppServerInstance"
}
请确认您的设置与上述设置一致,并且已经在learn-terraform-aws-instance目录中完成了初始化。
$ terraform init
在继续前进之前,请应用设置。在确认消息中,回答“是”。
$ terraform apply
输出EC2实例的配置
让我们在learn-terraform-aws-instance目录下创建一个名为outputs.tf的文件。
讓我們寫入以下設定並定義 EC2 實例的 ID 和 IP 輸出。
output "instance_id" {
description = "ID of the EC2 instance"
value = aws_instance.app_server.id
}
output "instance_public_ip" {
description = "Public IP address of the EC2 instance"
value = aws_instance.app_server.public_ip
}
验证输出值
请应用此配置。这样,您就可以使用这个输出值了。让我们试着应用设置。请在确认消息上回答“是”。
$ terraform apply
aws_instance.app_server: Refreshing state... [id=i-0bf954919ed765de1]
Changes to Outputs:
+ instance_id = "i-0bf954919ed765de1"
+ instance_public_ip = "54.186.202.254"
You can apply this plan to save these new output values to the Terraform state,
without changing any real infrastructure.
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
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
instance_id = "i-0bf954919ed765de1"
instance_public_ip = "54.186.202.254"
当应用设置后,将显示Output值。可以执行terraform output来查询此Output。
$ terraform output
instance_id = "i-0bf954919ed765de1"
instance_public_ip = "54.186.202.254"
您可以使用Terraform的Output功能,将当前的Terraform项目与基础设施的其他部分或其他Terraform项目关联起来。要了解更多信息,请参阅更详细的教程“从Terraform输出数据”。
基础设施的删除
删了基础设施。确认消息回答yes。
$ terraform destroy
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_instance.app_server will be destroyed
- resource "aws_instance" "app_server" {
- ami = "ami-08d70e59c07c61a3a" -> null
- arn = "arn:aws:ec2:us-west-2:561656980159:instance/i-0bf954919ed765de1" -> null
##...
Plan: 0 to add, 0 to change, 1 to destroy.
Changes to Outputs:
- instance_id = "i-0bf954919ed765de1" -> null
- instance_public_ip = "54.186.202.254" -> null
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_instance.app_server: Destroying... [id=i-0bf954919ed765de1]
aws_instance.app_server: Still destroying... [id=i-0bf954919ed765de1, 10s elapsed]
aws_instance.app_server: Still destroying... [id=i-0bf954919ed765de1, 20s elapsed]
aws_instance.app_server: Still destroying... [id=i-0bf954919ed765de1, 30s elapsed]
aws_instance.app_server: Destruction complete after 31s
Destroy complete! Resources: 1 destroyed.
将状态远程保存起来

使用Terraform Cloud,团队内可以轻松进行版本管理、基础设施监控和基础设备上的协同工作。此外,可以安全存储API令牌和访问密钥等变量,获取用于长时间运行Terraform进程的安全稳定环境。
在本教程中,我们将把Terraform的状态迁移到Terraform Cloud。
前提条件 – premise/constraint/assumption
假设您已经完成了上一篇教程,本教程是在此基础上写的。如果您还没有完成上一篇教程,请创建一个名为”learn-terraform-aws-instance”的目录,并将下面的代码保存为”main.tf”文件。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "app_server" {
ami = "ami-08d70e59c07c61a3a"
instance_type = "t2.micro"
}
执行terraform init命令,初始化工作目录并下载所需的提供商。即使该目录已经被初始化过,再次执行terraform init也没有问题。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 4.16"...
- Installing hashicorp/aws v4.27.0...
- Installed hashicorp/aws v4.27.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!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
请接受下面的设定。要接受更改,请输入“是”。
$ 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:
##...
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
##...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Terraform用于设置AWS EC2实例并将与资源相关的数据存储在本地状态文件中。
设置Terraform Cloud。
如果您已经拥有 HashiCorp Cloud Platform 或 Terraform Cloud 的账户,请使用这些认证信息进行登录。有关注册和创建组织的详细方法,请参阅 Terraform Cloud 注册教程。
然后,在main.tf文件中进行更改。 在Terraform配置中添加一个cloud块,并将organization-name替换为自己的组织名称。
terraform {
+ cloud {
+ organization = "organization-name"
+ workspaces {
+ name = "learn-tfc-aws"
+ }
+ }
+
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
}
登录Terraform Cloud
下一步,让我们使用终端并使用Terraform CLI尝试登录Terraform Cloud。
$ terraform login
Terraform will request an API token for app.terraform.io using your browser.
If login is successful, Terraform will store the token in plain text in
the following file for use by subsequent commands:
/Users/<USER>/.terraform.d/credentials.tfrc.json
Do you want to proceed?
Only 'yes' will be accepted to confirm.
Enter a value:
如果您回答确认消息为“是”,浏览器将自动打开,请按照指示进行操作。如果需要输入,请将生成的API密钥粘贴到终端中。如需了解有关登录的更多信息,请参阅Terraform Cloud上CLI的身份验证。
进行Terraform的初始化。
因为已经配置了和 Terraform Cloud 的集成,所以可以执行 terraform init 命令,重新初始化设置并将状态文件迁移到 Terraform Cloud 上。如果出现迁移确认消息,输入“yes”即可。
$ terraform init
Initializing Terraform Cloud...
Do you wish to proceed?
As part of migrating to Terraform Cloud, Terraform can optionally copy your
current workspace state to the configured Terraform Cloud workspace.
Answer "yes" to copy the latest state snapshot to the configured
Terraform Cloud workspace.
Answer "no" to ignore the existing state and just activate the configured
Terraform Cloud workspace with its existing state, if any.
Should Terraform migrate your existing state?
Enter a value: yes
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v4.17.0
Terraform Cloud has been successfully initialized!
You may now begin working with Terraform Cloud. Try running "terraform plan" to
see any changes that are required for your infrastructure.
If you ever set or change modules or Terraform Settings, run "terraform init"
again to reinitialize your working directory.
状態ファイル已经迁移到Terraform Cloud上了,请删除本地的状态文件。
$ rm terraform.tfstate
如果您想使用CLI从Terraform Cloud操作,可以选择使Terraform在远程运行或在本地运行。如果选择在本地运行,则Terraform Cloud会执行本地机器上的Terraform,并将状态文件存储在Terraform Cloud的远程位置。在本教程中,我们将使用远程执行模式。
设置工作区变量
执行terraform init命令后,将在Terraform Cloud的Organization内创建一个名为learn-tfc-aws的工作区。要对AWS提供程序进行身份验证,请使用您自己的认证信息配置工作区。

應用設置
让我们执行`terraform apply`来运行Terraform Cloud。应该会显示没有进行任何更改。
$ terraform apply
## ...
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
------------------------------------------------------------------------
这意味着当前设置与实际存在的物理资源之间完全没有差异。因此,不需要执行任何操作。
这样做可以将状态存储在Terraform Cloud上。通过将状态存储在远程位置,可以更容易地进行协作,并将状态文件和机密信息与本地硬盘分离。远程状态只在使用时被加载到内存中。
删除基础设施
不要忘记执行terraform destroy命令来删除在本教程中创建的资源。terraform destroy命令将在Terraform Cloud上执行,并将结果输出到终端上。当确认消息显示时,请输入yes。您也可以通过Terraform Cloud的Web UI访问自己的工作空间并确认执行情况以确保操作正确。
$ terraform destroy
Running apply in Terraform Cloud. Output will stream here. Pressing Ctrl-C
will cancel the remote apply if it's still pending. If the apply started it
will stop streaming the logs, but will not stop the apply running remotely.
Preparing the remote apply...
To view this run in a browser, visit:
https://app.terraform.io/app/hashicorp-training/learn-tfc-aws/runs/run-kovFzCiUSrbMP3sD
Waiting for the plan to start...
Terraform v1.2.0
on linux_amd64
Initializing Terraform configuration...
aws_instance.app_server: Refreshing state... [id=i-0e756c00e19ec8f6b]
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_instance.app_server will be destroyed
##...
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
下一步
现在Terraform入门指南结束了。您已经学会使用Terraform创建和管理基础架构。
请参阅以下的教程,了解有关Terraform的配置语言、资源设置以及现有基础架构导入等实践技巧。
設定言語 – 変数やOutput、依存関係、メタ引数など設定言語の他の特徴に慣れてより洗練されたTerraformの設定を書きましょう。
モジュール – モジュールでTerraformの設定を整理して再利用してみましょう。
セットアップ – PackerやCloud-initを使ってみましょう。自動でSSHキーとウェブ・サーバをTerraformでAWSに作成したLinux VM上にセットアップできるようになります。
インポート – 既存のインフラをTerraformにインポートしてみましょう。
请查阅Terraform文档以获取有关可用设置选项的详细信息。
要深入了解Terraform Cloud,请参考以下内容。
Terraform可以存储状态并支持在本地执行Terraform,但当用作远程执行环境时才能发挥其真正价值。
-
- VCS方式。VCSに変更がコミットされる度に自動で計画がキューに入れられます。
- API方式。CIなどの自動化されたツールが設定を直接アップロードします。
关于VCS(Versions Control System)方式的实践经验,请参阅Terraform Cloud的入门指南。Terraform Cloud还提供商业解决方案,包括团队内权限管理、策略执行和业务代理等功能。
准确地说,”+”和”-“将替换为”加”和”减”。↩