はじめに
Terraformを使ってみるとTerraformでコードを書く
よりも 既存リソースをTerraformにインポート
することが結構あります。
公式のドキュメントを読めばやり方はわかります。
ただ、少しわかりづらい箇所もあるので細かい部分も説明しながらインポート手順を説明していきます
前提
- 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
はGiHub等にAWSのキーをpushしないためのファイルなのでローカルだけで作業する場合は不要です。
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で既存リソースをインポート
まずは terraform リソース名
でブラウザ検索してみましょう
今回はlambdaのリソースをインポートするので terraform lambda
で検索すると
Terraform公式のリンクが表示されます
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function
こちらのリンクに記載されているExample Usage
の章を参考に最低限のリソースの雛形を書きます
# "test_lambda"の部分は任意の名前でOK
resource "aws_lambda_function" "test_lambda" {
}
これで雛形が完成です
次にインポートのコマンドを調べます
Import
の章を確認しましょう
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#import
ここにインポートの際に必要なコマンドが記載されています
$ terraform import aws_lambda_function.test_lambda my_test_lambda_function
こちらを解釈すると
$ 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 import aws_instance.web i-12345678
参照:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#import
インポートのコマンドはリソースごとに調べて実行しましょう
Terraformerでtfファイルを出力
Terraformによるインポートが終わったら、Terraformerを使ってリソースの中身を書いていきます。
GitHubに必要なコマンドとリソース名が掲載されているのでこちらを使用します
https://github.com/GoogleCloudPlatform/terraformer/blob/master/docs/aws.md
基本的なコマンドは以下の通りです
$ terraformer import aws --resources=(リソース名) --regions=(リージョン名)
まずインポートしたいリソース名をGitHub上で検索します。
検索する理由はTerraformer上でのリソース名が一般的なリソース名を省略した形になっている場合があるからです
例えばsecurity_group
をインポートしたい場合、GitHub上で 検索するとsg
で入力してね。と書いてあります
今回はlambda
をインポートしたいのでGitHub上で調べてみると、そのままlambda
がリソース名として使えそうです
リソース名がわかったらコマンドをターミナルで入力しましょう
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等にpushする際は変数化してハードコーディングを回避しましょう
インポートできたか確認
最後に既存リソースとTerraform上のリソースに差分がないかterraform plan
を実行して確認します
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.
No changes.
と出れば差分なくインポート完了です
終わり
今回はlambdaを使って既存リソースのインポートを行いました
他のリソースでも同様の手順でインポートできるのでぜひやってみてください