Terraformメモ2

適当に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がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654538/72e878a2-261e-4d43-8de4-1f1ac3838163.png)

1. そのリソース用のterraformコード（一旦Requiredのプロパティだけでもよい）を作成
1. terraform importでリソースをstateファイルに入れる
1. terraform planを実行、デフォルトから変更している部分については差分が出てくるので、最初に作ったコードに反映
1. 再度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が作成されないことがあるので注意。

https://dev.classmethod.jp/articles/terraform-import-without-using-apply/

```
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が使える。

1. terraform state rm コマンドで旧リソースをtfstateから削除する
1. terraform import コマンドで新リソースをTerraformの管理下に取り込む
1. 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にキーを持つのがセキュリティ的にイケてない。

https://learn.microsoft.com/ja-jp/azure/developer/terraform/store-state-in-azure-storage?tabs=azure-cli

Service PrincipalでAzureにアクセスする方法についてはこちらに詳しく書いたのでこちら参照。

https://qiita.com/smr1/items/2d8f18bd60c4eca30869#remote-state%E3%81%ABazure-storage-account%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B

# ディレクトリ構造

この辺については詳しくまとめられているので、ごちゃごちゃいうより既存のものを参照。

https://zenn.dev/terraform_jp/articles/2024-08-12_terraform_directories

# 公式ガイド
あとは公式ガイドによるベストプラクティス等。Terraform 公式ガイドを参照する。

https://developer.hashicorp.com/terraform/language/style

こちらにまとめてくださっている方がいたのでリンクを貼る。

https://qiita.com/ogatango/items/9cd57fe8c48b1c03b2bd