TerraformでAmazon EC2インスタンスを作成、変更、削除してみよう:「AWS」×「Terraform」で学ぶクラウド時代のインフラ管理入門(2)
自動化ツールの一つである「Terraform」について、これから学ぼうという方、使っていきたい方を対象に、基本的な使い方を紹介していきます。第2回は、EC2インスタンスの作成、変更、削除方法について。
自動化ツールの一つである「Terraform」について、これから学ぼうという方、使っていきたい方を対象に、基本的な使い方を紹介していく本連載。第1回では、Terraformの概要と導入方法を解説しました。第2回は、Terraformを利用してAmazon Web Services(AWS)の環境でAmazon EC2インスタンスの作成、変更、削除方法を解説します。
TerraformでEC2インスタンスを作成する
まずは、習うより慣れろの気持ちで、Terraformを使用してEC2インスタンスを作成してみましょう。第1回でTerraformのコードを記述したファイルmain.tfに、以下の内容を追記します。
resource "aws_instance" "example" {
ami = "ami-0f9816f78187c68fb"
instance_type = "t2.micro"
}
設定している各パラメーターの簡単な説明は以下の通りです。
| パラメーター名 | 説明 |
|---|---|
| ami | 作成するEC2インスタンスの元となるAMI(Amazon マシンイメージ)のIDを指定します。今回はAmazon Linux 2023のAMIを指定しています。 |
| instance_type | 作成するEC2インスタンスのインスタンスタイプを指定します。今回は AWSの無料利用枠対象でもある「t2.micro」を指定しています。 |
続いて、以下のようにterraform planコマンドを実行してどのような処理が行われるのか確認してみましょう。
$ 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-0f9816f78187c68fb"
+ 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_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
+ subnet_id = (known after apply)
+ tags_all = (known after apply)
+ 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のコードを修正してください。
╷
│ Error: Unsupported block type
│
│ on main.tf line 14:
│ 14: resourct "aws_instance" "example" {
│
│ Blocks of type "resourct" are not expected here. Did you mean "resource"?
╵
エラーメッセージが出力されず問題なく処理されたら、terraform applyコマンドを実行しましょう。途中、「Enter a value:」というプロンプトが表示された場合は「yes」と入力して[Enter]キーを押します。
$ 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" {
(中略)
}
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: Creation complete after 21s [id=i-xxxxxxxxxxxxxxxxx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
上記のように「Apply complete!」と表示されれば、EC2インスタンスの作成に成功しているはずです。AWSのマネジメントコンソールにアクセスして確認してみましょう。以下の画像のように、EC2インスタンスが作成されていることが確認できます。
TerraformでEC2インスタンスを変更する
TerraformでEC2インスタンスを手軽に作成できることが分かったところで、今度は作成したEC2インスタンスに対して変更を加えてみましょう。AWSマネジメントコンソールの「Name」欄は、EC2インスタンスに「Name」タグが設定されている場合、その値が表示されるようになっています。この、「Name」タグの設定をTerraformのコードで実現しましょう。
先ほど作成したmain.tfに、以下のような変更を加えます。
resource "aws_instance" "example" {
ami = "ami-0f9816f78187c68fb"
instance_type = "t2.micro"
# ここから下を追記。
tags = {
Name = "example"
}
}
追記したパラメーターの簡単な説明は以下の通りです。
| パラメーター名 | 説明 |
|---|---|
| tags | EC2インスタンスに設定するタグを記述します。タグ名と値の組み合わせで設定します。 |
追記が完了したら、EC2インスタンスを作成したときと同様にterraform planコマンドを実行して、問題がないことを確認します。
$ terraform plan
aws_instance.example: Refreshing state... [id=i-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_instance.example will be updated in-place
~ resource "aws_instance" "example" {
id = "i-xxxxxxxxxxxxxxxxx"
~ tags = {
+ "Name" = "example"
}
~ tags_all = {
+ "Name" = "example"
}
# (30 unchanged attributes hidden)
# (8 unchanged blocks hidden)
}
Plan: 0 to add, 1 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.
コマンドの実行結果を見ると、作成したEC2インスタンスを残したまま、タグを設定するような動作をする予定であると分かります。問題はなさそうなので、このままterraform applyコマンドを実行して、変更を適用してみましょう。
$ terraform apply
aws_instance.example: Refreshing state... [id=i-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_instance.example will be updated in-place
~ resource "aws_instance" "example" {
id = "i-xxxxxxxxxxxxxxxxx"
~ tags = {
+ "Name" = "example"
}
~ tags_all = {
+ "Name" = "example"
}
# (30 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.example: Modifying... [id=i-xxxxxxxxxxxxxxxxx]
aws_instance.example: Modifications complete after 0s [id=i-xxxxxxxxxxxxxxxxx]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
変更が完了したので、AWSマネジメントコンソールを確認します。以下のように、「Name」欄に「example」が設定されているはずです。
次に、タグ以外も変更してみましょう。EC2インスタンスのストレージサイズも変更します。main.tfに以下のような変更を加えます。
resource "aws_instance" "example" {
ami = "ami-0f9816f78187c68fb"
instance_type = "t2.micro"
tags = {
Name = "example"
}
# ここから下を追記。
root_block_device {
volume_size = 10
}
}
追記したパラメーターの簡単な説明は以下の通りです。
| パラメーター名 | 説明 |
|---|---|
| root_block_device | EC2インスタンスのルートブロックデバイスに関する各種設定です。 |
| volume_size | ボリュームサイズをGiB単位で設定します。 |
追記が完了したら、先ほどと同様にterraform planコマンドを実行して問題がないことを確認し、terraform applyコマンドで変更を適用します。
$ terraform apply
aws_instance.example: Refreshing state... [id=i-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_instance.example will be updated in-place
~ resource "aws_instance" "example" {
id = "i-xxxxxxxxxxxxxxxxx"
tags = {
"Name" = "example"
}
# (31 unchanged attributes hidden)
~ root_block_device {
tags = {}
~ volume_size = 8 -> 10
# (7 unchanged attributes hidden)
}
# (7 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.example: Modifying... [id=i-xxxxxxxxxxxxxxxxx]
aws_instance.example: Still modifying... [id=i-xxxxxxxxxxxxxxxxx, 10s elapsed]
aws_instance.example: Still modifying... [id=i-xxxxxxxxxxxxxxxxx, 20s elapsed]
aws_instance.example: Still modifying... [id=i-xxxxxxxxxxxxxxxxx, 30s elapsed]
aws_instance.example: Modifications complete after 30s [id=i-xxxxxxxxxxxxxxxxx]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
変更が完了したので、AWSマネジメントコンソールを確認します。対象のEC2インスタンスを選択し、その下に表示されるインスタンスの詳細情報のうち「ストレージ」タブを選択すると、EC2インスタンスにアタッチされているブロックデバイスが表示されます。
ルートブロックデバイスのサイズが先ほど設定した「10」になっていることを確認します。
TerraformでEC2インスタンスを削除する
最後に、作成したEC2インスタンスをTerraformで削除します。TerraformによるEC2インスタンスの削除はとても簡単で、先ほどまで記述した以下の内容を、そのまま削除するだけで実現できます。
# 以下の内容を全て削除する。
resource "aws_instance" "example" {
ami = "ami-0f9816f78187c68fb"
instance_type = "t2.micro"
tags = {
Name = "example"
}
root_block_device {
volume_size = 10
}
}
削除が完了したら、terraform planでどのような処理が実行されるか確認します。
$ terraform plan
aws_instance.example: Refreshing state... [id=i-xxxxxxxxxxxxxxxxx]
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
# (because aws_instance.example is not in configuration)
- resource "aws_instance" "example" {
(中略)
}
Plan: 0 to add, 0 to change, 1 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.
EC2インスタンスが削除されることを確認できました。では、terraform applyコマンドを実行して、削除を実行します。
$ terraform apply
aws_instance.example: Refreshing state... [id=i-xxxxxxxxxxxxxxxxx]
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
# (because aws_instance.example is not in configuration)
- resource "aws_instance" "example" {
(中略)
}
Plan: 0 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-xxxxxxxxxxxxxxxxx]
aws_instance.example: Still destroying... [id=i-xxxxxxxxxxxxxxxxx, 10s elapsed]
aws_instance.example: Still destroying... [id=i-xxxxxxxxxxxxxxxxx, 20s elapsed]
aws_instance.example: Destruction complete after 29s
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
AWSマネジメントコンソールの画面でも確認してみましょう。以下のように、作成していたEC2インスタンスの状態が「終了済み」となっており、削除されたことが確認できます。
Terraformコードの記述方法について
ここまでで、EC2インスタンスの作成と変更、削除手順を解説しました。その手順の中で記述してきたTerraformのコードについてもう少し詳しく解説します。
Terraformでは、EC2インスタンスなど、作成すべき対象を「リソース」と呼びます。そして、作成するリソースタイプが存在し、作成するリソースにはTerraform上で区別する名前を付ける必要があります。この記述ルールをTerraformのコードで表すと、次のようになります。
resource "<リソースタイプ>" "<リソースの名前>" {
# リソース固有の設定
}
本記事では、「aws_instance」というリソースを「example」という名前で作成していたことになります。
TerraformがAWS向けに用意しているリソースなどをまとめた公式ドキュメントを見ると、非常に多くのリソースタイプが用意されており、AWSで作成したいリソースはほぼTerraformで作成できるといっても過言ではありません。
次回は、複数のEC2インスタンス環境を構築したり運用したりする手順を紹介していきます。
筆者紹介
鎌田啓佑
サイオステクノロジー所属。OSS よろず相談室でサポート対応をしているテクニカルサポートエンジニア。Ansible に出会ってから自動化に取り憑かれ、自身の業務やプライベートであらゆるものの自動化に取り組む。プライベートでは Java でちょっとしたツールの開発を趣味にしている。
Copyright © ITmedia, Inc. All Rights Reserved.

