如何在 Terraform 中导入现有基础设施资源
目录
我叫寺冈,是一名基础设施工程师。
您是否曾经想过,“我希望能够使用 Terraform 管理现有的基础设施配置?”
Terraform 提供了命令来实现此目的,因此我将在本文中介绍它们。
我没有提前使用 Terraform 创建了一个 VPC。
这次,我们将其导入 Terraform 中。
目录结构
$ tree . ├── README.md ├──provider.tf ├──terraform.tfstate ├──variables.tf └──vpc.tf 0个目录,5个文件
写入提供者和变量
导入之前,请编写提供程序和变量,因为它们是最低要求。
提供商.tf
提供商“aws” { access_key = var.access_key Secret_key = var.secret_key 区域 = var.region Should_role { role_arn = var.role_arn } }
变量.tf
#################### # 提供程序 ###################### 变量 "access_key" { 描述 = " AWS 访问密钥" } 变量 "secret_key" { 描述 = "AWS 密钥" } 变量 "role_arn" { 描述 = "AWS Role Arn" } 变量 "region" { 默认 = "ap-northeast-1" }
将您的 AWS 访问密钥等保存在环境变量中。
$ 导出 TF_VAR_access_key=XXXXXXXXXXXXXXXXXX $ 导出 TF_VAR_secret_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX $ 导出 TF_VAR_role_arn=arn:aws:iam::XXXXXXXXXXXX:角色/XXXXXXXXXXXXXXXXXXX
运行计划
尝试运行计划。
由于现在没有导入任何内容,因此执行以“无更改”结束。
$ terraform plan 正在计划之前刷新内存中的 Terraform 状态...刷新的状态将用于计算此计划,但不会持久保存到本地或远程状态存储 ------------。 -------------------------------------------------- ---------- 没有更改。这意味着 Terraform 没有检测到您的配置和实际物理资源之间存在任何差异,因此无需执行任何操作。 。
运行导入
要使用 Terraform 导入现有资源,请运行“terraform import”命令。
命令格式在 Terraform 手册(*1),因此请参考它并执行以下命令。
$ terraform import aws_vpc.vpc vpc-09a9f1827bfd851f4 错误:配置中不存在资源地址“aws_vpc.vpc”。在导入此资源之前,请在根模块中创建其配置,例如:resource "aws_vpc" "vpc" { #(资源参数)}
发生错误。
导入时,您将指定资源类型和名称,例如“aws_vpc.vpc”,对于此处指定的tf文件中的资源,将导入现有的资源信息。
因此,需要提前在tf文件中写入相应的资源。
描述vpc资源
我将其写如下。
vpc.tf
#################### # VPC #################### 资源 "aws_vpc" "vpc" { cidr_block =“10.0.0.0/16”enable_dns_support = trueenable_dns_hostnames = true标签={名称=“vpc-tfstate-test”}}
再次运行导入
我会尝试再次运行它。
这次我能够毫无问题地导入。
$ Terraform导入AWS_VPC.VPC VPC-09A9F1827BFD851F4 AWS_VPC.VPC:从ID中导入“ VPC-09A9F1827BFD851F4” ... 9F182 7bfd851f4 ] 导入成功! 导入的资源如上所示。这些资源现在处于您的 Terraform 状态,并且今后将由 Terraform 管理。
这个 terraform 导入有什么作用?
运行该命令时,您将看到已创建一个名为“terraform.tfstate”的文件。
terraform.tfstate
{“版本”:4,“terraform_version”:“0.12.24”,“序列”:1,“血统”:“c0359eb1-d905-e252-2d8d-525710adddb1”,“输出”:{},“资源”: [ {“模式”:“托管”,“类型”:“aws_vpc”,“名称”:“vpc”,“提供商”:“provider.aws”,“实例”:[{“schema_version”:1,“属性": { "arn": "arn:aws:ec2:ap-northeast-1:485076298277:vpc/vpc-09a9f1827bfd851f4", "assign_ generated_ipv6_cidr_block": false, "cidr_block": "10.0.0.0/16", "default_network_acl_id" :“acl-0cd8abfed52e0e951”,“default_route_table_id”:“rtb-08c13269b1b26c9b8”,“default_security_group_id”:“sg-007ef29e563b6f9c7”,“dhcp_options_id”:“dopt-6c0f430b”,“enable_classiclink”:假, “enable_classiclink_dns_support”:假,“ enable_dns_hostnames": true, "enable_dns_support": true, "id": "vpc-09a9f1827bfd851f4", "instance_tenancy": "default", "ipv6_association_id": "", "ipv6_cidr_block": "", "main_route_table_id": "rtb- 08c13269b1b26c9b8", "owner_id": "485076298277", "tags": { "Name": "vpc-tfstate-test" } }, "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==" } ] } ] }
如果你往里面看,你会发现你之前导入的资源的信息已经被保存了。
执行时,Terraform 会自动判断是否创建、更改或删除资源并创建资源,但这种判断是根据执行期间读取的 tf 文件与 tfstate 中写入的内容之间的差异来完成的。
也就是说,为了管理Terraform上指定的现有资源,需要改变tfstate的内容,而terraform import就是读取指定现有资源的信息并将其添加到tfstate中的命令。
再次运行计划
现在我们已经运行了 terraform import,让我们再次运行 plan。
$ terraform plan 正在计划之前刷新内存中的 Terraform 状态...刷新的状态将用于计算此计划,但不会持久保存到本地或远程状态存储中:正在刷新状态... [id= vpc-09a9f1827bfd851f4] ---------------------------------------------------------- --- -------------------------- 基础设施没有变化,这意味着 Terraform 没有检测到任何差异。您的配置和实际存在的物理资源因此无需执行任何操作。
aws_vpc.vpc 作为 Terraform 上的资源加载。
让我们将enable_dns_hostnames 更改为false。
$ terraform plan 正在计划之前刷新内存中的 Terraform 状态...刷新的状态将用于计算此计划,但不会持久保存到本地或远程状态存储中:正在刷新状态... [id= vpc-09a9f1827bfd851f4] ---------------------------------------------------------- --- -------------------------- 执行计划已生成,如下所示,资源操作用以下符号表示:~就地更新 Terraform 将执行以下操作: # aws_vpc.vpc 将就地更新 ~ resource "aws_vpc" "vpc" { arn = "arn:aws:ec2:ap-northeast-1:485076298277:vpc/vpc -09a9f1827bfd851f4“分配生成的ipv6_cidr_block = false cidr_block =“10.0.0.0/16”default_network_acl_id =“acl-0cd8abfed52e0e951”default_route_table_id =“rtb-08c13269b1b26c9b8”default_security_group_id =“sg- 007ef29e563b6f9c7”dhcp_options_id =“dopt-6c0f430b”enable_classiclink = falseenable_classiclink_dns_support = false〜 enable_dns_hostnames = true -> false enable_dns_support = true id =“vpc-09a9f1827bfd851f4”instance_tenancy =“默认”main_route_table_id =“rtb-08c13269b1b26c9b8”owner_id =“485076298277”标签={“名称”=“vpc-tfstate-test”}}计划: 0 为添加,1 为更改,0 为销毁 -------------------------------------------------- --- -------------------------------- 注意:您没有指定要保存的“-out”参数这个计划,因此 Terraform 不能保证如果随后运行“terraform apply”,这些操作将被准确执行。
这种行为是试图只改变差异。
概括
如import 命令的说明页(*2)
也就是说,你需要自己编写实际的tf文件,同时检查与tfstate的差异。以后好像会增加一个自动生成tf文件的功能,不过目前来看,目标越多就越难。 。 。
为了解决这个问题,Terraformer (*3)已作为 OSS 发布。
下次我会写一篇关于如何使用它的博客。
参考网址
*1 : https://www.terraform.io/docs/providers/aws/r/vpc.html
*2 : //www.terraform.io/docs/import/index.html
*3 : https:// /github.com/GoogleCloudPlatform/terraformer