使用Terraform/Terrafomrer导入AWS现有资源

首先

尝试使用Terraform时,很多时候会发现将现有资源导入到Terraform中比直接使用Terraform编写代码更常见。
只要阅读官方文档,就能明白如何操作。

然而,由于有些地方有点难以理解,所以我会边解释细节边给你讲解导入的步骤。

前提 tí)

    • AWSアカウント作成済

 

    • AWSリソース作成済(今回はこちらの記事で作成したlambda関数をリソースとして使用します。他のリソースでも構いません)

 

    • terraform インストール済 (参考: https://dev.classmethod.jp/articles/beginner-terraform-install-mac/)

 

    terraformer インストール済 (参考: https://beyondjapan.com/blog/2020/05/terraformer-import-existing-infrastructure/)

文件夹结构

root
  ┣━ test
  ┃   ┣━ provider.tf
  ┃   ┣━ terraform.tfvars
  ┃   ┗━ lambda.tf
    ┗━ .gitignore

为了进行导入,我们准备了必需的最低限度文件。
.gitignore是一个用于在本地操作时不将AWS密钥推送到GitHub等平台的文件,因此在仅在本地操作时无需使用。

variable "aws_access_key" {}
variable "aws_secret_key" {}

provider "aws" {
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = "us-east-2"
}
# AWSのアクセスキーとシークレットキーを記述
aws_access_key = "xxxxxxxxxx"
aws_secret_key = "xxxxxxxxxx"
# ここにlambdaのリソースをインポートしていきます
# .tfstate files
*.tfstate
*.tfstate.*

# .tfvars files
*.tfvars

# terraformer import fils
*/generated/

导入方法

使用Terraform导入现有资源。

スクリーンショット 2021-09-10 8.41.59.png

我会参考这个链接中的“Example Usage”一节来撰写一个最基本的资源模板。

# "test_lambda"の部分は任意の名前でOK
resource "aws_lambda_function" "test_lambda" {
}

这样一来,模板就完成了。

スクリーンショット 2021-09-10 8.43.18.png

在这里记录了导入所需的命令。

用中国的母语重述如下,仅提供一个选项:

$ terraform import aws_lambda_function.test_lambda my_test_lambda_function

$ 使用Terraform将my_test_lambda_function导入到aws_lambda_function.test_lambda。

如果解读这个,

$ terraform import aws_lambda_function.(import_target_name) (lambda_function_name)

$ terraform import aws_lambda_function.(要导入的目标名称) (要导入的lambda函数的名称)

以下是其中文翻译:「即为」。

本次的目的是使用名为test_lambda的导入位置,以及需要导入的lambda函数的名称start_stop_ec2_inatance,在终端上执行命令。

user@user test % terraform import aws_lambda_function.test_lambda start_stop_ec2_instance

aws_lambda_function.test_lambda: Importing from ID "start_stop_ec2_instance"...
aws_lambda_function.test_lambda: Import prepared!
  Prepared aws_lambda_function for import
aws_lambda_function.test_lambda: Refreshing state... [id=start_stop_ec2_instance]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

成功导入!只要出现“Import successful!”的日志即可意味着成功。

导入时需要注意的事项

需要注意的是,每个资源的导入命令写法是不同的。

在之前的lambda情况下,我们在命令的末尾输入了lambda函数的名称,但是对于EC2实例的情况下,我们需要在命令的末尾输入实例的id,例如如下:

使用 Terraform 将 AWS EC2 实例的资源 ID `i-12345678` 导入命名为 `aws_instance.web` 的资源。参考文档:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#import

让我们逐个检查和运行资源的导入命令吧。

使用Terraformer工具导出tf文件。

当Terraform的导入完成之后,我们接下来要使用Terraformer来编写资源的内容。

スクリーンショット 2021-09-10 8.54.57.png

基本命令如下:

$ 使用 terraformer 导入 aws –资源=(资源名称) –地区=(地区名称)

首先在GitHub上搜索您想要导入的资源名称。
搜索的原因是因为Terraformer上的资源名称有时会缩写为常见的资源名称。

スクリーンショット 2021-09-10 8.57.00.png
スクリーンショット 2021-09-10 8.59.47.png

如果您知道资源名称,请在终端中输入命令。

user@user test % terraformer import aws --resources=lambda --regions=us-east-2

2021/09/07 09:05:11 aws importing region us-east-2
2021/09/07 09:05:14 aws importing... lambda
2021/09/07 09:05:16 aws done importing lambda
2021/09/07 09:05:16 Number of resources for service lambda: 1
2021/09/07 09:05:16 Refreshing state... aws_lambda_function.tfer--test_lambda
2021/09/07 09:05:19 Filtered number of resources for service lambda: 1
2021/09/07 09:05:19 aws Connecting.... 
2021/09/07 09:05:19 aws save lambda
2021/09/07 09:05:19 aws save tfstate for lambda

如果命令成功,将创建一个 generated 目录,并且在其中生成 lambda_function.tf 文件。

把先前创建的 lambda.tf 文件的框架写入其中.

resource "aws_lambda_function" "test_lambda" {
  environment {
    variables = {
      INSTANCE_ID = "i-xxxxxxxxxx"
    }
  }

  function_name                  = "start_stop_ec2_instance"
  handler                        = "lambda_function.lambda_handler"
  memory_size                    = "128"
  package_type                   = "Zip"
  reserved_concurrent_executions = "-1"
  role                           = "arn:aws:iam::xxxxxxxxxx:role/start_stop_instance_lambda"
  runtime                        = "python3.8"
  source_code_hash               = "xxxxxxxxxxxxxxxxxxxx"
  timeout                        = "3"

  tracing_config {
    mode = "PassThrough"
  }
}

需要注意的一点是在这里有一个硬编码的位置,例如INSTANCE_ID = “i-xxxxxxxxxx”。

在推送到GitHub等平台时,我们应该将变量化,避免硬编码。

请确认是否成功进行了导入。

最终,我们将执行terraform plan来确认现有资源和Terraform上的资源是否存在差异。

user@user test % terraform plan

aws_lambda_function.test_lanmbda: Refreshing state... [id=start_stop_ec2_instance]

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.

只需要一个选项,我能用中文转述,不需要进行任何更改,完成导入。

结束

本次使用lambda进行了现有资源的导入。因为其他资源也可以用相同的步骤导入,所以请务必试一试。

bannerAds