从 Terraform 1.5 及更高版本开始,您可以使用 import
块直接在您的配置中管理资源的导入。此功能简化了将现有基础设施导入 Terraform 状态的过程,消除了单独的 CLI terraform import
命令的需要。
在本文中,我们将解释 import 块以及如何使用它导入不同的资源。
什么是 Terraform 导入块?
在 Terraform v1.5.0 中引入的 Terraform import
块提供了一种声明性的方法,用于将现有基础设施资源导入 Terraform 状态文件。它使资源导入成为 Terraform 计划过程的一个组成部分——类似于其他管理资源——而不是被视为直接的状态操作。
因此,import
块提高了透明度,并将资源导入与基础设施即代码 (IaC) 的核心原则对齐,使用户能够更有效和可预测地管理他们的基础设施。
Terraform 中 import
块的语法如下:
import {
to = <resource_address>
id = <resource_identifier>
}
to
:指定您配置中导入的资源将被映射到的资源地址。id
:定义提供程序 API 中现有资源的唯一标识符。确保您的Terraform 提供程序已正确配置以访问要导入的资源。
请注意,某些资源类型可能对导入有额外要求或约束。
导入块 vs. Terraform 导入命令
import
块在Terraform中允许您直接在配置文件中定义资源,简化现有基础设施的管理。
相比之下,当使用terraform import
命令而没有import
块时,它会将现有资源链接到 Terraform 状态,但不会自动生成相应的配置到您的代码中。您必须在之后手动添加此配置。导入命令特别适用于一次性导入或将基础设施过渡至 Terraform 管理。
这两种方法都需要仔细处理,以确保 Terraform 状态与实际基础设施之间的一致性。Import
块通常更适合持续资源管理,而独立命令则适用于偶尔的导入。
示例1:使用Terraform导入块导入S3存储桶
假设我们有一个现有的AWS S3存储桶(my-existing-bucket
),您希望使用Terraform 进行管理。
resource
块指定了S3存储桶(aws_s3_bucket.example
),bucket
属性定义了现有存储桶的名称:
resource "aws_s3_bucket" "example" {
bucket = "my-existing-bucket"
}
import {
to = aws_s3_bucket.example
id = "my-existing-bucket"
}
import
块将现有的S3存储桶链接到Terraform资源。
to
:将导入的资源映射到resource
块的地址(aws_s3_bucket.example
)id
:指定存储桶的唯一ID(my-existing-bucket
)。
当您运行terraform plan
时,Terraform会读取import
块,检查现有S3存储桶的状态,并显示将对状态文件进行的更改预览。然后,在运行terraform apply
之后,Terraform会更新状态文件以包括现有存储桶,并将其映射到aws_s3_bucket.example
资源。
在运行terraform apply
并成功导入资源后,最佳做法是删除import
块。保留它不会造成任何损害,但删除它有助于保持清洁的配置并在未来状态管理过程中减少潜在的混淆。
示例2:使用Terraform导入块导入EC2实例
让我们再看一个例子:我们有一个现有的ID为i-1234567890abcdef0
的EC2实例,并希望将其纳入Terraform管理。
我们在resource
块中定义我们希望Terraform管理的aws_instance
资源。确保属性(例如ami
、instance_type
)与现有实例的配置匹配:
resource "aws_instance" "example" {
ami = "ami-0abcdef1234567890" # Replace with the actual AMI ID
instance_type = "t2.micro"
}
import {
to = aws_instance.example
id = "i-1234567890abcdef0"
}
在import
块中:
to
:将您配置中的资源(aws_instance.example
)映射到现有资源。id
:指定要导入的EC2实例的唯一ID。
一旦您将资源块和导入语句添加到Terraform配置文件中,运行terraform plan
以预览更改。接下来,运行terraform apply
将资源导入Terraform的状态文件。
导入后,Terraform将管理现有的EC2实例,确保其配置保持声明性。
示例3:使用Terraform导入块导入Azure资源组
在下一个示例中,我们将导入一个Azure资源组。
我们有一个现有的Azure资源组,名称为example-resource-group
,位于East US
地区,我们希望用Terraform来管理它。
首先,在resource
块中,我们定义Terraform将管理的azurerm_resource_group
资源:
resource "azurerm_resource_group" "example" {
name = "example-resource-group"
location = "East US"
}
import {
to = azurerm_resource_group.example
id = "/subscriptions/<subscription_id>/resourceGroups/example-resource-group"
}
导入块:
to
:将您配置中的资源(azurerm_resource_group.example
)映射到现有的Azure资源。id
:指定资源组的完全限定Azure资源ID。请记得用您的实际订阅ID替换<subscription_id>
。
将资源和导入块添加到您的Terraform配置文件中。接下来,运行terraform plan
命令预览更改,并执行terraform apply
来应用更改并将资源导入到Terraform的状态文件中。
可以有条件地使用Terraform导入块吗?
Terraform 导入块设计为声明性,并需要在计划时间知道特定值。因此,它不能在 Terraform 代码中有条件地使用。
导入块不支持根据条件确定导入 ID 的动态表达式或变量。尝试在导入块中使用像 count 或变量这样的结构将导致错误,因为 Terraform 不允许在此上下文中使用这些参数。
关键要点
在 Terraform 1.5+ 中引入导入块简化了资源管理,通过在配置文件中直接导入和定义资源。它符合IaC 原则,通过减少复杂性并使将现有基础设施集成到 Terraform 配置中变得更容易。
Source:
https://dzone.com/articles/how-to-use-terraform-import-block