[大阪/横滨/德岛] 寻找基础设施/服务器端工程师!

[大阪/横滨/德岛] 寻找基础设施/服务器端工程师!

【超过500家企业部署】AWS搭建、运维、监控服务

【超过500家企业部署】AWS搭建、运维、监控服务

【CentOS的后继者】AlmaLinux OS服务器搭建/迁移服务

【CentOS的后继者】AlmaLinux OS服务器搭建/迁移服务

[仅适用于 WordPress] 云服务器“Web Speed”

[仅适用于 WordPress] 云服务器“Web Speed”

[便宜]网站安全自动诊断“快速扫描仪”

[便宜]网站安全自动诊断“快速扫描仪”

[预约系统开发] EDISONE定制开发服务

[预约系统开发] EDISONE定制开发服务

[注册100个URL 0日元] 网站监控服务“Appmill”

[注册100个URL 0日元] 网站监控服务“Appmill”

【兼容200多个国家】全球eSIM“超越SIM”

【兼容200多个国家】全球eSIM“超越SIM”

[如果您在中国旅行、出差或驻扎]中国SIM服务“Choco SIM”

[如果您在中国旅行、出差或驻扎]中国SIM服务“Choco SIM”

【全球专属服务】Beyond北美及中国MSP

【全球专属服务】Beyond北美及中国MSP

[YouTube]超越官方频道“美由丸频道”

[YouTube]超越官方频道“美由丸频道”

使用 Terraformer 将现有基础设施资源导入 Terraform

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

,我们在下面的文章中介绍了 terraform import 命令,作为将现有资源导入 Terraform 的方法

如何在 Terraform 中导入现有基础设施资源

正如本文总结中提到的,
使用 import 命令只能重写 tfstate,因此
需要自己编写 tf 文件,同时检查与 tfstate 的差异。
如果人多的话,好像要花很多时间,这是个问题。

这对你们所有人来说都是个好消息。
名为 terraformer 的工具作为 OSS 发布。

https://github.com/GoogleCloudPlatform/terraformer

CLI 工具,用于从现有基础设施生成 terraform 文件(将基础设施逆向代码)。

正如这样写的,它似乎是一个 CLI 工具,可以从现有基础设施自动生成​​ Terraform 文件。
Github上也有介绍如何使用,我们来尝试一下。

安装

对于Mac,您可以使用brew 命令安装它。

$brew install terraformer $terraformer 版本 Terraformer v0.8.7

到目前为止,这很容易。
这次我们将使用 v0.8.7。

基础设施配置

我提前使用 terraformer 创建了要导入的基础设施。

https://github.com/beyond-teraoka/terraform-aws-multi-environment-sample

配置图

我在同一个 AWS 账户中有 3 个环境。

  1. 发展
  2. 生产
  3. 管理

此外,每个环境还具有以下资源:

  1. 专有网络
  2. 子网
  3. 路由表
  4. 互联网网关
  5. NAT网关
  6. 安全组
  7. VPC 对等互连
  8. 电子工业园区
  9. EC2
  10. 白蛋白
  11. RDS

虽然图中没有显示,但是每个环境资源都被赋予一个Environment标签,并且
dev、prod和mng被设置为每个环境的值。

准备凭据

准备您的 AWS 凭证。
请根据您的环境准备此内容。

$ cat /Users/yuki.teraoka/.aws/credentials [beyond-poc] aws_access_key_id = XXXXXXXXXXXXXXXXXX aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX [beyond-poc-admin] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/XXXXXXXXXXXXXXXX XXXX source_profile = Beyond-波克

运行地形改造者

首先,尝试执行 GitHub 上编写的示例。

$ terraformer 导入 aws --resources=alb,ec2_instance,eip,ebs,igw,nat,rds,route_table,sg,子网,vpc,vpc_peering --regions=ap-northeast-1 --profile=beyond-poc-admin 2020 /05/05 18:29:14 aws 导入区域 ap-northeast-1 2020/05/05 18:29:14 aws 导入... vpc 2020/05/05 18:29:15 open /Users/yuki.teraoka /.terraform.d/plugins/darwin_amd64:没有这样的文件或目录

执行 terraform init 时似乎需要插件目录。
准备init.tf和init.tf。

$ echo 'provider "aws" {}' > init.tf $ terraform init

我会尝试再次运行它。

$ terraformer import aws --resources=alb,ec2_instance,eip,ebs,igw,nat,rds,route_table,sg,subnet,vpc,vpc_peering --regions=ap-northeast-1 --profile=beyond-poc-admin

看来导入成功了。
已经创建了一个名为 generated 的目录,该目录此前并不存在。

目录结构

$ 树 └── aws ├── alb │ ├── lb.tf │ ├── lb_listener.tf │ ├── lb_target_group.tf │ ├── lb_target_group_attachment.tf │ ├── 输出.tf │ ├──提供商.tf │ ├── terraform.tfstate │ └── 变量.tf ├── ebs │ ├── ebs_volume.tf │ ├── 输出.tf │ ├── 提供商.tf │ └── terraform.tfstate ├ ── ec2_instance │ ├── 实例.tf │ ├── 输出.tf │ ├── 提供者.tf │ ├── terraform.tfstate │ └── 变量.tf ├── eip │ ├── eip.tf │ ├── 输出.tf │ ├── 提供者.tf │ └── terraform.tfstate ├── igw │ ├── internet_gateway.tf │ ├── 输出.tf │ ├── 提供者.tf │ ├── terraform .tfstate │ └── 变量.tf ├── nat │ ├── nat_gateway.tf │ ├── 输出.tf │ ├── 提供商.tf │ └── terraform.tfstate ├── rds │ ├── db_instance .tf │ ├── db_parameter_group.tf │ ├── db_subnet_group.tf │ ├── 输出.tf │ ├── 提供商.tf │ ├── terraform.tfstate │ └── 变量.tf ├── 路由表 │ ├ ── main_route_table_association.tf │ ├──outputs.tf │ ├──provider.tf │├──route_table.tf │├──route_table_association.tf │├──terraform.tfstate │└──variables.tf ├── sg │ ├── 输出.tf │ ├── 提供商.tf │ ├── security_group.tf │ ├── security_group_rule.tf │ ├── terraform.tfstate │ └── 变量.tf ├── 子网 │ ├─ ─ 输出.tf │ ├── 提供商.tf │ ├── 子网.tf │ ├── terraform.tfstate │ └── 变量.tf ├── vpc │ ├── 输出.tf │ ├── 提供商.tf │ ├── terraform.tfstate │ └── vpc.tf └── vpc_peering ├──outputs.tf ├──provider.tf ├──terraform.tfstate └──vpc_peering_connection.tf 13个目录,63个文件

我希望您注意目录结构。Terraformer
似乎将其导入到默认结构“{output}/{provider}/{service}/{resource}.tf”中。
这也记录在 GitHub 上。

Terraformer 默认情况下将每个资源分隔成一个文件,并将其放入给定的服务目录中。

资源文件的默认路径是 {output}/{provider}/{service}/{resource}.tf,并且可能因每个提供程序而异。

这种结构存在以下问题:

  1. 由于 tfstate 是针对每个 Terraform 资源进行划分的,因此即使是很小的更改也需要多次应用。
  2. 所有环境的资源都记录在同一个tfstate中,因此一个环境的变化会影响所有环境。

如果可以的话,我想把tfstate按照develop、生产、manage等环境来划分,
这样每个环境的所有资源都记录在同一个tfstate中。
当我研究是否可以做到这一点时,我发现了以下内容。

  1. 可以使用 --path-pattern 选项显式指定层次结构
  2. 只能导入具有使用 --filter 选项指定的标签的资源。

将这两者结合起来似乎可以实现这一点,所以让我们尝试一下。

$ terraformer import aws --resources=alb,ec2_instance,eip,ebs,igw,nat,rds,route_table,sg,subnet,vpc,vpc_peering --regions=ap-northeast-1 --profile=beyond-poc-admin - -path-pattern {输出}/{provider}/develop/ --filter="Name=tags.Environment;Value=dev" $ terraformer import aws --resources=alb,ec2_instance,eip,ebs,igw,nat,rds ,route_table,sg,子网,vpc,vpc_peering --regions=ap-northeast-1 --profile=beyond-poc-admin --path-pattern {输出}/{provider}/生产/ --filter="名称= Tags.Environment;Value=prod" $ terraformer import aws --resources=ec2_instance,eip,ebs,igw,route_table,sg,subnet,vpc,vpc_peering --regions=ap-northeast-1 --profile=beyond-poc- admin --path-pattern {output}/{provider}/manage/ --filter="Name=tags.Environment;Value=mng"

导入后的目录结构如下。

目录结构

$ 树 └── aws ├── 开发 │ ├── db_instance.tf │ ├── db_parameter_group.tf │ ├── db_subnet_group.tf │ ├── eip.tf │ ├── instance.tf │ ├── internet_gateway.tf │ ├── lb.tf │ ├── lb_target_group.tf │ ├── nat_gateway.tf │ ├──outputs.tf │ ├──provider.tf │ ├──route_table.tf │├──security_group .tf │ ├──subnet.tf │ ├── terraform.tfstate │ ├── 变量.tf │ └── vpc.tf ├── 管理 │ ├── instance.tf │ ├── internet_gateway.tf │ ├ ── 输出.tf │ ├── 提供商.tf │ ├── 路由表.tf │ ├── security_group.tf │ ├── 子网.tf │ ├── terraform.tfstate │ ├── 变量.tf │ ├─ ─ vpc.tf │ └── vpc_peering_connection.tf └── 生产 ├── db_instance.tf ├── db_parameter_group.tf ├── db_subnet_group.tf ├── eip.tf ├── instance.tf ├── internet_gateway。 tf ├── lb.tf ├── lb_target_group.tf ├── nat_gateway.tf ├── 输出.tf ├── 提供商.tf ├── 路由表.tf ├── 安全组.tf ├── 子网.tf ├ ── terraform.tfstate ├── Variables.tf └── vpc.tf 4个目录,45个文件

资源是按环境划分的。
如果你尝试在develop下查看vpc.tf,只会导入相应环境的VPC。

开发/vpc.tf

资源“aws_vpc”“tfer--vpc-002D-0eea2bc99da0550a6”{分配_生成_ipv6_cidr_block =“假”cidr_block =“10.1.0.0/16”enable_classiclink =“假”enable_classiclink_dns_support =“假”enable_dns_hostnames =“真”enable_dns_support =“真”实例_tenancy = "default" 标签 = { 环境 = "dev" 名称 = "vpc-terraformer-dev" } }

关于tfstate,每个环境的所有资源都记录在一个文件中,所以这里看起来没有问题。
内容比较长,我就不赘述了。

关注点

有些地方对资源ID值进行了硬编码。


有多个地方对资源ID值进行了硬编码,例如下面aws_security_group的vpc_id

资源“aws_security_group”“tfer--alb-002D-dev-002D-sg_sg-002D-00d3679a2f3309565”{description =“for ALB”出口{cidr_blocks = [“0.0.0.0/0”]description =“出站全部”from_port = “0”协议=“-1”self=“假”to_port=“0”}入口{cidr_blocks=[“0.0.0.0/0”]描述=“allow_http_for_alb”from_port=“80”协议=“tcp”self= “假”to_port =“80”}名称=“alb-dev-sg”标签={环境=“dev”名称=“alb-dev-sg”}vpc_id =“vpc-0eea2bc99da0550a6”}

在编写新的HCL时,像“vpc_id = aws_vpc.vpc.id”一样动态引用它,但
在导入时似乎仍然很难完成。
对于这部分,tfstate中已经记录了VPC ID,因此只需修改tf文件即可。

terraform_remote_state的描述与0.12不兼容

有些地方的HCL描述是针对Terraform 0.11系列的,例如下面aws_subnet的vpc_id。

资源“aws_subnet”“tfer--subnet-002D-02f90c599d4c887d3”{assign_ipv6_address_on_creation =“false”cidr_block =“10.1.2.0/24”map_public_ip_on_launch =“true”标签={环境=“dev”名称=“subnet-terraformer-dev” -public-1c" } vpc_id = "${data.terraform_remote_state.local.outputs.aws_vpc_tfer--vpc-002D-0eea2bc99da0550a6_id}" }

如果在这种状态下应用0.12系列,它会运行,但会出现警告。

另外,如果将 --path-pattern 选项更改为每个环境的单独目录,则
tfstate 本身将输出在一个文件中,但
在引用 tf 文件中的资源时,它们仍将被引用为 terraform_remote_state。
如果你看一下GitHub,有下面的描述,所以它就是规范。

使用 terraform_remote_state (本地和存储桶)在资源之间进行连接。

在上述 vpc_id 的情况下,aws_vpc 和 aws_subnet 记录在同一 tfstate 中,因此
可以简单地通过“vpc_id = aws_vpc.tfer--vpc-002D-0eea2bc99da0550a6.id”来引用它们。
看起来你必须自己修复这部分。

概括

你觉得怎么样?
如果使用 terraformer,导入现有基础设施似乎会更容易。
有一些担忧,但解决起来并不困难,所以我认为在可以接受的范围内。
我一直认为导入 terraform 很困难,所以我
真诚地尊重“Waze SRE”的人们,他们创建了一个工具,很好地解决了这个问题。
请大家尝试使用一下。

如果您觉得这篇文章有帮助,请点赞!
1
加载中...
1 票,平均:1.00 / 11
18,273
X Facebook 哈特纳书签 口袋
[2025.6.30 Amazon Linux 2 支持结束] Amazon Linux 服务器迁移解决方案

[2025.6.30 Amazon Linux 2 支持结束] Amazon Linux 服务器迁移解决方案

[大阪/横滨] 积极招募基础设施工程师和服务器端工程师!

[大阪/横滨] 积极招募基础设施工程师和服务器端工程师!

写这篇文章的人

关于作者

寺冈由纪

于 2016 年加入 Beyond,目前是他担任基础设施工程师
MSP 的第六个年头,他负责排除故障,同时
使用 AWS 等公共云设计和构建基础设施。
最近,我
一直在使用 Terraform 和 Packer 等 Hashicorp 工具作为构建 Docker 和 Kubernetes 等容器基础设施以及自动化操作的一部分,并且我
还扮演了在外部学习小组和研讨会上发言的传播者的角色。

・GitHub
https://github.com/nezumisannn

・演示历史
https://github.com/nezumisannn/my-profile

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

・认证:
AWS认证解决方案架构师-
谷歌云专业云架构师