【備忘録】TerraformのInstall & 既存AWS環境の情報をHCLとして出力

# 背景
- AWS環境を個人で触り始めたが、いかんせん費用が発生するのがつらい
- ということで、使いたいときにだけリソースを作成し、終了したらリリース(削除)することでコストカットしたい

# 目的
- いい機会なので、業務でも使い始めたTerraformを使って解決してみた
※ちなみに対応したリソースは以下
   - VPC
   - サブネット
   - ルートテーブル
   - ネットワーク ACL 
   - インターネットゲートウェイ
   - セキュリティグループ
   - IAM ロール
   - EC2

# 参考資料

https://qiita.com/future_kame/items/e6766662e21f57384bbb

https://dev.classmethod.jp/articles/aws-with-terraform/

https://registry.terraform.io/providers/hashicorp/aws/latest/docs

https://qiita.com/Hikosaburou/items/1d3765d85d5398e3763f

# 利用したもの/環境
- AWS
- Terraform Version: 1.11.3
- Windows 11
- Microsoft Edge
- WSL2 Ubuntu(Windows Terminalのコマンド調べるの面倒だった)

# 目次
- Terraformのインストール
- 初期設定
   - Terraformの初期設定
   - AWSの認証情報設定
- AWS環境の既存リソースをHCL言語としてコード化
   - VPC
   - Subnet
   - Security Group
   - IAM 
   - EC2
   - Host Zone
- ハードコーディングの削除
- 再構築と削除
   - 別環境で同じリソースを構築
   - 前の環境を削除
- 終わりに


# Terraformのインストール
- 個人PCにはTerraformを入れていなかったので、インストールからスタート
- 公式ページからダウンロード

https://developer.hashicorp.com/terraform/install#windows

- Windows 11なのでもちろんAMD64の方をインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/266af4f1-1f14-4232-9a45-2a4c683b081c.png)

- 全然関係ないけど、上記画像のWindowsの左側、386はIntelの32bit CPUの名称の一つであるi386(もしくはIntel 80386)から来てるっぽい
- x86はよく聞くけど、386は初耳だった。。。どうやら、Intelの型番が80186,80286,80386....と続いたため、それらを総称してx86という呼び方になったらしい。~~いつも思うけど、普通に32bitって書いてくれよ~~

https://ja.wikipedia.org/wiki/Intel_80386#:~:text=Intel%2080386%20%EF%BC%88%E3%81%BE%E3%81%9F%E3%81%AF%20i386%EF%BC%89%E3%81%AF%20%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AB%20%E3%81%AE%2032%E3%83%93%E3%83%83%E3%83%88%20%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5,%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%20%E3%82%92%E5%BC%B7%E5%8C%96%E3%81%97%E3%81%9F%E3%80%82%20%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AB%E3%81%8C%E7%8F%BE%E5%9C%A8%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E5%90%8D%E7%A7%B0%E3%81%AF%20Intel386TM%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B5%20%28Intel386TM%20Processor%29%20%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82%20%E4%BA%92%E6%8F%9BCPU%E3%81%AB%E3%82%82386%E3%81%AE%E5%9E%8B%E7%95%AA%E3%81%8C%E4%BB%98%E3%81%8F%E3%82%82%E3%81%AE%E3%81%8C%E3%81%82%E3%82%8B%E3%80%82

- ダウンロードしたら、zipファイルを解凍
- Terraformの実行ファイルがあるだけなので、好きな場所に置いて環境変数にパスを通す必要がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/06437273-c942-444a-be62-5512e7e86c7e.png)
- とりあえずインストールしたアプリがよく置かれているAppDataディレクトリに、Terraformディレクトリを作成して実行ファイルを格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/47b889f9-88bc-49a7-8bde-dcccbecfb35d.png)
- 環境変数にファイルを格納したディレクトリのパスを追加
![スクリーンショット 2025-03-27 222601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/0e492f50-32f6-448c-8a60-1c3bf2c4ea10.png)
- PCを再起動してコマンドプロンプトでバージョン確認のコマンドを実行。無事インストール完了
```terminal:Windows Terminal
> terraform -v
Terraform v1.11.3
on windows_amd64
```

# 初期設定
## Terraformの初期設定
- まず、terraformの基本設定のファイルを作成
```hcl:provider.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}
```
- 次に、terraform側に設定ファイルを読み込ませるため、initを実行
```terminal:Windows Terminal
> terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.92.0...
- Installed hashicorp/aws v5.92.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```
- 試しにllしてみると、lockファイルと.terraformディレクトリができていることが確認できる
```terminal:WSL2
> ll
total 4
drwxr-xr-x 1  4096 Mar 27 22:54 ./
drwxr-xr-x 1  4096 Mar 27 22:39 ../
drwxr-xr-x 1  4096 Mar 27 22:54 .terraform/
-rwxr--r-- 1  1406 Mar 27 22:54 .terraform.lock.hcl*
-rw-r--r-- 1   116 Mar 27 22:53 provider.tf
```
## AWSの認証情報設定
### Organaizationを切っている（もしくは切る)場合
- 先人の資料の方が分かりやすかったため、資料のみ共有
- 後述の手順でも使うので、基本的にこちらがおすすめ

https://qiita.com/kzmqiita/items/55d34245f5adb7ecc4b7

- 上記完了後、terraformに認証情報を設定する方法については以下を参照してください

https://dev.classmethod.jp/articles/how-to-use-terraform-with-aws-sso-permission/

### RootアカウントでIAMを発行して、トークン情報をとってくる場合
:::note alert
公式でも推奨されていないので必要な場合のみ実施、終わったらアクセスキーの削除を行いましょう
:::


- 今時、Organaizationを切ってない環境なんて珍しいだろうけど、古いaws環境や個人開発ではありうるので記載

- まずは、AWS環境でアクセスキーを発行。以下のように警告されるが無視して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/081a3f92-d56d-4858-9e80-253f1a176616.png)
- 次の画面でアクセスキーとシークレットキーが取得できるので、ローカルのメモ帳等に貼り付け
![スクリーンショット 2025-04-02 214126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/f1de55d5-ede9-4d7d-bf93-b8ca0b532388.png)

- コマンドプロンプトに戻り、provider.tfを修正
```hcl:provider.tf
//ファイルの末尾に以下を追加
provider "aws" {
  access_key = var.access_key // アクセスキー
  secret_key = var.secret_key // シークレットキー
  region = "ap-northeast-1" // 東京リージョン
}
```
- 引数を管理するファイルであるterraform.tfvarsを作成し、先ほどメモしたアクセスキーとシークレットキーを貼り付け
```hcl:variables.tf
access_key = "[アクセスキー]"
secret_key = "[シークレットキー]"
```
- 順序が逆ではあるが、terraformに上記の変数を認識してもらうための定義を作成
```hcl:variables.tf
variable "access_key" {
  type = string
  description = "AWSアクセスキー"
}

variable "secret_key" {
  type = string
  description = "AWSシークレットキー"
}
```

- 一応terraform init
```terminal:Windows Terminal
> terraform init
```

# AWS環境の既存リソースをHCL言語としてコード化
- コード化するためにあらかじめtfファイルを作成し、各リソースのIDを指定してインポートをする必要があるらしい
- 各リソースごとに実施内容とその結果を記載
- 1件目のVPCをコード化する箇所のみ細かく記載してそれ以外は流れ作業で書いてるので、具体的な内容が見たい人はVPCのケースを読んでね～

## VPC
- AWS上でVPCリソースのIDを確認(矢印で指してるとこ)
![スクリーンショット 2025-04-02 215234.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/2e7a89e0-27e6-42d9-89a2-8e29d574b224.png)

- コマンドラインで以下の内容のファイルを作成
```hcl:network.tf
resource "aws_vpc" "terraform-sample-vpc" {

}
```
- ちなみに、「terraform-sample-vpc」はterraform内でどのVPCかを判別するためのエイリアスなので、適当な名前でOK(他のリソースでも同様)
- 実際のリソース情報をimport
```terminal:Windows Terminal
> terraform import  aws_vpc.terraform-sample-vpc [VPCリソースID]

aws_vpc.terraform-sample-vpc: Importing from ID "[VPCリソースID]"...
aws_vpc.terraform-sample-vpc: Import prepared!
  Prepared aws_vpc for import
aws_vpc.terraform-sample-vpc: Refreshing state... [id=[VPCリソース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.

```

- 成功すると、リソース情報として以下のファイルが生成される
:::note info
terraformで管理するリソースを追加する、というコマンドなので、別のリソースをimportコマンドで指定してもう一度実行した場合は、terrafrom.tfstateを上書きではなく、追記をしてくれます。便利ですね～
:::


```hcl:terraform.tfstate
{
  "version": 4,
  "terraform_version": "1.11.3",
  "serial": 1,
  "lineage": "****",
  "outputs": {},
  "resources": [
    {
      "mode": ""****",",
      "type": "aws_vpc",
      "name": "terraform-sample-vpc",
      "provider": "****",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "arn": "****",
            "assign_generated_ipv6_cidr_block": false,
            "cidr_block": "****",
            "default_network_acl_id":"****",
            "default_route_table_id": "****",
            "default_security_group_id": "****",
            "dhcp_options_id": "****",
            "enable_dns_hostnames": true,
            "enable_dns_support": true,
            "enable_network_address_usage_metrics": false,
            "id": "****",
            "instance_tenancy": "default",
            "ipv4_ipam_pool_id": null,
            "ipv4_netmask_length": null,
            "ipv6_association_id": "",
            "ipv6_cidr_block": "",
            "ipv6_cidr_block_network_border_group": "",
            "ipv6_ipam_pool_id": "",
            "ipv6_netmask_length": 0,
            "main_route_table_id": "****",
            "owner_id": "****",
            "tags": {},
            "tags_all": {}
          },
          "sensitive_attributes": [],
          "private": "****",
        }
      ]
    }
  ],
  "check_results": null
}
```
- また、以下を実行すればわざわざterraform.tfstateを見なくても指定したリソースのパラメータを確認可能
```terminal:Windows Terminal
> terraform state show aws_vpc.terraform-sample-vpc

# aws_vpc.terraform-sample-vpc:
resource "aws_vpc" "terraform-sample-vpc" {
    arn                                  = "******"
    assign_generated_ipv6_cidr_block     = false
    cidr_block                           = "******"
    default_network_acl_id               = "******"
    default_route_table_id               = "******"
    default_security_group_id            = "******"
    dhcp_options_id                      = "******"
    enable_dns_hostnames                 = true
    enable_dns_support                   = true
    enable_network_address_usage_metrics = false
    id                                   = "******"
    instance_tenancy                     = "default"
    ipv6_association_id                  = null
    ipv6_cidr_block                      = null
    ipv6_cidr_block_network_border_group = null
    ipv6_ipam_pool_id                    = null
    ipv6_netmask_length                  = 0
    main_route_table_id                  = "******"
    owner_id                             = "******"
    tags                                 = {}
    tags_all                             = {}
}
```
- 上記で確認できたＶＰＣのリソース情報をnetwork.tfに肉づけしていく
- デフォルト値とは異なる箇所だけ入れればいいので、コピーするのは以下のみ
```
    cidr_block                           = "******" // 
    enable_dns_hostnames                 = true
    enable_dns_support                   = true
```
- あとやってるときに気づいたが、名前を付けていなかったのでtagもついでに追加。その結果は以下

```hcl:network.tf
resource "aws_vpc" "terraform-sample-vpc" {
    cidr_block                           = "******"  // IPv4 CIDR
    enable_dns_hostnames                 = true      // DNS ホスト名を有効化
    enable_dns_support                   = true      // DNS 解決を有効化
  tags = {
    Name = "my_vpc"
  }
}
```
- 上記ができたら、``` terraform plan ```を実行してterraform.tfstateとの差分がtagのみであることを確認
```terminal:Windows Terminal
> terraform plan
aws_vpc.terraform-sample-vpc: Refreshing state... [id=[VPCリソースID]]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_vpc.terraform-sample-vpc will be updated in-place
  ~ resource "aws_vpc" "terraform-sample-vpc" {
        id                                   = "[VPCリソースID]"
      ~ tags                                 = {
          ~ "Name" = null -> "my_vpc"
        }
      ~ tags_all                             = {
          ~ "Name" = null -> "my_vpc"
        }
        # (18 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

```
- ```terrafrom plan```を実行して反映されることをAWS上で確認
```
> terraform apply 
aws_vpc.terraform-sample-vpc: Refreshing state... [id=[VPCリソースID]]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_vpc.terraform-sample-vpc will be updated in-place
  ~ resource "aws_vpc" "terraform-sample-vpc" {
        id                                   = "[VPCリソースID]"
      ~ tags                                 = {
          ~ "Name" = null -> "my_vpc"
        }
      ~ tags_all                             = {
          ~ "Name" = null -> "my_vpc"
        }
        # (18 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_vpc.terraform-sample-vpc: Modifying... [id=[VPCリソースID]]
aws_vpc.terraform-sample-vpc: Modifications complete after 1s [id=[VPCリソースID]]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```
- 実行前
![スクリーンショット 2025-04-06 230937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/f114a6b5-a85e-45de-81ef-dbea614fb01f.png)

- 実行後
![スクリーンショット 2025-04-06 231120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/907f6082-4485-40ed-9ee7-edbdddb53bf0.png)

## サブネット
- リソースの数だけ定義を追加
```hcl:network.tf
// 末尾に以下を追加

resource "aws_subnet" "terraform-sample-subnet1a" {
}

resource "aws_subnet" "terraform-sample-subnet1c" {
}

resource "aws_subnet" "terraform-sample-subnet1d" {
}
```

- ```terraform import```を実行
:::note info
一括で取得する方法(terraformerやimportブロック等)はあったのですが、今回はそこまでたくさんリソースがあるわけではないので複数回コマンドを叩いてます
:::

```terminal: Windows Terminal
> terraform import aws_subnet.terraform-sample-subnet1a [SubnetリソースID]
> terraform import aws_subnet.terraform-sample-subnet1c [SubnetリソースID]
> terraform import aws_subnet.terraform-sample-subnet1d [SubnetリソースID]
```

- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)
```
//　resources内に追加されたもののみ抜粋
    {
      "mode": "managed",
      "type": "aws_subnet",
      "name": "terraform-sample-subnet1a",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
          // Subnetの設定情報
        }
      ]
    },
    {
      "mode": "managed",
      "type": "aws_subnet",
      "name": "terraform-sample-subnet1c",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
          // Subnetの設定情報
        }
      ]
    },
    {
      "mode": "managed",
      "type": "aws_subnet",
      "name": "terraform-sample-subnet1d",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
          // Subnetの設定情報
        }
      ]
    },
```

- 定義しているファイル内に設定情報を肉付け

```hcl: network.tf
resource "aws_vpc" "terraform-sample-vpc" {
    cidr_block                           = "******"  // IPv4 CIDR
    enable_dns_hostnames                 = true      // DNS ホスト名を有効化
    enable_dns_support                   = true      // DNS 解決を有効化
  tags = {
    Name = "my_vpc"
  }
}

resource "aws_subnet" "terraform-sample-subnet1a" {
   availability_zone          = "ap-northeast-1a"
   cidr_block                 = "******"
   map_public_ip_on_launch    = true   // パブリック IPv4 アドレスの自動割り当てを有効化
   vpc_id                     = "${aws_vpc.terraform-sample-vpc.id}"
   tags = {
      Name                    = "my-subnet-1a"
   }
}

resource "aws_subnet" "terraform-sample-subnet1c" {
   availability_zone = "ap-northeast-1c"
   cidr_block = "******"
   map_public_ip_on_launch    = true  // パブリック IPv4 アドレスの自動割り当てを有効化
   vpc_id = "${aws_vpc.terraform-sample-vpc.id}"
   tags = {
      Name = "my-subnet-1c"
   }
}

resource "aws_subnet" "terraform-sample-subnet1d" {
   availability_zone = "ap-northeast-1d"
   cidr_block = "******"
   map_public_ip_on_launch    = true  // パブリック IPv4 アドレスの自動割り当てを有効化
   vpc_id = "${aws_vpc.terraform-sample-vpc.id}"
   tags = {
      Name = "my-subnet-1d"
   }
}
```

- ```terraform plan```で名前のみ差分に出ることを確認

```terminal: Windows Terminal
> terraform plan
aws_vpc.terraform-sample-vpc: Refreshing state... [id=[VPCリソースID]]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=[サブネットリソースID]]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_subnet.terraform-sample-subnet1a will be updated in-place
  ~ resource "aws_subnet" "terraform-sample-subnet1a" {
        id                                             = "[サブネットリソースID]"
      ~ tags                                           = {
          + "Name" = "my-subnet-1a"
        }
      ~ tags_all                                       = {
          + "Name" = "my-subnet-1a"
        }
        # (19 unchanged attributes hidden)
    }

  # aws_subnet.terraform-sample-subnet1c will be updated in-place
  ~ resource "aws_subnet" "terraform-sample-subnet1c" {
        id                                             = "[サブネットリソースID]"
      ~ tags                                           = {
          + "Name" = "my-subnet-1c"
        }
      ~ tags_all                                       = {
          + "Name" = "my-subnet-1c"
        }
        # (19 unchanged attributes hidden)
    }

  # aws_subnet.terraform-sample-subnet1d will be updated in-place
  ~ resource "aws_subnet" "terraform-sample-subnet1d" {
        id                                             = "[サブネットリソースID]"
      ~ tags                                           = {
          + "Name" = "my-subnet-1d"
        }
      ~ tags_all                                       = {
          + "Name" = "my-subnet-1d"
        }
        # (19 unchanged attributes hidden)
    }

Plan: 0 to add, 3 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply"
now.
```


- ```terraform apply```を実行
```terminal: Windows Terminal
> terraform apply
aws_vpc.terraform-sample-vpc: Refreshing state... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=[サブネットリソースID]]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_subnet.terraform-sample-subnet1a will be updated in-place
  ~ resource "aws_subnet" "terraform-sample-subnet1a" {
        id                                             = "[サブネットリソースID]"
      ~ tags                                           = {
          + "Name" = "my-subnet-1a"
        }
      ~ tags_all                                       = {
          + "Name" = "my-subnet-1a"
        }
        # (19 unchanged attributes hidden)
    }

  # aws_subnet.terraform-sample-subnet1c will be updated in-place
  ~ resource "aws_subnet" "terraform-sample-subnet1c" {
        id                                             = "[サブネットリソースID]"
      ~ tags                                           = {
          + "Name" = "my-subnet-1c"
        }
      ~ tags_all                                       = {
          + "Name" = "my-subnet-1c"
        }
        # (19 unchanged attributes hidden)
    }

  # aws_subnet.terraform-sample-subnet1d will be updated in-place
  ~ resource "aws_subnet" "terraform-sample-subnet1d" {
        id                                             = "[サブネットリソースID]"
      ~ tags                                           = {
          + "Name" = "my-subnet-1d"
        }
      ~ tags_all                                       = {
          + "Name" = "my-subnet-1d"
        }
        # (19 unchanged attributes hidden)
    }

Plan: 0 to add, 3 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_subnet.terraform-sample-subnet1a: Modifying... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1c: Modifying... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1d: Modifying... [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1c: Modifications complete after 0s [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1a: Modifications complete after 0s [id=[サブネットリソースID]]
aws_subnet.terraform-sample-subnet1d: Modifications complete after 0s [id=[サブネットリソースID]]

Apply complete! Resources: 0 added, 3 changed, 0 destroyed.
```

## ルートテーブル
- リソースの数だけ定義を追
```hcl:network.tf
resource "aws_route_table" "imported" {
  vpc_id = aws_vpc.terraform-sample-vpc.id
}
```

- terraform importを実行
```terminal: Windows Terminal
> terraform import aws_route_table.imported rtb-xxxxxxxxxxxxxxxx
aws_route_table.imported: Importing from ID "rtb-xxxxxxxxxxxxxxxx"...
aws_route_table.imported: Import prepared!
  Prepared aws_route_table for import
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxxx]

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.
```
- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)
```terminal: Windows Terminal
> terraform state show aws_route_table.imported
# aws_route_table.imported:
resource "aws_route_table" "imported" {
    arn              = "xxxxxxxxxxxxxx"
    id               = "rtb-xxxxxxxxxxxxxx"
    owner_id         = "xxxxxxxxxxxxx"
    propagating_vgws = []
    route            = [
        {
            carrier_gateway_id         = null
            cidr_block                 = "0.0.0.0/0"
            core_network_arn           = null
            destination_prefix_list_id = null
            egress_only_gateway_id     = null
            gateway_id                 = "igw-xxxxxxxxxxxxxx"
            ipv6_cidr_block            = null
            local_gateway_id           = null
            nat_gateway_id             = null
            network_interface_id       = null
            transit_gateway_id         = null
            vpc_endpoint_id            = null
            vpc_peering_connection_id  = null
        },
    ]
    tags             = {}
    tags_all         = {}
    vpc_id           = "vpc-xxxxxxxxxxxxxx"
}
```

- 定義しているファイル内に設定情報を肉付け
```
resource "aws_route_table" "imported" {
  vpc_id = aws_vpc.terraform-sample-vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "igw-xxxxxxxxxxxxxxxx"
  }
   tags = {
    Name = "imported-route-table"
  }
}
```
- terraform planで名前のみ差分に出ることを確認
```terminal: Windows Terminal
> terraform plan
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxx]
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_route_table.imported will be updated in-place
  ~ resource "aws_route_table" "imported" {
        id               = "rtb-xxxxxxxxxxxxxxxxx"
      ~ tags             = {
          + "Name" = "imported-route-table"
        }
      ~ tags_all         = {
          + "Name" = "imported-route-table"
        }
        # (5 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
```
- terraform applyを実行
```
> terraform apply
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxx]
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_route_table.imported will be updated in-place
  ~ resource "aws_route_table" "imported" {
        id               = "rtb-xxxxxxxxxxxxxxx"
      ~ tags             = {
          + "Name" = "imported-route-table"
        }
      ~ tags_all         = {
          + "Name" = "imported-route-table"
        }
        # (5 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_route_table.imported: Modifying... [id=rtb-xxxxxxxxxxxxxxx]
aws_route_table.imported: Modifications complete after 0s [id=rtb-xxxxxxxxxxxxxxx]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```
##　ネットワークACL
- リソースの数だけ定義を追加
```hcl: network.tf
resource "aws_default_network_acl" "imported" {
  default_network_acl_id = "acl-0d3783bb08b89dd6d"
  # ルールやタグは import 後に追記
}
```
- terraform importを実行
```terminal: Windows Terminal
> terraform import aws_default_network_acl.imported acl-xxxxxxxxxxxxxxx
aws_default_network_acl.imported: Importing from ID "acl-xxxxxxxxxxxxxxx"...
aws_default_network_acl.imported: Import prepared!
  Prepared aws_default_network_acl for import
aws_default_network_acl.imported: Refreshing state... [id=acl-xxxxxxxxxxxxxxx]

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.
```
- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)
```terminal: Windows Terminal
> terraform state show aws_route_table.imported
# aws_route_table.imported:
resource "aws_route_table" "imported" {
    arn              = "xxxxxxxxxxxxxx"
    id               = "rtb-xxxxxxxxxxxxxx"
    owner_id         = "xxxxxxxxxxxxxx"
    propagating_vgws = []
    route            = [
        {
            carrier_gateway_id         = null
            cidr_block                 = "0.0.0.0/0"
            core_network_arn           = null
            destination_prefix_list_id = null
            egress_only_gateway_id     = null
            gateway_id                 = "igw-xxxxxxxxxxxxxx"
            ipv6_cidr_block            = null
            local_gateway_id           = null
            nat_gateway_id             = null
            network_interface_id       = null
            transit_gateway_id         = null
            vpc_endpoint_id            = null
            vpc_peering_connection_id  = null
        },
    ]
    tags             = {
        "Name" = "imported-route-table"
    }
    tags_all         = {
        "Name" = "imported-route-table"
    }
    vpc_id           = "vpc-xxxxxxxxxxxxxx"
}
```
- 定義しているファイル内に設定情報を肉付け
```hcl:network.tf
resource "aws_default_network_acl" "imported" {
  default_network_acl_id = "acl-xxxxxxxxxxxxxxxxx"

  ingress {
    protocol   = "-1"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  egress {
    protocol   = "-1"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  subnet_ids = [
    aws_subnet.terraform-sample-subnet1a.id,
    aws_subnet.terraform-sample-subnet1c.id,
    aws_subnet.terraform-sample-subnet1d.id
  ]

  tags = {
    Name        = "imported-default-acl"
  }
}
```
- terraform planで名前のみ差分に出ることを確認
```terminal: Windows Terminal
> terraform plan
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxx]
aws_default_network_acl.imported: Refreshing state... [id=acl-xxxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_default_network_acl.imported will be updated in-place
  ~ resource "aws_default_network_acl" "imported" {
        id                     = "acl-xxxxxxxxxxxxxxxxxx"
      ~ tags                   = {
          + "Name" = "imported-default-acl"
        }
      ~ tags_all               = {
          + "Name" = "imported-default-acl"
        }
        # (5 unchanged attributes hidden)

        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
```
- terraform applyを実行
```terminal: Windows Terminal
> terraform apply
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxxxx]
aws_default_network_acl.imported: Refreshing state... [id=acl-xxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_default_network_acl.imported will be updated in-place
  ~ resource "aws_default_network_acl" "imported" {
        id                     = "acl-xxxxxxxxxxxxxxxxx"
      ~ tags                   = {
          + "Name" = "imported-default-acl"
        }
      ~ tags_all               = {
          + "Name" = "imported-default-acl"
        }
        # (5 unchanged attributes hidden)

        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_default_network_acl.imported: Modifying... [id=acl-xxxxxxxxxxxxxxxxx]
aws_default_network_acl.imported: Modifications complete after 0s [id=acl-xxxxxxxxxxxxxxxxx]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```

## インターネットゲートウェイ
- リソースの数だけ定義を追加
```hcl:network.tf
resource "aws_internet_gateway" "imported" {
  vpc_id = aws_vpc.terraform-sample-vpc.id

  tags = {
    Name = "imported-igw"
  }
}
```
- terraform importを実行
```
> cd aws && terraform import aws_internet_gateway.imported igw-xxxxxxxxxxxxx
aws_internet_gateway.imported: Importing from ID "igw-xxxxxxxxxxxxx"...
aws_internet_gateway.imported: Import prepared!
  Prepared aws_internet_gateway for import
aws_internet_gateway.imported: Refreshing state... [id=igw-xxxxxxxxxxxxx]

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.
```
- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)
```terminal: Windows Terminal
> terraform state show aws_default_network_acl.imported
# aws_default_network_acl.imported:
resource "aws_default_network_acl" "imported" {
    arn                    = "xxxxxxxxxxxx"
    default_network_acl_id = "acl-xxxxxxxxxxxx"
    id                     = "acl-xxxxxxxxxxxx"
    owner_id               = "xxxxxxxxxxxx"
    subnet_ids             = [
        "subnet-xxxxxxxxxxxx",
        "subnet-xxxxxxxxxxxx",
        "subnet-xxxxxxxxxxxx",
    ]
    tags                   = {
        "Name" = "imported-default-acl"
    }
    tags_all               = {
        "Name" = "imported-default-acl"
    }
    vpc_id                 = "vpc-xxxxxxxxxxxx"

    egress {
        action          = "allow"
        cidr_block      = "0.0.0.0/0"
        from_port       = 0
        icmp_code       = 0
        icmp_type       = 0
        ipv6_cidr_block = null
        protocol        = "-1"
        rule_no         = 100
        to_port         = 0
    }

    ingress {
        action          = "allow"
        cidr_block      = "0.0.0.0/0"
        from_port       = 0
        icmp_code       = 0
        icmp_type       = 0
        ipv6_cidr_block = null
        protocol        = "-1"
        rule_no         = 100
        to_port         = 0
    }
}
```
- 定義しているファイル内に設定情報を肉付け
```hcl:network.tf
resource "aws_default_network_acl" "imported" {
  default_network_acl_id = "acl-xxxxxxxxxxxxxx"

  subnet_ids = [
    aws_subnet.terraform-sample-subnet1a.id,
    aws_subnet.terraform-sample-subnet1c.id,
    aws_subnet.terraform-sample-subnet1d.id
  ]

  egress {
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    protocol   = "-1"
    rule_no    = 100
    to_port    = 0
    # ICMP系は不要なら省略可
  }

  ingress {
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    protocol   = "-1"
    rule_no    = 100
    to_port    = 0
    # ICMP系は不要なら省略可
  }

  tags = {
    Name = "imported-default-acl"
  }
}

```

- terraform planで名前のみ差分に出ることを確認
```terminal: Windows Terminal
> terraform plan
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxxxx]
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxxxxx]
aws_internet_gateway.imported: Refreshing state... [id=igw-xxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxxxxxx]
aws_default_network_acl.imported: Refreshing state... [id=acl-xxxxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_internet_gateway.imported will be updated in-place
  ~ resource "aws_internet_gateway" "imported" {
        id       = "igw-xxxxxxxxxxxxxxxxxxx"
      ~ tags     = {
          + "Name" = "imported-igw"
        }
      ~ tags_all = {
          + "Name" = "imported-igw"
        }
        # (3 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

```
- terraform applyを実行
```terminal: Windows Terminal
> terraform apply
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxx]
aws_internet_gateway.imported: Refreshing state... [id=igw-xxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxx]
aws_default_network_acl.imported: Refreshing state... [id=acl-xxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_internet_gateway.imported will be updated in-place
  ~ resource "aws_internet_gateway" "imported" {
        id       = "igw-xxxxxxxxxxxx"
      ~ tags     = {
          + "Name" = "imported-igw"
        }
      ~ tags_all = {
          + "Name" = "imported-igw"
        }
        # (3 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_internet_gateway.imported: Modifying... [id=igw-xxxxxxxxxxxx]
aws_internet_gateway.imported: Modifications complete after 0s [id=igw-xxxxxxxxxxxx]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```

## セキュリティグループ
- リソースの数だけ定義を追加(少し面倒になってきて、Clineに書いてもらっている)
```hcl
resource "aws_security_group" "launch_wizard_1" {
  name        = "launch-wizard-1"
  description = "Imported security group launch-wizard-1"
  vpc_id      = "REPLACE_ME_VPC_ID"
}

```
- terraform importを実行
```bash
 terraform import aws_security_group.launch_wizard_1 [セキュリティグループID]
aws_security_group.launch_wizard_1: Importing from ID "セキュリティグループID"...
aws_security_group.launch_wizard_1: Import prepared!
  Prepared aws_security_group for import
aws_security_group.launch_wizard_1: 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.
```
- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)

```terminal: Windows Terminal
> terraform state show aws_security_group.launch_wizard_1

# aws_security_group.launch_wizard_1:
resource "aws_security_group" "launch_wizard_1" {
    arn         = "xxxxxxxx"
    description = "launch-wizard-1 created 2025-03-23T11:37:05.000Z"
    egress      = [
        {
            cidr_blocks      = [
                "0.0.0.0/0",
            ]
            description      = null
            from_port        = 0
            ipv6_cidr_blocks = []
            prefix_list_ids  = []
            protocol         = "-1"
            security_groups  = []
            self             = false
            to_port          = 0
        },
    ]
    ingress     = [
        {
            cidr_blocks      = [
                "126.15.24.6/32",
            ]
            description      = null
            from_port        = 22
            ipv6_cidr_blocks = []
            prefix_list_ids  = []
            protocol         = "tcp"
            security_groups  = []
            self             = false
            to_port          = 22
        },
    ]
    name        = "launch-wizard-1"
    name_prefix = null
    tags        = {}
    tags_all    = {}

}
```
- 定義しているファイル内に設定情報を肉付け
```hcl
resource "aws_security_group" "launch_wizard_1" {
  name        = "launch-wizard-1"
  description = "launch-wizard-1 created 2025-03-23T11:37:05.000Z"
  vpc_id      = "vpc-xxxxxxxxxxxxxxx"

  ingress {
    description      = null
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["126.15.24.6/32"]
    ipv6_cidr_blocks = []
    prefix_list_ids  = []
    security_groups  = []
    self             = false
  }

  egress {
    description      = null
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = []
    prefix_list_ids  = []
    security_groups  = []
    self             = false
  }
  tags = {
    Name = "launch-wizard-1"
  }
}
```
- terraform planで名前のみ差分に出ることを確認
```terminal:Windows Terminal
> terraform plan
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.launch_wizard_1 will be updated in-place
  ~ resource "aws_security_group" "launch_wizard_1" {
        id                     = "sg-xxxxxxxxxxxxxxx"
        name                   = "launch-wizard-1"
      + revoke_rules_on_delete = false
      ~ tags                   = {
          + "Name" = "launch-wizard-1"
        }
      ~ tags_all               = {
          + "Name" = "launch-wizard-1"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
```

- terraform applyを実行
```terminal:Windows Terminal
> terraform apply
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.launch_wizard_1 will be updated in-place
  ~ resource "aws_security_group" "launch_wizard_1" {
        id                     = "sg-xxxxxxxxxxxxxxxxxxxx"
        name                   = "launch-wizard-1"
      + revoke_rules_on_delete = false
      ~ tags                   = {
          + "Name" = "launch-wizard-1"
        }
      ~ tags_all               = {
          + "Name" = "launch-wizard-1"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.launch_wizard_1: Modifying... [id=sg-xxxxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Modifications complete after 0s [id=sg-xxxxxxxxxxxxxxxxxxxx]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```

## IAM Role
- リソースの数だけ定義を追加
```hcl
resource "aws_iam_role" "accessTest_role_xxxxxxx" {
    name = "accessTest-role-xxxxxxx"
    assume_role_policy = jsonencode({
        Version = "2012-10-17"
        Statement = [
        {
            Action = "sts:AssumeRole"
            Effect = "Allow"
            Principal = {
            Service = "ec2.amazonaws.com"
            }
        }
        ]
    })
    
    tags = {
        Name = "accessTest-role-xxxxxxx"
    }
}
```
- terraform importを実行
```terminal:Windows Terminal
> terraform import aws_iam_role.accessTest_role_0mj0a3vo [ロール名]
aws_iam_role.accessTest_role_0mj0a3vo: Importing from ID "ロール名"...
aws_iam_role.accessTest_role_0mj0a3vo: Import prepared!
  Prepared aws_iam_role for import
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [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.
```
- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)
```terminal:Windows Terminal
terraform state show aws_iam_role.accessTest_role_0mj0a3vo
# aws_iam_role.accessTest_role_0mj0a3vo:
resource "aws_iam_role" "accessTest_role_0mj0a3vo" {
    arn                   = "xxxxxxxxxxxxxxxxxxx"
    assume_role_policy    = jsonencode(
        {
            Statement = [
                {
                    Action    = "sts:AssumeRole"
                    Effect    = "Allow"
                    Principal = {
                        Service = "lambda.amazonaws.com"
                    }
                },
            ]
            Version   = "2012-10-17"
        }
    )
    create_date           = "2025-03-23T11:18:21Z"
    description           = null
    force_detach_policies = false
    id                    = "accessTest-role-0mj0a3vo"
    managed_policy_arns   = [
        "xxxxxxxxxxxxxxxxxxx",
    ]
    max_session_duration  = 3600
    name                  = "accessTest-role-0mj0a3vo"
    name_prefix           = null
    path                  = "/service-role/"
    permissions_boundary  = null
    tags                  = {}
    tags_all              = {}
    unique_id             = "xxxxxxxxxxxxxxxxxxx"
}
```
- 定義しているファイル内に設定情報を肉付け
```hcl
resource "aws_iam_role" "accessTest_role_0mj0a3vo" {
  name               = "accessTest-role-0mj0a3vo"
  path               = "/service-role/"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
  max_session_duration = 3600
  force_detach_policies = false
  # description, permissions_boundary, tags などはstateがnull/空なので省略OK
  tags = {
    Name = "accessTest-role-0mj0a3vo"
  }
}
```
- terraform planで名前のみ差分に出ることを確認
```terminal: Windows Terminal
> terraform plan
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_iam_role.accessTest_role_0mj0a3vo will be updated in-place
  ~ resource "aws_iam_role" "accessTest_role_0mj0a3vo" {
        id                    = "accessTest-role-0mj0a3vo"
        id                    = "accessTest-role-0mj0a3vo"
        name                  = "accessTest-role-0mj0a3vo"
      ~ tags                  = {
          + "Name" = "accessTest-role-0mj0a3vo"
        }
      ~ tags_all              = {
          + "Name" = "accessTest-role-0mj0a3vo"
        }
        # (11 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
```
- terraform applyを実行
```terminal: Windows Terminal
> terraform apply
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_iam_role.accessTest_role_0mj0a3vo will be updated in-place
  ~ resource "aws_iam_role" "accessTest_role_0mj0a3vo" {
        id                    = "accessTest-role-0mj0a3vo"
        name                  = "accessTest-role-0mj0a3vo"
      ~ tags                  = {
          + "Name" = "accessTest-role-0mj0a3vo"
        }
      ~ tags_all              = {
          + "Name" = "accessTest-role-0mj0a3vo"
        }
        # (11 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_iam_role.accessTest_role_0mj0a3vo: Modifying... [id=xxxxxxxxxxxxxxxxxxxx]
aws_iam_role.accessTest_role_0mj0a3vo: Modifications complete after 1s [id=xxxxxxxxxxxxxxxxxxxx]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```
## EC2
- リソースの数だけ定義を追加
```hcl:ec2.tf
resource "aws_instance" "imported_instance" {
  # インポート時は空でOK
}
```
- terraform importを実行
```terminal: Windows Terminal
> terraform import aws_instance.imported_instance [EC2インスタンスID]
>> 
aws_instance.imported_instance: Importing from ID "EC2インスタンスID"...
aws_instance.imported_instance: Import prepared!
  Prepared aws_instance for import
aws_instance.imported_instance: Refreshing state... [id=EC2インスタンス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.
```
- 状態ファイルを確認(マスクするのが面倒なので細かいところは省略)
```terminal: Windows Terminal
> terraform state show aws_instance.imported_instance
>>
# aws_instance.imported_instance:
resource "aws_instance" "imported_instance" {
    ami                                  = "ami-xxxxxxxxxxxx"
    arn                                  = "xxxxxxxxxxxx"
    associate_public_ip_address          = false
    availability_zone                    = "ap-northeast-1a"
    cpu_core_count                       = 1
    cpu_threads_per_core                 = 1
    disable_api_stop                     = false
    disable_api_termination              = false
    ebs_optimized                        = false
    get_password_data                    = false
    hibernation                          = false
    host_id                              = null
    iam_instance_profile                 = null
    id                                   = "i-xxxxxxxxxxxx"
    instance_initiated_shutdown_behavior = "stop"
    instance_lifecycle                   = null
    instance_state                       = "stopped"
    instance_type                        = "t2.micro"
    ipv6_address_count                   = 0
    ipv6_addresses                       = []
    key_name                             = "ec2-key"
    monitoring                           = false
    outpost_arn                          = null
    password_data                        = null
    placement_group                      = null
    placement_partition_number           = 0
    primary_network_interface_id         = "eni-xxxxxxxxxxxx"
    private_dns                          = "xxxxxxxxxxxx"
    private_ip                           = "172.31.33.76"
    public_dns                           = null
    public_ip                            = null
    secondary_private_ips                = []
    security_groups                      = [
        "launch-wizard-1",
    ]
    source_dest_check                    = true
    spot_instance_request_id             = null
    subnet_id                            = "subnet-xxxxxxxxxxxx"
    tags                                 = {
        "Name" = "test"
    }
    tags_all                             = {
        "Name" = "test"
    }
    tenancy                              = "default"
    vpc_security_group_ids               = [
        "sg-0efe16e696a3918be",
    ]

    capacity_reservation_specification {
        capacity_reservation_preference = "open"
    }

    cpu_options {
        amd_sev_snp      = null
        core_count       = 1
        threads_per_core = 1
    }

    credit_specification {
        cpu_credits = "standard"
    }

    enclave_options {
        enabled = false
    }

    maintenance_options {
        auto_recovery = "default"
    }

    metadata_options {
        http_endpoint               = "enabled"
        http_protocol_ipv6          = "disabled"
        http_put_response_hop_limit = 2
        http_tokens                 = "required"
        instance_metadata_tags      = "disabled"
    }

    private_dns_name_options {
        enable_resource_name_dns_a_record    = true
        enable_resource_name_dns_aaaa_record = false
        hostname_type                        = "ip-name"
    }

    root_block_device {
        delete_on_termination = true
        device_name           = "/dev/xvda"
        encrypted             = false
        iops                  = 3000
        kms_key_id            = null
        tags                  = {}
        tags_all              = {}
        throughput            = 125
        volume_id             = "vol-xxxxxxxxxxxx"
        volume_size           = 8
        volume_type           = "gp3"
    }
}
```
- 定義しているファイル内に設定情報を肉付け
```hcl: ec2.tf
resource "aws_instance" "imported_instance" {
  ami                         = "ami-xxxxxxxxxxxxxxxxxxx"
  instance_type               = "t2.micro"
  subnet_id                   = "subnet-xxxxxxxxxxxxxxxxxxx"
  key_name                    = "ec2-key"
  vpc_security_group_ids      = ["sg-xxxxxxxxxxxxxxxxxxx"]
  associate_public_ip_address = false
  private_ip                  = "172.31.33.76"
  tags = {
    Name = "test-instance"
  }

  root_block_device {
    volume_type           = "gp3"
    volume_size           = 8
    iops                  = 3000
    throughput            = 125
    delete_on_termination = true
    encrypted             = false
  }

  credit_specification {
    cpu_credits = "standard"
  }

  metadata_options {
    http_endpoint               = "enabled"
    http_protocol_ipv6          = "disabled"
    http_put_response_hop_limit = 2
    http_tokens                 = "required"
    instance_metadata_tags      = "disabled"
  }

  capacity_reservation_specification {
    capacity_reservation_preference = "open"
  }

  cpu_options {
    core_count       = 1
    threads_per_core = 1
  }

  enclave_options {
    enabled = false
  }

  maintenance_options {
    auto_recovery = "default"
  }

  private_dns_name_options {
    enable_resource_name_dns_a_record    = true
    enable_resource_name_dns_aaaa_record = false
    hostname_type                        = "ip-name"
  }
}
```
- terraform planで名前のみ差分に出ることを確認
```terminal: Windows Terminal
> terraform plan
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_instance.imported_instance will be updated in-place
  ~ resource "aws_instance" "imported_instance" {
        id                                   = "i-xxxxxxxxxxxxxxxx"
      ~ tags                                 = {
          ~ "Name" = "test" -> "test-instance"
        }
      ~ tags_all                             = {
          ~ "Name" = "test" -> "test-instance"
        }
      + user_data_replace_on_change          = false
        # (37 unchanged attributes hidden)

        # (8 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 
```
- terraform applyを実行
```terminal: Windows Terminal
> terraform apply
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxxxxxxxx]
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxxxxxx]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_instance.imported_instance will be updated in-place
  ~ resource "aws_instance" "imported_instance" {
        id                                   = "i-xxxxxxxxxxxxxxxxxxxxxxx"
      ~ tags                                 = {
          ~ "Name" = "test" -> "test-instance"
        }
      ~ tags_all                             = {
          ~ "Name" = "test" -> "test-instance"
        }
      + user_data_replace_on_change          = false
        # (37 unchanged attributes hidden)

        # (8 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.imported_instance: Modifying... [id=i-xxxxxxxxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Modifications complete after 1s [id=i-xxxxxxxxxxxxxxxxxxxxxxx]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```

# ハードコーディングの削除
- ここまでで、AWS環境のリソースのHCL化が完了。ただ、このままのソースコードで同じ環境を作ることはできない
- なぜなら、vpc_idやらsubnet_idやらがハードコーディングされており、削除、もしくは新規で別環境で立ち上げる時に整合性が取れないため
- なので、リソース定義上からハードコーディングをなくし、どの環境でも構築可能にする。修正後のソースが以下
```hcl: network.tf
resource "aws_vpc" "terraform-sample-vpc" {
    cidr_block                           = "172.31.0.0/16"  // IPv4 CIDR
    enable_dns_hostnames                 = true      // DNS ホスト名を有効化
    enable_dns_support                   = true      // DNS 解決を有効化
  tags = {
    Name = "my_vpc"
  }
}
resource "aws_internet_gateway" "imported" {
  vpc_id = aws_vpc.terraform-sample-vpc.id

  tags = {
    Name = "imported-igw"
  }
}

resource "aws_subnet" "terraform-sample-subnet1a" {
   availability_zone          = "ap-northeast-1a"
   cidr_block                 = "172.31.32.0/20"	
   map_public_ip_on_launch    = true   
   vpc_id                     = "${aws_vpc.terraform-sample-vpc.id}"
   tags = {
      Name                    = "my-subnet-1a"
   }
}

resource "aws_subnet" "terraform-sample-subnet1c" {
   availability_zone = "ap-northeast-1c"
   cidr_block = "172.31.0.0/20"
   map_public_ip_on_launch    = true
   vpc_id = "${aws_vpc.terraform-sample-vpc.id}"
   tags = {
      Name = "my-subnet-1c"
   }
}

resource "aws_subnet" "terraform-sample-subnet1d" {
   availability_zone = "ap-northeast-1d"
   cidr_block = "172.31.16.0/20"
   map_public_ip_on_launch    = true
   vpc_id = "${aws_vpc.terraform-sample-vpc.id}"
   tags = {
      Name = "my-subnet-1d"
   }
}

resource "aws_route_table" "imported" {
  vpc_id = aws_vpc.terraform-sample-vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.imported.id
  }


  tags = {
    Name        = "imported-route-table"
  }
}

resource "aws_default_network_acl" "imported" {
  default_network_acl_id = "acl-xxxxxxxxxxxx"//ここだけ任意指定

  subnet_ids = [
    aws_subnet.terraform-sample-subnet1a.id,
    aws_subnet.terraform-sample-subnet1c.id,
    aws_subnet.terraform-sample-subnet1d.id
  ]

  egress {
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    protocol   = "-1"
    rule_no    = 100
    to_port    = 0
    # ICMP系は不要なら省略可
  }

  ingress {
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    protocol   = "-1"
    rule_no    = 100
    to_port    = 0
    # ICMP系は不要なら省略可
  }

  tags = {
    Name = "imported-default-acl"
  }
}

```
```hcl:ec2.tf
resource "aws_instance" "imported_instance" {
  ami                         = "ami-0599b6e53ca798bb2"//AWS側でEnum管理されているID(Amazon Machine Image)なので問題なし
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.terraform-sample-subnet1a.id
  key_name                    = "ec2-key"
  vpc_security_group_ids      = [aws_security_group.launch_wizard_1.id]
  associate_public_ip_address = false
  private_ip                  = "172.31.33.76"
  tags = {
    Name = "test-instance"
  }

  root_block_device {
    volume_type           = "gp3"
    volume_size           = 8
    iops                  = 3000
    throughput            = 125
    delete_on_termination = true
    encrypted             = false
  }

  credit_specification {
    cpu_credits = "standard"
  }

  metadata_options {
    http_endpoint               = "enabled"
    http_protocol_ipv6          = "disabled"
    http_put_response_hop_limit = 2
    http_tokens                 = "required"
    instance_metadata_tags      = "disabled"
  }

  capacity_reservation_specification {
    capacity_reservation_preference = "open"
  }

  cpu_options {
    core_count       = 1
    threads_per_core = 1
  }

  enclave_options {
    enabled = false
  }

  maintenance_options {
    auto_recovery = "default"
  }

  private_dns_name_options {
    enable_resource_name_dns_a_record    = true
    enable_resource_name_dns_aaaa_record = false
    hostname_type                        = "ip-name"
  }
}

```
```hcl:security-group.tf
resource "aws_security_group" "launch_wizard_1" {
  name        = "launch-wizard-1"
  description = "launch-wizard-1 created 2025-03-23T11:37:05.000Z"
  vpc_id      = aws_vpc.terraform-sample-vpc.id

  ingress {
    description      = null
    from_port        = 22
    to_port          = 22
    protocol         = "tcp"
    cidr_blocks      = ["126.15.24.6/32"]
    ipv6_cidr_blocks = []
    prefix_list_ids  = []
    security_groups  = []
    self             = false
  }

  egress {
    description      = null
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = []
    prefix_list_ids  = []
    security_groups  = []
    self             = false
  }
  tags = {
    Name = "launch-wizard-1"
  }
}

```
# 再構築と削除
## 別環境で同じリソースを構築
:::note alert
元環境の定義情報が入っているterraform.tfstateが上書きされるため、
必要に応じてバックアップしてください
:::
- 構築完了したので、作ったり壊したりしてためしてみる
- 事前準備として、Organizationsで新規アカウントを切って、まっさらな環境を用意する
![スクリーンショット 2025-06-09 235922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984667/205f11b6-80fd-4f6b-804c-25fb47aae4bf.png)
- 用意したまっさらな環境に対して、planを実行
```hcl
> terraform plan
aws_iam_role.accessTest_role_0mj0a3vo: Refreshing state... [id=xxxxxxxxxxxxxxxxxxx]
aws_vpc.terraform-sample-vpc: Refreshing state... [id=vpc-xxxxxxxxxxxxxxxxxxx]
aws_internet_gateway.imported: Refreshing state... [id=igw-xxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1a: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1c: Refreshing state... [id=subnet-xxxxxxxxxxxxxxxxxxx]
aws_security_group.launch_wizard_1: Refreshing state... [id=sg-xxxxxxxxxxxxxxxxxxx]
aws_route_table.imported: Refreshing state... [id=rtb-xxxxxxxxxxxxxxxxxxx]
aws_instance.imported_instance: Refreshing state... [id=i-xxxxxxxxxxxxxxxxxxx]
aws_default_network_acl.imported: Refreshing state... [id=acl-xxxxxxxxxxxxxxxxxxx]

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply" which may have affected this plan:

  # aws_internet_gateway.imported has been deleted
  - resource "aws_internet_gateway" "imported" {
      - id       = "igw-xxxxxxxxxxxxxxxxxxx" -> null
        tags     = {
            "Name" = "imported-igw"
        }
        # (4 unchanged attributes hidden)
    }
-------------------
// 流石に長すぎるので省略
-------------------

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may  
include actions to undo or respond to these changes.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:      
  + create

Terraform will perform the following actions:

  # aws_default_network_acl.imported will be created
  + resource "aws_default_network_acl" "imported" {
      + arn                    = (known after apply)
      + default_network_acl_id = "acl-0d3783bb08b89dd6d"
      + id                     = (known after apply)
      + owner_id               = (known after apply)
      + subnet_ids             = (known after apply)
      + tags                   = {
          + "Name" = "imported-default-acl"
        }
      + tags_all               = {
          + "Name" = "imported-default-acl"
        }
      + vpc_id                 = (known after apply)

      + egress {
          + action          = "allow"
          + cidr_block      = "0.0.0.0/0"
          + from_port       = 0
          + protocol        = "-1"
          + rule_no         = 100
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }

      + ingress {
          + action          = "allow"
          + cidr_block      = "0.0.0.0/0"
          + from_port       = 0
          + protocol        = "-1"
          + rule_no         = 100
          + to_port         = 0
            # (1 unchanged attribute hidden)
        }
    }
-------------------
// 流石に長すぎるので省略
-------------------
```

- どうやら、別環境にしたことで、terraform.tfstateで記憶しているリソースとAWS環境の状況に差異が生じてしまったようです。
- 今回に関しては、新しい環境に消えて困るリソースはないので、でこのままデプロイしてしまいます
- なんかエラー出た。。。
```
│ Error: creating EC2 Instance: operation error EC2: RunInstances, https response error StatusCode: 400, RequestID: xxxxxxxxxx, api error UnsupportedOperation: The t2.micro instance type does not support specifying CpuOptions.
│
│   with aws_instance.imported_instance,
│   on ec2.tf line 1, in resource "aws_instance" "imported_instance":
│    1: resource "aws_instance" "imported_instance" {
│
╵
╷
│ Error: reading EC2 Network ACL (acl-xxxxxxxxxx): couldn't find resource
│
│   with aws_default_network_acl.imported,
│   on network.tf line 66, in resource "aws_default_network_acl" "imported":
│   66: resource "aws_default_network_acl" "imported" {
│
```
- 1点目
    - EC2インスタンスのt2.microにたいして、cpuコア数やスレッド数の指定はできないそう
    - terraformでの管理下では問題が出なかったため、インスタンスの新規作成時か、変更時のみ発生するエラーと考えられる
    - 以下を削除
```hcl:ec2.tf
  cpu_options {
    core_count       = 1
    threads_per_core = 1
  }

```
- 2点目
    - networkaclが見つからない旨のエラー
    - ハードコーディングの削除忘れ
    - ただ、default_network_aclをidなしで定義することができなかったため、通常のnetworkaclに置換
    - ※今回に関してはネットワークACLをインフラ構成上特に使っていないので、定義自体削除でもOK
```hcl:network.tf
resource "aws_network_acl" "custom_acl" {
  vpc_id = aws_vpc.terraform-sample-vpc.id

  ingress {
    protocol   = "-1"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  egress {
    protocol   = "-1"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 0
    to_port    = 0
  }

  subnet_ids = [
    aws_subnet.terraform-sample-subnet1a.id,
    aws_subnet.terraform-sample-subnet1c.id,
    aws_subnet.terraform-sample-subnet1d.id
  ]

  tags = {
    Name = "custom-acl"
  }
}
```
- 再度デプロイ
- 追加でエラー発生。。。
```ternminal:Windows Terminal
╷
│ Error: creating EC2 Instance: operation error EC2: RunInstances, https response error StatusCode: 400, RequestID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx, api error InvalidKeyPair.NotFound: The key pair 'ec2-key' does not exist
│ 
│   with aws_instance.imported_instance,
│   on ec2.tf line 1, in resource "aws_instance" "imported_instance":
│    1: resource "aws_instance" "imported_instance" {
│ 
```
- どうやら、EC2リソースでSSH接続用に作っていたキーペアが必要みたい。。。。忘れてた。。。
- 以下のように修正
```hcl:ec2.tf
resource "aws_instance" "imported_instance" {
  ami                         = "ami-0599b6e53ca798bb2"
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.terraform-sample-subnet1a.id
  key_name                    = aws_key_pair.imported_key.key_name //ココを更新
  vpc_security_group_ids      = [aws_security_group.launch_wizard_1.id]
  associate_public_ip_address = false
  private_ip                  = "172.31.33.76"
  tags = {
    Name = "test-instance"
  }


.........
.........
.........


resource "aws_key_pair" "imported_key" {
  key_name   = "公開鍵名"
  public_key = "[キーペアの公開鍵]"
}

```
- terraform apply
```
> terraform apply

// 長いので割愛

aws_network_acl.custom_acl: Creating...
aws_network_acl.custom_acl: Creation complete after 2s [id=acl-xxxxxxxxxxxxx]
aws_subnet.terraform-sample-subnet1d: Creation complete after 12s [id=subnet-xxxxxxxxxxxxx]
aws_network_acl.custom_acl: Creating...
aws_network_acl.custom_acl: Creation complete after 2s [id=acl-xxxxxxxxxxxxx]
aws_instance.imported_instance: Still creating... [10s elapsed]
aws_instance.imported_instance: Still creating... [20s elapsed]
aws_network_acl.custom_acl: Creation complete after 2s [id=acl-xxxxxxxxxxxxx]
aws_instance.imported_instance: Still creating... [10s elapsed]
aws_instance.imported_instance: Still creating... [20s elapsed]
aws_instance.imported_instance: Still creating... [10s elapsed]
aws_instance.imported_instance: Still creating... [20s elapsed]
aws_instance.imported_instance: Creation complete after 22s [id=i-xxxxxxxxxxxxx]
aws_instance.imported_instance: Creation complete after 22s [id=i-xxxxxxxxxxxxx]


Apply complete! Resources: 11 added, 0 changed, 0 destroyed.

```
- できた！！！！


## 前の環境を削除
- terraform destroyを叩けば一発で消してくれる
- でも、自分は別環境にdeployするときにバックアップを取り忘れたので手作業でやりました。。。

# 終わりに
- 今回は既存のAWS環境をHCL化して、Organizationや他のアカウントに移管できるようにした
- ただ、上記までの作業を見ればわかると思いますが、こんな単純なことに時間をかけ過ぎたな、と思っています...正直Claude Codeに一から構築してもらった方が早かった。。。
- 暇があったら簡単な構成をいくつかClaude Codeに作ってもらって、パブリックリポジトリで公開してみようと思っています