<Terraform学習>AWSにサブネットを作成してみる

# 前提条件
学習のため細かく分けて作成していきます。
VPCは以前作成したVPCを使用します。（[<Terraform学習>AWSにVPCを作成してみる](https://qiita.com/TTG/items/59f0579383c705870ee8)）

# バージョン情報
- Terraform: `Terraform v1.10.5`
- AWS CLI: `aws-cli/2.24.11 Python/3.12.9 Windows/11 exe/AMD64`

# Terraform ファイルの作成
## `02_subnet.tf`
以下の Terraform ファイルを作成しました。
既存のリソースを使用する場合には`dataブロック` を使用します。

ファイル内で使用している以下のものは任意の名前で大丈夫です。
- terraform-vpc-data
- terraform-public-subnet
- terraform-private-subnet

```json
provider "aws" {
    region = "us-west-2"
}

data "aws_vpc" "terraform-vpc-data" {
    filter {
        name = "tag:Name"
        values = ["terraform"]
    }
}

resource "aws_subnet" "terraform-public-subnet" {
    vpc_id = data.aws_vpc.terraform-vpc-data.id
    cidr_block = "10.0.1.0/24"
    map_public_ip_on_launch = true
    tags = {
        Name = "terraform-public"
    }
}

resource "aws_subnet" "terraform-private-subnet"{
    vpc_id = data.aws_vpc.terraform-vpc-data.id
    cidr_block = "10.0.2.0/24"
    map_public_ip_on_launch = false
    tags = {
        Name = "terraform-private"
    }
}
```

# Terraform の実行
## `terraform init`
Terraform を初期化します。
```powershell
PS C:\work\Terraform\01_basic\02-subnet> terraform init
```
出力結果:
```log
Terraform has been successfully initialized!
```

## `terraform plan`
Terraform の適用計画を確認します。
```powershell
PS C:\work\Terraform\01_basic\02-subnet> terraform plan
```
出力結果:
```log
data.aws_vpc.terraform-vpc-data: Reading...
data.aws_vpc.terraform-vpc-data: Read complete after 2s [id=vpc-xxxxxxxxxxxxxxxx]

Terraform will perform the following actions:

  # aws_subnet.terraform-private-subnet will be created
  # aws_subnet.terraform-public-subnet will be created

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

## `terraform apply`
サブネットを作成します。
```powershell
PS C:\work\Terraform\01_basic\02-subnet> terraform apply
```
出力結果:
```log
aws_subnet.terraform-private-subnet: Creating...
aws_subnet.terraform-public-subnet: Creating...
aws_subnet.terraform-private-subnet: Creation complete after 2s [id=subnet-xxxxxxxxxxxxxxxxx]
aws_subnet.terraform-public-subnet: Still creating... [10s elapsed]
aws_subnet.terraform-public-subnet: Creation complete after 13s [id=subnet-xxxxxxxxxxxxxxxxx]

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

# AWS Subnetパラメータについて
<details><summary>パラメータ一覧</summary>
参照： 

[Terraform_Resource: aws_vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet)
| パラメータ名 | 説明 |
|-------------|------|
| `assign_ipv6_address_on_creation` | 指定したサブネット内で作成されるネットワークインターフェースに IPv6 アドレスを割り当てるかどうか。デフォルトは `false`。 |
| `availability_zone` | サブネットのアベイラビリティゾーン（AZ）。 |
| `availability_zone_id` | サブネットの AZ ID。一部のリージョンやパーティションではサポートされていないため、必要に応じて `availability_zone` を使用。 |
| `cidr_block` | サブネットの IPv4 CIDR ブロック。 |
| `customer_owned_ipv4_pool` | カスタマー所有の IPv4 アドレスプール。通常、`map_customer_owned_ip_on_launch` 引数と組み合わせて使用。設定時には `outpost_arn` も指定する必要がある。 |
| `enable_dns64` | サブネット内で Amazon 提供の DNS Resolver に対する DNS クエリが、IPv4 のみの宛先に対して IPv6 アドレスを返すかどうかを指定。デフォルトは `false`。 |
| `enable_lni_at_device_index` | サブネット内のローカルネットワークインターフェースのデバイス位置を指定。例えば、`1` を指定すると `eth1` がセカンダリネットワークインターフェースになる。 |
| `enable_resource_name_dns_aaaa_record_on_launch` | インスタンスのホスト名に対する DNS クエリの応答で、DNS AAAA レコード（IPv6）を返すかどうかを指定。デフォルトは `false`。 |
| `enable_resource_name_dns_a_record_on_launch` | インスタンスのホスト名に対する DNS クエリの応答で、DNS A レコード（IPv4）を返すかどうかを指定。デフォルトは `false`。 |
| `ipv6_cidr_block` | サブネットの IPv6 ネットワーク範囲（CIDR 表記）。サブネットサイズは `/64` プレフィックスを使用する必要がある。 |
| `ipv6_native` | IPv6 のみのサブネットを作成するかどうかを指定。デフォルトは `false`。 |
| `map_customer_owned_ip_on_launch` | サブネット内で作成されるネットワークインターフェースにカスタマー所有の IP アドレスを割り当てるかどうかを指定。設定時には `customer_owned_ipv4_pool` と `outpost_arn` を指定する必要がある。デフォルトは `false`。 |
| `map_public_ip_on_launch` | サブネットに起動するインスタンスにパブリック IP アドレスを割り当てるかどうかを指定。デフォルトは `false`。 |
| `outpost_arn` | Outpost の Amazon リソースネーム（ARN）。 |
| `private_dns_hostname_type_on_launch` | サブネット内のインスタンスに割り当てるホスト名の種類。IPv6 のみのサブネットではインスタンス ID に基づくホスト名が必須。IPv4 またはデュアルスタックのサブネットでは、DNS 名が IPv4 アドレスまたはインスタンス ID のいずれかを使用可能。`ip-name` または `resource-name` の値が利用可能。 |
| `vpc_id` | サブネットが属する VPC の ID（必須）。 |
| `tags` | リソースに割り当てるタグのマップ。プロバイダーで `default_tags` を設定している場合、キーが一致するタグはプロバイダー側の値で上書きされる。 |
</details>


# 気づいたこと、勘違いしていたこと
1. Terraformはファイルごとに実行できない。
    私は複数の.tfファイルがあっても実行するファイルをオプションで指定すれば個別で実行できると勘違いしていました。
    実際にはそんな仕様はありませんでした。
    今回は細かく分割してAWSリソースを作る方針だったので、フォルダを新しく作成して、terraformコマンドを実行することにしました。
    
1. AWSのリソースへ適切な`Tag`を作成することが大切。
    `dataブロック`を使用するときに`Tag`を使用して参照するようにしました。
    これまでは何となく設定していたのですが、用途ごとに適切に設定する必要性を実感しました。
    命名のセンスも問われそうだと思いました。

# まとめ
- 既存の VPC を参照してパブリックサブネットとプライベートサブネットを作成しました。

次回は **ルートテーブルの設定** を行います。