如何使用 Terraform 导入现有基础设施资源

我叫寺冈,是一名基础设施工程师。

你是否曾经想过,“我想用 Terraform 来管理我现有的基础设施配置?”
Terraform 提供了一些命令来实现这一点,我将在本文中介绍这些命令。

我事先创建了一个 VPC,但没有使用 Terraform。

这次,我们将把它导入到 Terraform 中。

目录结构

$ tree . ├── README.md ├── provider.tf ├── terraform.tfstate ├── variables.tf └── vpc.tf 0 个目录,5 个文件

描述提供者和变量

导入之前,我们需要先编写提供程序和变量,因为这是最低要求。

provider.tf

provider "aws" { access_key = var.access_key secret_key = var.secret_key region = var.region assume_role { role_arn = var.role_arn } }

variables.tf

#################### # 提供商 ################### 变量 "access_key" { description = "AWS 访问密钥" } 变量 "secret_key" { description = "AWS 秘密密钥" } 变量 "role_arn" { description = "AWS 角色 ARN" } 变量 "region" { default = "ap-northeast-1" }

将您的 AWS 访问密钥存储在环境变量中。

$ export TF_VAR_access_key=XXXXXXXXXXXXXXXXXX $ export TF_VAR_secret_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX $ export TF_VAR_role_arn=arn:aws:iam::XXXXXXXXXXXX:role/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 ################### resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "vpc-tfstate-test" } }

再次运行导入程序

我们再试一次。
这次导入很顺利。

$ terraform import aws_vpc.vpc vpc-09a9f1827bfd851f4 aws_vpc.vpc: 正在从 ID "vpc-09a9f1827bfd851f4" 导入... aws_vpc.vpc: 导入已准备就绪!已准备好 aws_vpc 以进行导入 aws_vpc.vpc: 正在刷新状态... [id=vpc-09a9f1827bfd851f4] 导入成功!已导入的资源如上所示。这些资源现在已添加到您的 Terraform 状态中,并将由 Terraform 进行管理。.

这条 Terraform 导入命令的作用是什么?
运行该命令后,你会看到创建了一个名为“terraform.tfstate”的文件。

terraform.tfstate

{ "version": 4, "terraform_version": "0.12.24", "serial": 1, "lineage": "c0359eb1-d905-e252-2d8d-525710adddb1", "outputs": {}, "resources": [ { "mode": "managed", "type": "aws_vpc", "name": "vpc", "provider": "provider.aws", "instances": [ { "schema_version": 1, "attributes": { "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": false, "enable_classiclink_dns_support": false, "enable_dns_hostnames": true, "enabledns_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 状态... 刷新后的状态将用于计算此计划,但不会持久化到本地或远程状态存储。 aws_vpc.vpc:正在刷新状态... [id=vpc-09a9f1827bfd851f4] --------------------------------------------------------------------------- 无更改。基础设施已是最新状态。这意味着 Terraform 未检测到您的配置与实际存在的物理资源之间存在任何差异。因此,无需执行任何操作。.

aws_vpc.vpc 已作为资源加载到 Terraform 中。
让我们将 enable_dns_hostnames 设置为 false。

$ terraform plan 在执行计划之前,正在刷新内存中的 Terraform 状态... 刷新后的状态将用于计算此计划,但不会持久化到本地或远程状态存储。 aws_vpc.vpc:正在刷新状态... [id=vpc-09a9f1827bfd851f4] --------------------------------------------------------------------------- 已生成执行计划,如下所示。资源操作用以下符号表示:~ 就地更新 Terraform 将执行以下操作:# aws_vpc.vpc 将被就地更新 ~ 资源 "aws_vpc" "vpc" { 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 = false enable_classiclink_dns_support = false ~ enable_dns_hostnames = true -> false enable_dns_support = true id = "vpc-09a9f1827bfd851f4" instance_tenancy = "default" main_route_table_id = "rtb-08c13269b1b26c9b8" owner_id = "485076298277" tags = { "Name" = "vpc-tfstate-test" } } 计划:0 个要添加,1 个要更改,0 个要销毁。 --------------------------------------------------------------------------- 注意:您没有指定“-out”参数来保存此计划,因此 Terraform 无法保证如果随后运行“terraform apply”,这些操作将完全执行。.

它似乎只想改变差异。

概括

导入命令说明页(※2)所述

换句话说,你需要一边查看与 tfstate 的差异,一边自己编写实际的 tf 文件。未来似乎会添加自动生成 tf 文件的功能,但就目前而言,目标越多,难度就越大……

为了解决这个问题,Terraformer (※3)作为开源软件发布了。
我将在下一篇博文中解释如何使用它。

参考网址

*1 https://www.terraform.io/docs/providers/aws/r/vpc.html
*2 //www.terraform.io/docs/import/index.html
*3 //github.com/GoogleCloudPlatform/terraformer

 

如果您觉得这篇文章有用,请点击【点赞】!
2
加载中...
2票,平均分:1.00/12
42,104
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

寺冈由纪

他于 2016 年加入 Beyond 公司,目前已是第六年
担任 MSP(托管服务提供商)的基础设施工程师,负责故障排除以及
使用 AWS 等公有云设计和构建基础设施。近期,他开始

使用 HashiCorp 的 Terraform 和 Packer 等工具,用于构建和运维
Docker 和 Kubernetes 等容器基础设施的自动化流程。此外,他还扮演着技术推广者的角色,经常在外部学习小组和研讨会上发表演讲。

・GitHub
https://github.com/nezumisannn

・讲述历史
https://github.com/nezumisannn/my-profile

・演示材料(SpeakerDeck)
https://speakerdeck.com/nezumisannn

・认证:
AWS认证解决方案架构师 - 助理级、
Google Cloud专业云架构师