既存のリソースをterraform管理にする手順
簡易に手順とハマりどころをまとめておく。
過去に手動で作ってしまったGCPのCloud SQLのインスタンスやDB設定、ユーザー設定があったのでそれをterraform管理下にした話。
まず、公式にあるとおり、現在のバージョン(記事執筆時点でのlatestはv0.11.13)ではstateへの反映のみで構成(*.tf)ファイルを自動で生成してくれるところまではサポートしてないとのこと。
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管理に寄せていく流れを加速させるにはマジで早いところ対応するべきところだと思う。
というわけで実際の作業の流れは下記のようになる。
- 新しくterraformに管理させたい既存のリソース定義を空で追加
terraform import
コマンドを使って1つずつ、terraform管理に入れていく- 管理対象に入れたリソースの定義を頑張って手動で追加
terraform plan
で差分確認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いじる系はやっぱりセンシティブなんだなと。
バージョン合わせることで無事できました。