本記事はサムザップ #1 Advent Calendar 2020の4日目の記事です。
はじめに
SREの島田です。
弊社ではインフラのコード管理にterraformというツールを使用しているのですが、既に構成管理を使用しないで作成された環境とかってよくありますよね。
- 昔ながらの手動で作成されたリソース
- terraformとは別の構成管理で作成されたリソース
- 手動で作成した方が楽なリソース
- 前任者が構築していて、どのように構築したのか分からないリソース
今回の記事ではそのような既存のリソースを簡単にインポートし、インフラコード化するやり方をご紹介致します。
ここでは実際にdatadogプロバイダーを例として取りあえげます。
※ datadogのdashboardは見た目も重要なので、最初は手作業で構築することが多いため
terraform import
まずはじめに思い浮かぶのが、 terraform import
です。
とりあえず、main.tfとprovider.tfを用意します。
main.tfの中身は適当で required
な項目だけ用意しておきます。
$ tree
.
├── main.tf
└── provider.tf
main.tf
resource "datadog_dashboard" "my_dashbord" {
title = "test"
layout_type = "ordered"
widget {}
}
provider.tf
provider "datadog" {
api_key = var.api_key
app_key = var.app_key
}
ファイルが用意できたら、環境変数にキー情報をセットし、terraform init
をして初期化します。
その後 terraform import
を行えばインポート完了です。
datadogのダッシュボードのリソースIDはURLから取得できます。(下記の画像の赤枠部分)
$ terraform import datadog_dashboard.my_dashbord [リソースID]
実行して下記のように出力されれば成功!!
datadog_dashboard.my_dashbord: Importing from ID "[リソースID]"...
datadog_dashboard.my_dashbord: Import prepared!
Prepared datadog_dashboard for import
datadog_dashboard.my_dashbord: Refreshing state... [id=[リソースID]]
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.
terraform.tfstate
ファイルができているのが確認できると思います。
※ 実行前にある場合は中身が更新されます。
$ tree
.
├── main.tf
├── provider.tf
└── terraform.tfstate
中身を確認すると先程インポートしたリソースの情報が、保存されていることが確認できると思います。
ここでリソースの情報がインポートできたので、terraform plan
を実行してみましょう。
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
datadog_dashboard.my_dashbord: Refreshing state... [id=[リソースID]]
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# datadog_dashboard.my_dashbord will be updated in-place
~ resource "datadog_dashboard" "my_dashbord" {
~~ 差分表示 省略 ~~
Plan: 0 to add, 1 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
こんな感じで現在の適当に作ったmain.tfの情報と、importしたリソースの情報の差分が表示されます。
この差分がなくなるようにmain.tfを修正すれば、既存リソースの取り込み完了です!!
....
ちょっとまて! 流石に差分取り込むのしんどいだろ!!
と思わずツッコミたくなりますよね。私も漏れなくツッコミました。
何がimportだと、全然簡単に取り込めないやん。って感じですよね。
そうなんです、terraform import
だけだと肝心のtfファイルを(今は)自動生成してくれません。
そこで使用するのが今回紹介したい terraformer
というツールです!!
terraformer
terraformerとはgoogleが作成した Terraformのtfファイルを自動生成してくれるCLI toolです。
さすが天下のgoogleさま、流石です!!
ということで早速使ってみましょう。
インストール
mac環境だとbrewが使えるので簡単です。
$ brew install terraformer
$ terraformer version
Terraformer v0.8.9
実行
実行も簡単です。対応するリソースはGitHubのREADME.mdを確認下さい。
$ terraformer import datadog --resources=dashboard --filter=dashboard=[リソースID] --api-key=${api_key} --app-key=${app_key}
importに成功するとホームにgenerated
ディレクトリが作成され、それ以下にdashboard.tf
が作成されます。
$ tree
.
├── generated
│ └── datadog
│ └── dashboard
│ ├── dashboard.tf
│ ├── outputs.tf
│ ├── provider.tf
│ └── terraform.tfstate
├── main.tf
├── provider.tf
└── terraform.tfstate
ディレクトリの構造とかも--path-pattern
オプションで自由に変更できるので、これだけで既存のリソースをすべてコード化することが可能ですね
Import current state to Terraform configuration from a provider
Usage:
import [provider] [flags]
import [provider] [command]
Available Commands:
list List supported resources for a provider
Flags:
-b, --bucket string gs://terraform-state
-c, --connect (default true)
-С, --compact (default false)
-x, --excludes strings firewalls,networks
-f, --filter strings compute_firewall=id1:id2:id4
-h, --help help for google
-O, --output string output format hcl or json (default "hcl")
-o, --path-output string (default "generated")
-p, --path-pattern string {output}/{provider}/ (default "{output}/{provider}/{service}/")
--projects strings
-z, --regions strings europe-west1, (default [global])
-r, --resources strings firewall,networks or * for all services
-s, --state string local or bucket (default "local")
-v, --verbose verbose mode
Use " import [provider] [command] --help" for more information about a command.
その他
どうでしょうか、既存リソースのtfファイルがあっという間に出来上がります。
コード化されていないプロジェクトでも導入を考えるのに十分なツールではないでしょうか。
考察
-
リソースのID値の参照がハードコーディングされてしまう
- この点だけは注意が必要です。基本的にはterraformのdataリソースなどに置き換えましょう。 -
terraform 0.13をサポートされている
- 以前利用した際は0.12対応されていなかったのですが、サポートされたみたいですね。 -
ツールの更新が盛んに行われている
- terraformの更新やプロバイダー更新も追従しているようなので助かります。
まとめ
今回は、インフラリソースのコード化によく利用されるterraformのtfファイルを、既存のリソースから自動生成することができるterraformer
を実際に使用しながら紹介しました。
datadogのdashboardを例に上げましたが、AWSやGCPなどよく使われるプロバイダーにも対応しています。
インフラリソースのコード化がまだできていないというプロジェクトが、こちらの記事をキッカケに挑戦していただけたら幸いです!
参考
terraform import
terraformer GitHub
Terraformerを使ってTerraformに既存インフラのリソースをインポートする
明日は @morimoto_kazunori の記事です。