FFFT

主にwebプロダクト開発に関連する話をつらつらと

既存のリソースをterraform管理にする手順

簡易に手順とハマりどころをまとめておく。

過去に手動で作ってしまったGCPのCloud SQLインスタンスやDB設定、ユーザー設定があったのでそれをterraform管理下にした話。

まず、公式にあるとおり、現在のバージョン(記事執筆時点でのlatestはv0.11.13)ではstateへの反映のみで構成(*.tf)ファイルを自動で生成してくれるところまではサポートしてないとのこと。

www.terraform.io

The current implementation of Terraform import can only import resources into the state. It does not generate configuration. A future version of Terraform will also generate configuration.

今後のバージョンアップで設定ファイルも自動で出力してくれるようにするみたいだが熱望。
この後の流れでさらっとまとめるがすでに動いている環境のリソース定義を手動で構成ファイルにまとめていくのは心臓によろしくないし、俺何やってるんだろう状態になる。
とりあえずplanを叩くことがやたら多かった。
terraformで管理されていない環境をまるっとterraform管理に寄せていく流れを加速させるにはマジで早いところ対応するべきところだと思う。

というわけで実際の作業の流れは下記のようになる。

  1. 新しくterraformに管理させたい既存のリソース定義を空で追加
  2. terraform import コマンドを使って1つずつ、terraform管理に入れていく
  3. 管理対象に入れたリソースの定義を頑張って手動で追加
  4. terraform plan で差分確認
  5. terraform apply

新しくterraformに管理させたい既存のリソース定義を空で追加

公式より。

Because of this, prior to running terraform import it is necessary to write manually a resource configuration block for the resource, to which the imported object will be mapped.

とのこと。
空で追加していく。

Cloud SQLインスタンスとDB, ユーザーをterraform管理下にしたい。
下記を構成ファイルに追加する。

resource "google_sql_database_instance" "instance-name" {
}

resource "google_sql_database" "db-name" {
}

resource "google_sql_user" "user-name" {
}

terraform import コマンドを使って1つずつ、terraform管理に入れていく

terraform importコマンドを使う。
www.terraform.io


残念ながら一括でリソース指定はできないよう。
terraformをstaging, productionそれぞれで使っている人が多い気がするので対象のリソースが多ければスクリプトを組んでまとめた方が安全な気がします。

実際のコマンドの使い方は下記。

terraform import ${リソースタイプ} ${ID}

ここで言うIDはすでに環境で稼働しているリソースを一意に識別するもの。
IDはリソースタイプによって指定方法が異なるので、公式で一つ一つ指定方法を確認していく必要がある。

それぞれのリソースタイプのリファレンスの下部にimportの指定方法が記載されている。(見つけにくかった。)

https://www.terraform.io/docs/providers/google/r/sql_database_instance.html#import
https://www.terraform.io/docs/providers/google/r/sql_database.html#import
https://www.terraform.io/docs/providers/google/r/sql_user.html#import

今回はそれぞれ下記のようになった。

terraform import google_sql_database_instance.instance-name ${プロジェクト名}/${インスタンス名}
terraform import google_sql_user.user-name ${インスタンス名}/${ホスト名}/${ユーザー名}
terraform import google_sql_database.db-name ${インスタンス名}/${データベース名}

実行。

が、下記のようなエラーが。。。

Error: Provider "kubernetes" depends on non-var "google_container_cluster.hoge_cluster.0/google_container_cluster.hoge_cluster.N". Providers for import can currently
only depend on variables or must be hardcoded. You can stop import
from loading configurations by specifying `-config=""`.

解決策はこちら。
keyama.hatenablog.com

管理対象に入れたリソースの定義を頑張って手動で追加

頑張る。

後はplanを叩きつつ、修正しながら差分チェックしてオッケーであればapply。

ここで自分はterraform importを実行した環境のバージョンとterraform plan, terraform applyを実行したバージョンのパッチバージョンが異なることで怒られた。

Error: 
Terraform doesn't allow running any operations against a state
that was written by a future Terraform version. The state is
reporting it is written by Terraform '0.11.10'

Please run at least that version of Terraform to continue.

パッチバージョンのズレも許さない徹底感。
stateいじる系はやっぱりセンシティブなんだなと。

バージョン合わせることで無事できました。