はじめに

Terraform を使ったことがなく、今後使うようにしてみたいなと思った。
まずはシンプルな構成を構築するのが良さそうなので、普段使っているAWS上でEC2のインスタンスを作るということをやってみる。

環境

1
2
3
4
Windows 10 Professional

WSL2 (Ubuntu 22.04 LTS)
Terraform v1.5.5

準備

  • AWSアカウントを作成済み
  • WSL2導入済み
  • AWSコマンド導入済み の前提で始める。

下記を参考にして構築する。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs

構築するアーキテクチャ

pluralith-infra.png

Terraformの導入

下記を参考にインストールする。
https://developer.hashicorp.com/terraform/downloads

  1. GPGキーの導入
1
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
  1. HashiCorpのリポジトリをAPT (Advanced Package Tool) パッケージマネージャーに追加する
1
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
  1. terraformのインストール
1
sudo apt update && sudo apt install terraform
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Get:1 https://apt.releases.hashicorp.com jammy InRelease [12.9 kB]
Get:2 https://apt.releases.hashicorp.com jammy/main amd64 Packages [94.5 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Hit:4 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:5 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
Get:6 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [657 kB]
Get:7 http://security.ubuntu.com/ubuntu jammy-security/main Translation-en [153 kB]
Get:8 http://security.ubuntu.com/ubuntu jammy-security/main amd64 c-n-f Metadata [11.2 kB]
Get:15 http://archive.ubuntu.com/ubuntu jammy-updates/restricted amd64 Packages [674 kB]
Get:16 http://archive.ubuntu.com/ubuntu jammy-updates/restricted Translation-en [108 kB]
Get:17 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages [965 kB]
Get:18 http://archive.ubuntu.com/ubuntu jammy-updates/multiverse amd64 Packages [41.6 kB]
Fetched 4916 kB in 4s (1267 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
12 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  golang-1.18 golang-1.18-doc golang-1.18-go golang-1.18-src golang-doc golang-go golang-src pkg-config
Use 'sudo apt autoremove' to remove them.
The following NEW packages will be installed:
  terraform
0 upgraded, 1 newly installed, 0 to remove and 12 not upgraded.
Need to get 21.8 MB of archives.
After this operation, 65.2 MB of additional disk space will be used.
Get:1 https://apt.releases.hashicorp.com jammy/main amd64 terraform amd64 1.5.5-1 [21.8 MB]
Fetched 21.8 MB in 0s (68.9 MB/s)
Selecting previously unselected package terraform.
(Reading database ... 80156 files and directories currently installed.)
Preparing to unpack .../terraform_1.5.5-1_amd64.deb ...
Unpacking terraform (1.5.5-1) ...
Setting up terraform (1.5.5-1) ...
  1. バージョンの確認
1
terraform -v
1
2
Terraform v1.5.5
on linux_amd64

v1.5.5 がインストールできた。

aws configureの実行

※事前にTerraform用のIAMユーザを作成済み。
AmazonEC2FullAccessAmazonVPCFullAccess の権限を付与済み。

Terraformで使用する認証情報を設定する。

1
aws configure --profile terraform
1
2
3
4
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json

~/.aws/credentials

1
2
3
4
5
6
7
[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXX

[terraform]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXX

上記のようにプロファイルが追加されていればOK

AmazonLinux2023 AMIのAMI ID取得

create-pluralith-account-1

tfファイルの作成

Terraform では、 .tfファイルというのを作成してリソースを定義する。

各種リソースの定義

ファイル名役割
main.tfプロパイダーとリージョンの定義をする
aws_vpc.tfVPCの定義/サブネットの定義/ルートテーブルとIGWの定義
aws_ec2.tfEC2の定義

main.tf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "ap-northeast-1"
  shared_credentials_files = ["/path/to/dir/.aws/credentials"]
  profile = "terraform"
}

aws_vpc.tf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public_subnet" {
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = true
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.vpc.id
}

resource "aws_route_table" "route_table" {
  vpc_id = aws_vpc.vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }
}

resource "aws_route_table_association" "route_assoc" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.route_table.id
}

aws_ec2.tf

1
2
3
4
5
6
7
8
9
resource "aws_instance" "app_server" {
  ami           = "ami-0e0166ef4456f252a" #AmazonLinux2023 (arm)
  instance_type = "t4g.micro"
  subnet_id     = aws_subnet.public_subnet.id

  tags = {
    Name = "SampleEC2Instance"
  }
}

terraform initの実行

1
terraform init
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.12.0...
- Installed hashicorp/aws v5.12.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 ディレクトリができているはず。

terraform validateで構文をチェック

1
terraform validate
1
Success! The configuration is valid.

と出ればOK!

terraform fmtで整形

1
terraform fmt

コード整形がされる。

terraform applyでデプロイ

1
terraform apply
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

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.app_server will be created
  + resource "aws_instance" "app_server" {
      + ami                                  = "ami-0e0166ef4456f252a"
      + 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                        = "t4g.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" = "SampleEC2Instance"
        }
      + tags_all                             = {
          + "Name" = "SampleEC2Instance"
        }
      + 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)
    }

  # aws_internet_gateway.igw will be created
  + resource "aws_internet_gateway" "igw" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + owner_id = (known after apply)
      + tags_all = (known after apply)
      + vpc_id   = (known after apply)
    }

  # aws_route_table.route_table will be created
  + resource "aws_route_table" "route_table" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + carrier_gateway_id         = ""
              + cidr_block                 = "0.0.0.0/0"
              + core_network_arn           = ""
              + destination_prefix_list_id = ""
              + egress_only_gateway_id     = ""
              + gateway_id                 = (known after apply)
              + ipv6_cidr_block            = ""
              + local_gateway_id           = ""
              + nat_gateway_id             = ""
              + network_interface_id       = ""
              + transit_gateway_id         = ""
              + vpc_endpoint_id            = ""
              + vpc_peering_connection_id  = ""
            },
        ]
      + tags_all         = (known after apply)
      + vpc_id           = (known after apply)
    }

  # aws_route_table_association.route_assoc will be created
  + resource "aws_route_table_association" "route_assoc" {
      + id             = (known after apply)
      + route_table_id = (known after apply)
      + subnet_id      = (known after apply)
    }

  # aws_subnet.public_subnet will be created
  + resource "aws_subnet" "public_subnet" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags_all                                       = (known after apply)
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.vpc will be created
  + resource "aws_vpc" "vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags_all                             = (known after apply)
    }

Plan: 6 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.

こんな感じでできた!

1
  Enter a value: 

yes を入力する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
aws_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 1s [id=vpc-0f9fdc94b1ccf65aa]
aws_internet_gateway.igw: Creating...
aws_subnet.public_subnet: Creating...
aws_internet_gateway.igw: Creation complete after 0s [id=igw-00aef63daacb2c8bd]
aws_route_table.route_table: Creating...
aws_route_table.route_table: Creation complete after 1s [id=rtb-081629abd2b6d89c7]
aws_subnet.public_subnet: Still creating... [10s elapsed]
aws_subnet.public_subnet: Creation complete after 11s [id=subnet-0a6b4ee0093e590d4]
aws_route_table_association.route_assoc: Creating...
aws_instance.app_server: Creating...
aws_route_table_association.route_assoc: Creation complete after 0s [id=rtbassoc-0818666a2e04cfd16]
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Creation complete after 12s [id=i-0616050c6fa40c6a9]

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

作成された。

確認

construct-aws-resource

terraform destroyで削除する

1
terraform destroy
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
aws_vpc.vpc: Refreshing state... [id=vpc-0f9fdc94b1ccf65aa]
aws_internet_gateway.igw: Refreshing state... [id=igw-00aef63daacb2c8bd]
aws_subnet.public_subnet: Refreshing state... [id=subnet-0a6b4ee0093e590d4]
aws_route_table.route_table: Refreshing state... [id=rtb-081629abd2b6d89c7]
aws_instance.app_server: Refreshing state... [id=i-0616050c6fa40c6a9]
aws_route_table_association.route_assoc: Refreshing state... [id=rtbassoc-0818666a2e04cfd16]

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.app_server will be destroyed
  - resource "aws_instance" "app_server" {
      - ami                                  = "ami-0e0166ef4456f252a" -> null
      - arn                                  = "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:instance/i-0616050c6fa40c6a9" -> null
      - associate_public_ip_address          = true -> null
      - availability_zone                    = "ap-northeast-1a" -> null
      - cpu_core_count                       = 2 -> 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-0616050c6fa40c6a9" -> null
      - instance_initiated_shutdown_behavior = "stop" -> null
      - instance_state                       = "running" -> null
      - instance_type                        = "t4g.micro" -> null
      - ipv6_address_count                   = 0 -> null
      - ipv6_addresses                       = [] -> null
      - monitoring                           = false -> null
      - placement_partition_number           = 0 -> null
      - primary_network_interface_id         = "eni-09609d9af23b9512a" -> null
      - private_dns                          = "ip-10-0-1-30.ap-northeast-1.compute.internal" -> null
      - private_ip                           = "10.0.1.30" -> null
      - public_ip                            = "52.199.75.202" -> null
      - secondary_private_ips                = [] -> null
      - security_groups                      = [] -> null
      - source_dest_check                    = true -> null
      - subnet_id                            = "subnet-0a6b4ee0093e590d4" -> null
      - tags                                 = {
          - "Name" = "SampleEC2Instance"
        } -> null
      - tags_all                             = {
          - "Name" = "SampleEC2Instance"
        } -> null
      - tenancy                              = "default" -> null
      - user_data_replace_on_change          = false -> null
      - vpc_security_group_ids               = [
          - "sg-0acf7b9e30730ae15",
        ] -> null

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

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

      - credit_specification {
          - cpu_credits = "unlimited" -> 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-026e2cee1874532d2" -> null
          - volume_size           = 8 -> null
          - volume_type           = "gp3" -> null
        }
    }

  # aws_internet_gateway.igw will be destroyed
  - resource "aws_internet_gateway" "igw" {
      - arn      = "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:internet-gateway/igw-00aef63daacb2c8bd" -> null
      - id       = "igw-00aef63daacb2c8bd" -> null
      - owner_id = "XXXXXXXXXXXX" -> null
      - tags     = {} -> null
      - tags_all = {} -> null
      - vpc_id   = "vpc-0f9fdc94b1ccf65aa" -> null
    }

  # aws_route_table.route_table will be destroyed
  - resource "aws_route_table" "route_table" {
      - arn              = "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:route-table/rtb-081629abd2b6d89c7" -> null
      - id               = "rtb-081629abd2b6d89c7" -> null
      - owner_id         = "037292740688" -> null
      - propagating_vgws = [] -> null
      - route            = [
          - {
              - carrier_gateway_id         = ""
              - cidr_block                 = "0.0.0.0/0"
              - core_network_arn           = ""
              - destination_prefix_list_id = ""
              - egress_only_gateway_id     = ""
              - gateway_id                 = "igw-00aef63daacb2c8bd"
              - ipv6_cidr_block            = ""
              - local_gateway_id           = ""
              - nat_gateway_id             = ""
              - network_interface_id       = ""
              - transit_gateway_id         = ""
              - vpc_endpoint_id            = ""
              - vpc_peering_connection_id  = ""
            },
        ] -> null
      - tags             = {} -> null
      - tags_all         = {} -> null
      - vpc_id           = "vpc-0f9fdc94b1ccf65aa" -> null
    }

  # aws_route_table_association.route_assoc will be destroyed
  - resource "aws_route_table_association" "route_assoc" {
      - id             = "rtbassoc-0818666a2e04cfd16" -> null
      - route_table_id = "rtb-081629abd2b6d89c7" -> null
      - subnet_id      = "subnet-0a6b4ee0093e590d4" -> null
    }

  # aws_subnet.public_subnet will be destroyed
  - resource "aws_subnet" "public_subnet" {
      - arn                                            = "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:subnet/subnet-0a6b4ee0093e590d4" -> null
      - assign_ipv6_address_on_creation                = false -> null
      - availability_zone                              = "ap-northeast-1a" -> null
      - availability_zone_id                           = "apne1-az4" -> null
      - cidr_block                                     = "10.0.1.0/24" -> null
      - enable_dns64                                   = false -> null
      - enable_lni_at_device_index                     = 0 -> null
      - enable_resource_name_dns_a_record_on_launch    = false -> null
      - enable_resource_name_dns_aaaa_record_on_launch = false -> null
      - id                                             = "subnet-0a6b4ee0093e590d4" -> null
      - ipv6_native                                    = false -> null
      - map_customer_owned_ip_on_launch                = false -> null
      - map_public_ip_on_launch                        = true -> null
      - owner_id                                       = "XXXXXXXXXXXX" -> null
      - private_dns_hostname_type_on_launch            = "ip-name" -> null
      - tags                                           = {} -> null
      - tags_all                                       = {} -> null
      - vpc_id                                         = "vpc-0f9fdc94b1ccf65aa" -> null
    }

  # aws_vpc.vpc will be destroyed
  - resource "aws_vpc" "vpc" {
      - arn                                  = "arn:aws:ec2:ap-northeast-1:XXXXXXXXXXXX:vpc/vpc-0f9fdc94b1ccf65aa" -> null
      - assign_generated_ipv6_cidr_block     = false -> null
      - cidr_block                           = "10.0.0.0/16" -> null
      - default_network_acl_id               = "acl-0d6d26291702cb555" -> null
      - default_route_table_id               = "rtb-07682a7c4e9d70ae2" -> null
      - default_security_group_id            = "sg-0acf7b9e30730ae15" -> null
      - dhcp_options_id                      = "dopt-7016bf14" -> null
      - enable_dns_hostnames                 = false -> null
      - enable_dns_support                   = true -> null
      - enable_network_address_usage_metrics = false -> null
      - id                                   = "vpc-0f9fdc94b1ccf65aa" -> null
      - instance_tenancy                     = "default" -> null
      - ipv6_netmask_length                  = 0 -> null
      - main_route_table_id                  = "rtb-07682a7c4e9d70ae2" -> null
      - owner_id                             = "XXXXXXXXXXXX" -> null
      - tags                                 = {} -> null
      - tags_all                             = {} -> null
    }

Plan: 0 to add, 0 to change, 6 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 で削除する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
aws_route_table_association.route_assoc: Destroying... [id=rtbassoc-0818666a2e04cfd16]
aws_instance.app_server: Destroying... [id=i-0616050c6fa40c6a9]
aws_route_table_association.route_assoc: Destruction complete after 1s
aws_route_table.route_table: Destroying... [id=rtb-081629abd2b6d89c7]
aws_route_table.route_table: Destruction complete after 0s
aws_internet_gateway.igw: Destroying... [id=igw-00aef63daacb2c8bd]
aws_instance.app_server: Still destroying... [id=i-0616050c6fa40c6a9, 10s elapsed]
aws_internet_gateway.igw: Still destroying... [id=igw-00aef63daacb2c8bd, 10s elapsed]
aws_instance.app_server: Still destroying... [id=i-0616050c6fa40c6a9, 20s elapsed]
aws_internet_gateway.igw: Still destroying... [id=igw-00aef63daacb2c8bd, 20s elapsed]
aws_instance.app_server: Still destroying... [id=i-0616050c6fa40c6a9, 30s elapsed]
aws_internet_gateway.igw: Still destroying... [id=igw-00aef63daacb2c8bd, 30s elapsed]
aws_instance.app_server: Still destroying... [id=i-0616050c6fa40c6a9, 40s elapsed]
aws_internet_gateway.igw: Still destroying... [id=igw-00aef63daacb2c8bd, 40s elapsed]
aws_internet_gateway.igw: Destruction complete after 47s
aws_instance.app_server: Still destroying... [id=i-0616050c6fa40c6a9, 50s elapsed]
aws_instance.app_server: Destruction complete after 51s
aws_subnet.public_subnet: Destroying... [id=subnet-0a6b4ee0093e590d4]
aws_subnet.public_subnet: Destruction complete after 0s
aws_vpc.vpc: Destroying... [id=vpc-0f9fdc94b1ccf65aa]
aws_vpc.vpc: Destruction complete after 1s

AWS構成図の作成

Pluralithのインストール

https://docs.pluralith.com/docs/get-started/run-locally/

  1. pluralithをダウンロードし、実行権限を付与する。
1
2
3
4
mkdir -p /tmp/pluralith && cd $_
wget https://github.com/Pluralith/pluralith-cli/releases/download/v0.2.2/pluralith_cli_tap_linux_amd64_v0.2.2.tar.gz
tar xzvf pluralith_cli_tap_linux_amd64_v0.2.2.tar.gz
sudo mv linux/pluralith /usr/local/bin
  1. pluralithのアカウントを作成する。
    https://app.pluralith.com/ から Sign Upをする。

  2. Sign Up後のポップアップからAPI Keyを取得する。
    create-pluralith-account-1

  3. API Keyを使用して、pluralith login を実行する。

1
export PLURALITH_API_KEY=XXXXXXXXXXXXXX
1
sudo pluralith login --api-key $PLURALITH_API_KEY
  1. pluralith graph でグラフを生成する。
1
sudo pluralith graph
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
⠿ Initiating Graph ⇢ Posting Diagram To Pluralith Dashboard

→ Authentication
  ✔ API key is valid, you are authenticated!

→ Plan
  ✔ Local Execution Plan Generated
  ✔ Local Plan Cache Created
  ✔ Secrets Stripped
  - Cost Calculation Skipped

→ Graph
  ✔ Local Diagram Generated
  ✔ Diagram Posted To Pluralith Dashboard

  → Diagram Pushed To: https://app.pluralith.com/XXXXXXXXXXXXXXXXXXXXX

pluralith-infra.png

参考

おわりに

Terraformで AWSの構築をしてみたかったのでしてみた。
次回は、もうちょっと複雑な構成を作ってみる。
後、キーペアって設定するものなのかな…。今回はしていなかったけど。
いつもセキュリティグループでIP限定しとけば大丈夫というノリでSSHで接続してしまうのだが、AWS SSM?とか使ったほうが良いのか。
このあたりちゃんと調べてみようかな。
ちなみにデフォルトのSGは全開放なので、ちゃんとSG設定はしたほうが良いですね。
pluralith を使ってみたが tfファイルから構成図作れるのは便利そう。
draw.io でいつも手で書いていたが IaCなら自動で作図してくれる方が良い。