【Terraform/AWS】【入門編2】tfファイル・Terraformコマンドについて

# はじめに
本記事は、AWS初心者でIaCに挑戦してみたい方向けに導入～コード実行までをまとめた内容となります。
前回はTerraformを動かすための前準備手順をご紹介しました。
今回は簡単なコードを例にterraformコマンドの使い方を紹介をします。

なお、<cite><font size="1">[【Terraform/AWS】【入門編】環境準備](https://qiita.com/rittan_girla/items/eefc45c1f9dd0a1761fa/)</font></cite>を閲覧していることを前提としているため、重複する内容は割愛しておりますことをご了承ください。

- 記事構成
<cite><font size="1">[①【Terraform/AWS】【入門編1】環境準備](https://qiita.com/rittan_girla/items/eefc45c1f9dd0a1761fa/)</font></cite>
<cite><font size="1"><B>[②【Terraform/AWS】【入門編2】tfファイル・Terraformコマンドについて](https://qiita.com/rittan_girla/items/7dbd9a9da842ccbf8508/)</B></font></cite><B>　★本記事</B>
<cite><font size="1">[③【Terraform/AWS】【入門編3】フォルダ構成と各ファイルの役割について](https://qiita.com/rittan_girla/items/37458a11c14dacce9ca0/)</font></cite>
<cite><font size="1">[④【Terraform/AWS】【入門編4】モジュールについて](https://qiita.com/rittan_girla/items/81077f1493609eb7a6ca/)</font></cite>

# 1. Terraformコード準備
Terraformを動かすためにはまずコードが必要となります。
サンプルとして、EC2でAmazon Linux 2023を建てるコードを使います。
Terraform用の作業フォルダを作成して、下記のコード（main.tf）を格納します。

```main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "ap-northeast-1"
}

# Create an EC2 Instance
resource "aws_instance" "example" {
  ami           = "ami-0b5c74e235ed808b9"
  instance_type = "t2.micro"

  tags = {
    Name = "TEST1"
  }
}
```

※参考
https://developer.hashicorp.com/terraform/tutorials/aws-get-started/aws-build
https://registry.terraform.io/providers/hashicorp/aws/latest/docs

## 1-1. コード解説
### terraform{}
>The terraform {} block contains Terraform settings, including the required providers Terraform will use to provision your infrastructure

<cite><font size="1">[引用元：https://registry.terraform.io/providers/hashicorp/aws/latest/docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)</font></cite>

Terraformの設定を記載するブロックです。
AWSと連携する場合は、「hashicorp/aws」を指定します。
2024/2時点では、AWSプロバイダーのバージョンは「5.36.0」であるため、versionは5.0以降としています。

https://developer.hashicorp.com/terraform/tutorials/aws-get-started/aws-build

### providers{}
>The provider block configures the specified provider, in this case aws. A provider is a plugin that Terraform uses to create and manage your resources.

<cite><font size="1">[引用元：https://registry.terraform.io/providers/hashicorp/aws/latest/docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)</font></cite>

Terraform がリソースの作成と管理に使用するプラグインを指定します。
今回はAWSのため、プロバイダーは"AWS"と指定しています。
※Azureであれば"azurerm"となる等、使用するプロバイダーによって記載は変わります。

### resource{}
>Use resource blocks to define components of your infrastructure. A resource might be a physical or virtual component such as an EC2 instance, or it can be a logical resource such as a Heroku application.

<cite><font size="1">[引用元：https://registry.terraform.io/providers/hashicorp/aws/latest/docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)</font></cite>

実際に構築するリソースを記載するブロックです。
書式としては、resource "リソースタイプ" "リソース名"{}といった形になります。
今回はEC2インスタンスを構築するため、リソースタイプは"aws_instance"を指定しています。
構築するリソースタイプによって、この部分の指定の仕方は変わります。（VPCであれば"aws_vpc"等）

※リソースタイプは下記にまとめられています。

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


リソース名はリソースタイプの中で構築したリソースを識別するものです。
>Together, the resource type and resource name form a unique ID for the resource.

とあるように、リソースタイプとリソース名を組み合わせることで一意のIDが作成されます。
例えば、EC2インスタンスを二つ構築する場合で考えます。
それぞれリソース名を「example1」と「example2」とします。
この場合、example1のインスタンスIDは「aws_instance.example1.id」、example2のインスタンスIDは「aws_instance.example2.id」といったように呼び出すことができます。
複数のリソースを構築する場合に識別ができるようになります。

# 2. 初期化
コード実行するまでの準備が整ったので、まずはterraform initを行ってフォルダの初期化を行います。
terraform initを実行することで、先ほど指定したプロバイダーがダウンロードされます。

【実行コマンド】
```powershell
terraform init
```
【実行例】
```powershell
PS F:\work\terraform\test1> terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.36.0...
- Installed hashicorp/aws v5.36.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.
```

実行後に作業フォルダに下記が追加されます。
- .terraform\providers\registry.terraform.io\hashicorp\aws\5.36.0\windows_amd64\terraform-provider-aws_v5.36.0_x5.exe
  - プロバイダー
<br /> 

- .terraform.lock.hcl
  - プロバイダーのバージョン管理ファイル
  使用されたプロバイダーのバージョンとハッシュが記録されます 

>Terraform also creates a lock file named .terraform.lock.hcl which specifies the exact provider versions used, so that you can control when you want to update the providers used for your project.

引用元：<cite><font size="1">[https://registry.terraform.io/providers/hashicorp/aws/latest/docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)</font></cite>


```.terraform.lock.hcl
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.

provider "registry.terraform.io/hashicorp/aws" {
  version     = "5.36.0"
  constraints = "~> 5.0"
  hashes = [
    "************************************************",
    "zh:************************************************",
    "zh:************************************************",
・・・（途中省略）・・・
    "zh:************************************************",
    "zh:************************************************",
  ]
}
```
## プロバイダーのバージョンを変更する場合

upgradeフラグを使用することで、プロバイダーのバージョンアップができます。
```powershell
terraform init -upgrade
```

※参考

https://developer.hashicorp.com/terraform/tutorials/cli/init


# 3. フォーマット

下記コマンドを実行することで、.tfファイルをきれいにフォーマットしてくれます。
特にフォーマットの必要がない場合は、何も表示されませんが、フォーマットが行われた場合はフォーマットされたファイル名が表示されます。

【実行コマンド】
```powershell
terraform fmt
```
【実行例】※フォーマットが行われた場合
```powershell
PS F:\work\terraform\test1> terraform fmt
main.tf
```
【実行例】※フォーマットが行われなかった場合
```powershell
PS F:\work\terraform\test1> terraform fmt
```

フォーマットというのは、コードのインデントを揃える等の処理になります。
tagsのインデントをあえてずらした後にフォーマットすると下記のようにきれいに修正されます。

【フォーマット前】
```
# Create an EC2 Instance
resource "aws_instance" "example" {
  ami           = "ami-0b5c74e235ed808b9"
  instance_type = "t2.micro"

      tags = {
    Name = "TEST1"
  }
}
```
【フォーマット後】
```
# Create an EC2 Instance
resource "aws_instance" "example" {
  ami           = "ami-0b5c74e235ed808b9"
  instance_type = "t2.micro"

  tags = {
    Name = "TEST1"
  }
}
```

# 4. 検証
下記記載の通り、コードの検証を行います。
問題がなければ、「Success」と表示されます。
※あくまでも構文の検証のため、実際にコードを実行したら失敗することもあります。

>You can also make sure your configuration is syntactically valid and internally consistent by using the terraform validate command.

<cite><font size="1">[引用元：https://registry.terraform.io/providers/hashicorp/aws/latest/docs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)</font></cite>

【実行コマンド】
```powershell
terraform validate
```

【実行例】※問題ない場合
```powershell
PS F:\work\terraform\test1> terraform validate
Success! The configuration is valid.
```
【実行例】※問題がある場合（問題個所を教えてくれる）
```powershell
PS F:\work\terraform\test1> terraform validate
╷
│ Error: Duplicate resource "aws_instance" configuration
│
│   on main.tf line 25:
│   25: resource "aws_instance" "example" {
│
│ A aws_instance resource named "example" was already declared at main.tf:16,1-34. Resource names must be unique per type in each module.  
```
# 5. 計画
実行するコードで作成される内容が表示されます。
terraform planの内容を確認して、どういった設定で構築されるのかを事前に検証することができます。
今回はコードで指定している「ami」、「instance_type」、「Tags」の内容があっていれば問題ありません。

【実行コマンド】
```powershell
terraform plan
```
【実行例】
```powershell
PS F:\work\terraform\test1> terraform plan    

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_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0b5c74e235ed808b9"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_lifecycle                   = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t2.micro"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = (known after apply)
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + spot_instance_request_id             = (known after apply)
      + subnet_id                            = (known after apply)
      + tags                                 = {
          + "Name" = "TEST1"
        }
      + tags_all                             = {
          + "Name" = "TEST1"
        }
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)
    }

Plan: 1 to add, 0 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 planでプレビューした内容をファイルに保存することができます。

- 構築プランの場合　※""内は任意のファイル名を指定します
```powershell
terraform plan -out "tfplan"
```

- 削除プランの場合　※""内は任意のファイル名を指定します
```powershell
terraform plan -destroy -out "tfplan"
```

通常のテキストエディタでは内容を確認することができません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698496/2502565d-de41-046c-f398-c5a7122a8444.png)

外出ししたterraform planの内容を確認するときはterraform showを使います。

```powershell
terraform show "tfplan"
```

※参考

https://developer.hashicorp.com/terraform/tutorials/cli/plan


# 6. インスタンス構築
terraform applyでインスタンス構築処理としてコードが実行されます。
「Enter a value: 」に対して「yes」と入力してEnterを押下しない限りは、変更は適用されません。
※最初にterraform planを実行しているような感じです。

terraform applyを実行すると、下記ファイルが作成されます。
.tfstateが無いとこのコードで作成したインスタンスを削除・変更する操作ができなくなります。
- .terraform.tfstate.lock.info
  - .tfstateをロックするファイル(同時に変更が発生しないようにロックするため)
  ```text:.terraform.tfstate.lock.info
  {"ID":"******************","Operation":"OperationTypeApply","Info":"","Who":"PC名\\ユーザー名@PC名","Version":"1.7.3","Created":"yyyy-mm-ddThh:mm:dd.****","Path":"terraform.tfstate"}
  ```
  <br />
- terraform.tfstate
  - Terraformで構築したステータスを保存するファイル
  ```text:terraform.tfstate
  {
  "version": 4,
  "terraform_version": "1.7.3",
  "serial": 6,
  "lineage": "******************",
  "outputs": {},
  "resources": [],
  "check_results": null
  }
  ```

今回のコードの規模であれば、1～2分以内にはインスタンスが構築されます。

【実行コマンド】
```powershell
terraform apply
```

※terraform plan -out ""で出力したファイルを用いて適用する場合
```powershell
terraform apply "terraform planで外だししたファイル名"
```

【実行例】
```powershell
PS F:\work\terraform\test1> terraform apply

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_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0b5c74e235ed808b9"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_lifecycle                   = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t2.micro"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = (known after apply)
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + spot_instance_request_id             = (known after apply)
      + subnet_id                            = (known after apply)
      + tags                                 = {
          + "Name" = "TEST1"
        }
      + tags_all                             = {
          + "Name" = "TEST1"
        }
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)
    }

Plan: 1 to add, 0 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.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Still creating... [30s elapsed]
aws_instance.example: Creation complete after 32s [id=i-*****************]

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

- AWSコンソール確認
実際に構築されているかを確認します。

①AWSコンソールの検索ボックスに【EC2】と入力して検索し、サービス欄に表示された【EC2】を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698496/2d6f4d58-5662-78ae-c645-21a6e8bfbab6.png)

②左ペイン【▼インスタンス】＞【インスタンス】選択して、インスタンスを確認します。
　下記が作成されていれば問題ありません。
- Name：TEST1
- インスタンスタイプ：t2.micro
- AMI ID：ami-0b5c74e235ed808b9
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698496/b8d0a2e7-589c-a91c-67ca-02e84ab059b0.png)

# 7. インスタンス変更
AMIを変更してコードを実行してみます。
先ほどのmain.tfのamiの値を下記に変更して、terraform applyをします。

```diff
-  ami           = "ami-0b5c74e235ed808b9"
+  ami           = "ami-07c589821f2b353aa"
```

【実行例】
```powershell
PS F:\work\terraform\test1> terraform apply
aws_instance.example: Refreshing state... [id=i-**************a]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:    
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # aws_instance.example must be replaced
-/+ resource "aws_instance" "example" {
      ~ ami                                  = "ami-0b5c74e235ed808b9" -> "ami-07c589821f2b353aa" # forces replacement
      ~ arn                                  = "arn:aws:ec2:ap-northeast-1:**************:instance/i-**************a" -> (known after apply)  
      ~ associate_public_ip_address          = false -> (known after apply)
      ~ availability_zone                    = "ap-northeast-1c" -> (known after apply)
      ~ cpu_core_count                       = 1 -> (known after apply)
      ~ cpu_threads_per_core                 = 1 -> (known after apply)
      ~ disable_api_stop                     = false -> (known after apply)
      ~ disable_api_termination              = false -> (known after apply)
      ~ ebs_optimized                        = false -> (known after apply)
      - hibernation                          = false -> null
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      ~ id                                   = "i-**************a" -> (known after apply)
      ~ instance_initiated_shutdown_behavior = "stop" -> (known after apply)
      + instance_lifecycle                   = (known after apply)
      ~ instance_state                       = "stopped" -> (known after apply)
      ~ ipv6_address_count                   = 0 -> (known after apply)
      ~ ipv6_addresses                       = [] -> (known after apply)
      + key_name                             = (known after apply)
      ~ monitoring                           = false -> (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      ~ placement_partition_number           = 0 -> (known after apply)
      ~ primary_network_interface_id         = "eni-**************5" -> (known after apply)
      ~ private_dns                          = "ip-***-***-***-***.ap-northeast-1.compute.internal" -> (known after apply)
      ~ private_ip                           = "***.***.***.***" -> (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      ~ secondary_private_ips                = [] -> (known after apply)
      ~ security_groups                      = [
          - "default",
        ] -> (known after apply)
      + spot_instance_request_id             = (known after apply)
      ~ subnet_id                            = "subnet-**************3" -> (known after apply)
        tags                                 = {
            "Name" = "TEST1"
        }
      ~ tenancy                              = "default" -> (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      ~ vpc_security_group_ids               = [
          - "sg-**************c",
        ] -> (known after apply)
        # (5 unchanged attributes hidden)

      - capacity_reservation_specification {
          - capacity_reservation_preference = "open" -> null
        }

      - cpu_options {
          - core_count       = 1 -> null
          - threads_per_core = 1 -> null
        }

      - credit_specification {
          - cpu_credits = "standard" -> null
        }

      - enclave_options {
          - enabled = false -> null
        }

      - maintenance_options {
          - auto_recovery = "default" -> null
        }

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

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

      - root_block_device {
          - delete_on_termination = true -> null
          - device_name           = "/dev/xvda" -> null
          - encrypted             = false -> null
          - iops                  = 3000 -> null
          - tags                  = {} -> null
          - throughput            = 125 -> null
          - volume_id             = "vol-**************2" -> null
          - volume_size           = 8 -> null
          - volume_type           = "gp3" -> null
        }
    }

Plan: 1 to add, 0 to change, 1 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.example: Destroying... [id=i-**************a]
aws_instance.example: Still destroying... [id=i-**************a, 10s elapsed]
aws_instance.example: Destruction complete after 10s
aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Still creating... [30s elapsed]
aws_instance.example: Creation complete after 32s [id=i-***************e]

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

- AWSコンソール画面

先ほど構築したインスタンスが終了され、AMI IDが変更されたインスタンスが構築されています。
実行例でreplaceという記載があった通り、インスタンスが再構築されていることが分かります。
※Amazon LinuxからUbuntuに変更しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698496/2399d0ab-7e3f-22df-9137-30c5dcda0867.png)

# 8. インスタンス削除
terraform destroyで削除処理としてコードを実行することができます。
こちらもterraform applyの時と同様に「Enter a value: 」に対して「yes」と入力してEnterを押下しない限りは、変更は適用されません。
※最初にterraform planを実行しているような感じです。

【実行コマンド】
```powershell
terraform destroy
```
【実行例】
```powershell
PS F:\work\terraform\test1> terraform destroy
aws_instance.example: Refreshing state... [id=i-**************e]

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

Terraform will perform the following actions:

  # aws_instance.example will be destroyed
  - resource "aws_instance" "example" {
      - ami                                  = "ami-07c589821f2b353aa" -> null
      - arn                                  = "arn:aws:ec2:ap-northeast-1:**************:instance/i-**************e" -> null
      - associate_public_ip_address          = true -> null
      - availability_zone                    = "ap-northeast-1c" -> null
      - cpu_core_count                       = 1 -> null
      - cpu_threads_per_core                 = 1 -> null
      - disable_api_stop                     = false -> null
      - disable_api_termination              = false -> null
      - ebs_optimized                        = false -> null
      - get_password_data                    = false -> null
      - hibernation                          = false -> null
      - id                                   = "i-**************e" -> null
      - instance_initiated_shutdown_behavior = "stop" -> null
      - instance_state                       = "running" -> null
      - instance_type                        = "t2.micro" -> null
      - ipv6_address_count                   = 0 -> null
      - ipv6_addresses                       = [] -> null
      - monitoring                           = false -> null
      - placement_partition_number           = 0 -> null
      - primary_network_interface_id         = "eni-**************4" -> null
      - private_dns                          = "ip-***-***-***-***.ap-northeast-1.compute.internal" -> null
      - private_ip                           = "***-***-***-***" -> null
      - public_dns                           = "ec2-***-***-***-***.ap-northeast-1.compute.amazonaws.com" -> null
      - public_ip                            = "52.195.147.112" -> null
      - secondary_private_ips                = [] -> null
      - security_groups                      = [
          - "default",
        ] -> null
      - source_dest_check                    = true -> null
      - subnet_id                            = "subnet-**************" -> null
      - tags                                 = {
          - "Name" = "TEST1"
        } -> null
      - tags_all                             = {
          - "Name" = "TEST1"
        } -> null
      - tenancy                              = "default" -> null
      - user_data_replace_on_change          = false -> null
      - vpc_security_group_ids               = [
          - "sg-0decebbbeeed7d7ec",
        ] -> null

      - capacity_reservation_specification {
          - capacity_reservation_preference = "open" -> null
        }

      - cpu_options {
          - core_count       = 1 -> null
          - threads_per_core = 1 -> null
        }

      - credit_specification {
          - cpu_credits = "standard" -> null
        }

      - enclave_options {
          - enabled = false -> null
        }

      - maintenance_options {
          - auto_recovery = "default" -> null
        }

      - metadata_options {
          - http_endpoint               = "enabled" -> null
          - http_protocol_ipv6          = "disabled" -> null
          - http_put_response_hop_limit = 1 -> null
          - http_tokens                 = "optional" -> null
          - instance_metadata_tags      = "disabled" -> null
        }

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

      - root_block_device {
          - delete_on_termination = true -> null
          - device_name           = "/dev/sda1" -> null
          - encrypted             = false -> null
          - iops                  = 100 -> null
          - tags                  = {} -> null
          - throughput            = 0 -> null
          - volume_id             = "vol-**************" -> null
          - volume_size           = 8 -> null
          - volume_type           = "gp2" -> null
        }
    }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_instance.example: Destroying... [id=i-**************e]
aws_instance.example: Still destroying... [id=i-**************e, 10s elapsed]
aws_instance.example: Still destroying... [id=i-**************e, 20s elapsed]
aws_instance.example: Still destroying... [id=i-**************e, 30s elapsed]
aws_instance.example: Destruction complete after 30s

Destroy complete! Resources: 1 destroyed.
```
- AWSコンソール画面
インスタンスが【終了済み】になっていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698496/81c66a00-c70c-1860-37dd-e9dd619c2763.png)

# おわりに
今回はterraformのコードを実行するためのtfファイルの作成方法とterraformコマンドの使い方をご紹介しました。
次回はterraformのファイル構成についてご紹介します。

最後までお読みいただきありがとうございました。

# 参考
https://developer.hashicorp.com/terraform/tutorials/aws-get-started
https://developer.hashicorp.com/terraform/language/providers/requirements
https://registry.terraform.io/providers/hashicorp/aws/latest/docs
https://docs.aws.amazon.com/ja_jp/proton/latest/userguide/env-parameters-tform.html
https://docs.aws.amazon.com/ja_jp/proton/latest/userguide/ag-infrastructure-tmp-files-terraform.html