適当にTerraformの勉強その2
Import
既存の環境をterraform管理下に入れたい場合。IaCで最初からクリーンな環境を一から作成できるのはまれで、大体既存の環境をTerraformで管理することになる。
importコマンド
terraform importコマンドはあくまでも既存のリソースをterraform stateファイルに状態として入れるだけ、実際のterraformコードは自分で書かなくてはいけない
terraform import reource {id}
f.ex.
terraform import azurerm_storage_account.storageAcc1 /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myresourcegroup/providers/Microsoft.Storage/storageAccounts/myaccount
Importコマンドの形式はそれぞれのメニューの右下にimportがある。
- そのリソース用のterraformコード(一旦Requiredのプロパティだけでもよい)を作成
- terraform importでリソースをstateファイルに入れる
- terraform planを実行、デフォルトから変更している部分については差分が出てくるので、最初に作ったコードに反映
- 再度terraform planを実行し、No changeになるまでコードを修正する
importブロック
importブロックを使うと、コードはterraformが自動的に作成してくれる。importコマンドだと自分で書く必要があり大変だった。
import {
id = {id}
to = azurerm_resource_group.rg
}
import {
id = {id}
to = azurerm_storage_account.stterasima
}
importするときは、resourceブロックを指定してからapplyする方法もあるが、terraform planをする方法でやったほうがよさそう。また、tfstateファイルは消してから実行しないと、すでに取り込み済みの場合はgenerated.tfが作成されないことがあるので注意。
terraform plan -generate-config-out=generate.tf
...
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
こんなファイルが出力される。あとはこれをmain.tfなりにはっつけて、terraform planを実行し、差分が出力されないことを確認する。
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.
# __generated__ by Terraform from "/subscriptions/{id}/resourceGroups/rg-terraformsima"
resource "azurerm_resource_group" "rg" {
location = "japaneast"
managed_by = null
name = "rg-terraformsima"
tags = {}
}
# __generated__ by Terraform
resource "azurerm_storage_account" "stterasima" {
access_tier = "Hot"
account_kind = "StorageV2"
account_replication_type = "ZRS"
account_tier = "Standard"
allow_nested_items_to_be_public = true
allowed_copy_scope = null
cross_tenant_replication_enabled = false
name = "stterasima"
...
}
あとは手動でリソースを作り直したときなどにも、手動再作成によって、実値とtfstateとの乖離が生じるため、importが使える。
- terraform state rm コマンドで旧リソースをtfstateから削除する
- terraform import コマンドで新リソースをTerraformの管理下に取り込む
- terraform planコマンドを実行し、該当リソースで差分が表示されないことを確認する
State
TerraformのStateファイルは基本的に手動で更新しない。
Terraformで管理しているリソースはTerraformで設定変更する、でないと手動で変更した設定が戻ってしまったりする。
state command
terraform state list → terraformで管理しているリソースの一覧
vscode ➜ /workspaces/FirstProject/day1 (main) $ terraform state list
azurerm_resource_group.rg
azurerm_storage_account.sa
azurerm_storage_account_static_website.static_website
azurerm_storage_blob.blob
terraform state show → terraformで管理しているリソースの詳細
vscode ➜ /workspaces/FirstProject/day1 (main) $ terraform state show azurerm_resource_group.rg
# azurerm_resource_group.rg:
resource "azurerm_resource_group" "rg" {
id = "/subscriptions/80ca150b-3763-4e87-91f4-b6a3f7db947c/resourceGroups/myResourceGroup"
location = "japaneast"
managed_by = null
name = "myResourceGroup"
terraform state rm → terraformから管理しているリソースを対象外にする
# terraformから管理しているリソースを対象外にする
# 実リソースは削除されないでそのままにする
# この後.tfファイルからも削除する必要があるので注意、そのままterraformのファイルからリソースだけ消すと次にapplyしたときにリソースが削除されてしまう
vscode ➜ /workspaces/FirstProject/day1 (main) $ terraform state rm azurerm_resource_group.rg
Removed azurerm_resource_group.rg
Successfully removed 1 resource instance(s).
Remote State をStorage Accountに格納
基本はこれに従えばいいんだけど、環境変数にStorage Accountにキーを持つのがセキュリティ的にイケてない。
Service PrincipalでAzureにアクセスする方法についてはこちらに詳しく書いたのでこちら参照。
ディレクトリ構造
この辺については詳しくまとめられているので、ごちゃごちゃいうより既存のものを参照。
公式ガイド
あとは公式ガイドによるベストプラクティス等。Terraform 公式ガイドを参照する。
こちらにまとめてくださっている方がいたのでリンクを貼る。