目次Category
はじめに
今回の記事では、Terraform(テラフォーム)を使用してAWSリソースを構築する方法について説明します。
Terraformは、サーバーやネットワーク、データベースなどのインフラ構成をコードで定義するためのツールです。
このようにインフラをコードで管理する考え方を、Infrastructure as Code(IaC)と呼びます。
AWSマネジメントコンソールを使用する場合は、画面上で設定項目を一つずつ入力してリソースを作成します。 一方、Terraformでは、作成するリソースの種類や設定内容をコードとして記述し、そのコードをもとにAWSリソースを作成します。

参考画像
- 一度作成したTerraformのコードを利用することで、同じ設定のAWSリソースを別の環境にも作成しやすくなります。
- 設定内容を確認しやすい
AWSリソースの設定がコードとして残るため、どのような構成になっているのかを後から確認しやすくなります。 - 変更履歴を管理しやすい
Gitなどのバージョン管理システムと組み合わせることで、誰が、いつ、どの設定を変更したのかを記録できます。 - 作業を自動化・標準化しやすい
手作業による設定のばらつきを減らし、決められた構成でリソースを作成しやすくなります。 - 実行前に変更内容を確認できる
terraform planを実行することで、リソースを実際に変更する前に、作成・変更・削除される内容を確認できます。
Terraformを使用することで、AWSリソースを作成するだけではなく、構成の再利用や変更内容の確認、設定の管理までコードを中心に行えるようになります。
ただし、Terraformを使用すれば自動的に安全な構成になるわけではありません。 terraform apply や terraform destroy を実行する前に、変更対象を確認することが重要です。
今回は、Terraformの基本的な操作から、AWSリソースの作成、既存リソースのインポート、リソースの削除までを行います。
- AWS CLIでIAM Identity CenterのSSO認証を設定する
- TerraformからS3バケットを作成する
- TerraformからEC2インスタンスを作成する
- EC2上にApache Webサーバーを構築する
- セキュリティグループのポート番号を変数として管理する
- EC2のパブリックIPアドレスを出力する
- 既存のEC2インスタンスをTerraformへインポートする
- Terraformで作成したAWSリソースを削除する
この記事では、Terraformを初めて使用する人に向けて、実際に行った作業と各コマンドの役割を順番に説明します。
今回の作業では、VS CodeでTerraformの設定ファイルを作成し、AWS CLIで認証したAWS環境にS3とEC2を作成します。
・ VS Code └── Terraformの設定ファイルを作成 ・ AWS CLI └── IAM Identity CenterによるSSO認証 └── Terraform └── S3バケットを作成 └── EC2インスタンスを作成 └── Apache Webサーバーを構築 └── 既存EC2をインポート
Terraformでは、次の流れでAWSリソースを構築します。
Terraformの設定ファイル ↓ AWS Provider ↓ AWSのAPI ↓ S3・EC2などのAWSリソース
0. AWS CLIでSSO認証を設定する
TerraformからAWSリソースを作成するには、TerraformがAWSへアクセスするための認証情報が必要です。
今回は、アクセスキーを直接設定する方法ではなく、AWS IAM Identity Centerを利用したSSO認証を使用します。
0-1. SSOの設定を開始する
詳細な作業手順に関しては以下のブログを参照してください。
ECS (Fargate) + ALB Webアプリケーション構築ハンズオン | YAZエンジニアが運営するメディア Blilliant Engineer
1. TerraformでS3バケットを作成する
AWSマネジメントコンソールでは画面上から設定を入力しますが、Terraformでは設定内容を拡張子が.tfのファイルへ記述します。
1-1. 作業フォルダを作成する
今回の作業では、PC上にTerraform用の作業フォルダを作成し、VS Codeで開きます。
C:\work\Terraform1PowerShellから作成する場合は、次のコマンドを実行します。
cd C:\work
mkdir Terraform1
cd Terraform1
code .code .を実行すると、現在開いているフォルダをVS Codeで開けます。
1-2. main.tfを作成する
作業フォルダの中に、次のファイルを作成します。
main.tfmain.tfに、AWS ProviderとS3バケットの設定を記述します。
provider "aws" {
region = "<自身のリージョン>"
profile = "my-sso"
}
resource "aws_s3_bucket" "my_bucket_02" {
bucket = "ojt-s3-<名前>-02"
tags = {
Name = "My Terraform Bucket"
Environment = "Dev"
}
}各設定の役割は以下のとおりです。
provider "aws"
TerraformがAWSへ接続するための設定
region
AWSリソースを作成する自身のリージョン
profile
AWS CLIで作成したSSOプロファイル
resource "aws_s3_bucket"
S3バケットを作成するための定義
my_bucket_02
Terraform内部でS3バケットを識別するための名前
bucket
AWS上に実際に作成されるS3バケット名S3バケット名は、AWS全体でほかの利用者と重複しない名前にする必要があります。研修で指定された命名規則に従い、
<名前>の部分を自身の名前などへ置き換えてください。1-3. Terraformを初期化する
設定ファイルを作成したら、VS Codeのターミナルで次のコマンドを実行します。
terraform initterraform initは、TerraformがAWSを操作するために必要なAWS Providerなどを準備するコマンドです。
初めてTerraformを実行する場合や、使用するProviderを追加・変更した場合に実行します。
1-4. 作成予定の内容を確認する
次のコマンドを実行し、AWS上でどのような変更が行われるのかを確認します。
terraform planterraform planでは、実際にAWSリソースを変更する前に、作成・変更・削除される内容を確認できます。
S3バケットを1つ作成する場合は、実行結果の最後に次のような内容が表示されます。
Plan: 1 to add, 0 to change, 0 to destroy.1 to add
1個のリソースを作成する
0 to change
変更されるリソースはない
0 to destroy
削除されるリソースはない1-5. S3バケットを作成する
実行計画に問題がなければ、次のコマンドを実行します。
terraform apply実行内容の確認を求められたら、次のように入力します。
yes処理が完了し、次のメッセージが表示されれば作成成功です。
Apply complete!AWSマネジメントコンソールからS3を開き、指定した名前のバケットが作成されていることを確認します。
2. TerraformでEC2インスタンスを作成する
他メンバーがすでにブログで説明を行っているとも思いますが、
Amazon EC2は、AWS上に仮想サーバーを作成できるサービスです。
今回はTerraformを使用してEC2インスタンスを起動し、そのEC2上にApache Webサーバーを構築します。
2-1. ec2.tfを作成する
作業フォルダに、次のファイルを作成します。
ec2.tf最初に、EC2インスタンスの基本設定を記述します。
resource "aws_instance" "my_instance_02" {
ami = "<自身のリージョンに対応したAMI ID>"
instance_type = "t2.micro"
tags = {
Name = "ojt-ec2-<名前>-02"
}
}各設定の役割は以下のとおりです。
aws_instance
EC2インスタンスを作成するリソース
my_instance_02
Terraform内部で使用する識別名
ami
EC2で使用するOSイメージのID
instance_type
EC2のCPUやメモリなどの構成
tags
AWSマネジメントコンソール上で表示する名前AMI IDはリージョンごとに異なります。
providerで設定した自身のリージョンに対応するAMI IDを指定します。2-2. EC2の作成内容を確認する
設定を保存したら、次のコマンドを実行します。
terraform plan実行計画に問題がなければ、次のコマンドを実行します。
terraform apply確認画面でyesを入力します。
処理完了後、AWSマネジメントコンソールのEC2画面で、指定した名前のインスタンスが作成されていることを確認します。
3. EC2上にWebサーバーを構築する
ユーザーデータは、EC2インスタンスの初回起動時に実行する処理を記述する仕組みです。
今回はユーザーデータを使い、ApacheのインストールからHTMLファイルの作成までを自動化します。
実行する処理は以下のとおりです。
1. OSのパッケージを更新する
2. Apacheをインストールする
3. Apacheを起動する
4. EC2起動時にApacheが自動起動するよう設定する
5. index.htmlを作成する3-1. user_dataを追加する
aws_instanceの設定に、次のユーザーデータを追加します。
resource "aws_instance" "my_instance_02" {
ami = "<自身のリージョンに対応したAMI ID>"
instance_type = "t2.micro"
user_data = <<-EOF
#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from Terraform</h1>" > /var/www/html/index.html
EOF
user_data_replace_on_change = true
tags = {
Name = "ojt-ec2-<名前>-02"
}
}それぞれのコマンドは、次の処理を行っています。
dnf update -y
インストール済みパッケージを更新する
dnf install -y httpd
Apacheをインストールする
systemctl start httpd
Apacheを起動する
systemctl enable httpd
EC2の起動時にApacheも自動起動するよう設定する
echo ... > /var/www/html/index.html
ブラウザに表示するHTMLファイルを作成するuser_data_replace_on_change = trueを設定すると、ユーザーデータの変更時にEC2インスタンスを置き換える設定になります。
設定変更後は、再度以下のコマンドを実行します。
terraform plan
terraform apply4. ポート番号を変数として定義する
Terraformでは、複数の場所で使用する値を変数として定義できます。
今回は、Webアクセスで使用するHTTPの80番ポートと、SSH接続で使用する22番ポートを変数として定義します。
4-1. HTTPポートを定義する
variable "http_port" {
description = "The port used for HTTP traffic"
type = number
default = 80
}default = 80によって、HTTP通信で使用する初期値を80番ポートに設定しています。
4-2. SSHポートを定義する
variable "ssh_port" {
description = "The port used for SSH traffic"
type = number
default = 22
}default = 22によって、SSH通信で使用する初期値を22番ポートに設定しています。
4-3. セキュリティグループの受信ルールで変数を使用する
定義した変数を、セキュリティグループの受信ルールで使用します。
resource "aws_security_group" "my_security_group_04" {
name = "ojt-sgp-<名前>-04"
ingress {
from_port = var.http_port
to_port = var.http_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = var.ssh_port
to_port = var.ssh_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}HTTPの受信ルールではvar.http_portを使用し、SSHの受信ルールではvar.ssh_portを使用しています。
cidr_blocks = ["0.0.0.0/0"]は、すべてのIPv4アドレスからの通信を許可する設定です。研修環境のルールや指示に従って設定してください。セキュリティグループを作成しただけではEC2へ適用されないため、EC2側にセキュリティグループを関連付けます。
vpc_security_group_ids = [
aws_security_group.my_security_group_04.id
]設定後、変更内容を確認して反映します。
terraform plan
terraform apply5. EC2のパブリックIPアドレスを出力する
Terraformのoutputを使用すると、作成したリソースが持つ値をターミナルへ表示できます。
今回は、EC2インスタンスのパブリックIPアドレスを出力します。
ec2.tfに次の設定を追加します。
output "public_ip" {
value = aws_instance.my_instance_02.public_ip
description = "The public IP address of the web server"
}設定を反映した後、次のコマンドを実行します。
terraform output public_ip表示されたパブリックIPアドレスを使用して、ブラウザからEC2へアクセスします。
http://<EC2のパブリックIPアドレス>ブラウザ上に次の文字が表示されれば、Webサーバーの構築は成功です。
Hello from TerraformWebページが表示されない場合
Webページが表示されない場合は、次の順番で確認します。
1. EC2がrunningになっているか
2. EC2にパブリックIPが割り当てられているか
3. セキュリティグループで80番ポートが許可されているか
4. Apacheがインストールされているか
5. Apacheが起動しているか
6. /var/www/html/index.htmlが作成されているかブラウザからEC2までの通信経路に沿って確認すると、問題が発生している場所を切り分けやすくなります。
ブラウザ
↓
EC2のパブリックIPアドレス
↓
セキュリティグループの80番ポート
↓
Apache
↓
index.html6. 既存のEC2をTerraformへインポートする
Terraformから新しく作成したリソースだけではなく、すでにAWS上に存在するリソースをTerraformの管理対象へ追加することもできます。
今回は、すでに作成されているEC2インスタンスをTerraformへインポートします。
既存のEC2
↓
Terraformへインポート
↓
Terraformのstateで管理6-1. import.tfを作成する
作業フォルダに、次のファイルを作成します。
import.tfファイル内に、インポート先となるTerraform上のリソース名と、AWS上に存在するEC2のインスタンスIDを記述します。
import {
to = aws_instance.my_instance_01
id = "<既存EC2のインスタンスID>"
}それぞれの項目は以下を表しています。
to
Terraform上で使用するリソース名
id
AWS上に存在するEC2のインスタンスIDインスタンスIDは、AWSマネジメントコンソールのEC2画面から確認します。
6-2. 既存EC2の設定からTerraformコードを生成する
次のコマンドを実行します。
terraform plan -generate-config-out=generated_ec2.tfこのコマンドを実行すると、既存EC2の設定をもとに、次のファイルが生成されます。
generated_ec2.tf生成されたファイルには、AWS上に存在するEC2の設定がTerraformコードとして出力されます。
生成後は、次のような項目を確認します。
・AMI
・インスタンスタイプ
・サブネット
・セキュリティグループ
・タグ
・パブリックIPに関する設定
・意図していない設定が含まれていないか6-3. インポートを適用する
生成された内容を確認したら、次のコマンドを実行します。
terraform apply実行内容を確認し、問題がなければyesを入力します。
処理が完了すると、既存のEC2インスタンスがTerraformの管理対象として登録されます。
6-4. インポート結果を確認する
インポート完了後、次のコマンドを実行します。
terraform planAWS上のEC2とTerraformのコードが一致している場合は、変更がないことを示す内容が表示されます。
No changes.意図していない変更や削除が表示された場合は、
generated_ec2.tfの内容を確認します。7. terraform.tfstateについて
Terraformを実行すると、作業フォルダ内に次のファイルが作成されます。
terraform.tfstateterraform.tfstateには、Terraform上のリソースとAWS上の実際のリソースを対応付ける情報が保存されます。
Terraform上のリソース名
aws_instance.my_instance_02
↕ 対応付け
AWS上のEC2インスタンスID
i-xxxxxxxxxxxxxxxxxTerraformは、この情報を使用して、次回のterraform plan実行時に変更の有無を判断します。
terraform.tfstateを直接編集すると、TerraformがAWSリソースの状態を正しく判断できなくなる可能性があるため、基本的には手動で編集せず、Terraformのコマンドを通して管理します。8. 作成したAWSリソースを削除する
Terraformで作成したAWSリソースを削除する場合は、次のコマンドを実行します。
terraform destroy削除予定のリソースが表示されるため、内容を確認します。
問題がなければ、次のように入力します。
yes既存のEC2をインポートして同じTerraform構成で管理している場合、そのEC2も
terraform destroyの削除対象として表示される可能性があります。実行前に、削除対象を必ず確認しましょう。作業終了後は、AWSマネジメントコンソールでもS3やEC2が削除されていることを確認します。
Terraformで発生しやすい問題・その対処法
AWSの認証エラーが表示される
SSOのログイン情報が有効でない場合は、次のコマンドを実行します。
aws sso login --profile my-ssoPowerShellでは、環境変数に設定されているプロファイルも確認します。
$env:AWS_PROFILEAMIが見つからない
AWS Providerに設定したリージョンと、EC2で指定したAMI IDが一致しているか確認します。
provider "aws" {
region = "<自身のリージョン>"
}S3バケットを作成できない
指定したS3バケット名が、すでにほかのAWS利用者に使われている可能性があります。
バケット名を重複しにくい名前へ変更し、再度以下のコマンドを実行します。
terraform plan
terraform applyWebページへアクセスできない
次の通信経路に沿って確認します。
ブラウザ
↓
EC2のパブリックIPアドレス
↓
セキュリティグループ
↓
Apache
↓
index.htmlまとめ
今回の記事では、Terraformを使用してAWSリソースをコードから管理する方法、手順を記載しました。
今回実施した内容は以下のとおりです。
・AWS CLIでSSO認証を設定
・Terraformの作業フォルダを作成
・terraform initによる初期化
・S3バケットの作成
・terraform planによる変更内容の確認
・terraform applyによるAWSへの反映
・EC2インスタンスの作成
・ユーザーデータによるApacheの自動構築
・変数を利用したHTTP・SSHポートの管理
・outputを利用したパブリックIPの確認
・既存EC2インスタンスのインポート
・terraform.tfstateによる状態管理
・terraform destroyによるリソースの削除Terraformでは、コードを作成してすぐにAWSへ反映するのではなく、次の流れで作業することが重要です。
コードを記述する
↓
terraform initで必要な機能を準備する
↓
terraform planで変更内容を確認する
↓
terraform applyでAWSへ反映する
↓
terraform.tfstateで状態を管理するまた、AWSマネジメントコンソールから作成した既存リソースについても、インポート機能を使用することでTerraformの管理対象へ追加できます。
一方で、TerraformのコードとAWS上の実際の状態に差がある場合、意図していない変更や削除が発生する可能性があります。
特にterraform applyとterraform destroyを実行する前には、表示された実行計画を確認することが重要です。
参考にした記事
今回のTerraformを使ったAWSリソースの構築にあたり、以下の記事と公式ドキュメントを参考にしました。
「HashiCorp公式のTerraformチュートリアル(AWS)をやってみた」
https://dev.classmethod.jp/articles/hashicorp-terraform-tutorial-aws/
「TerraformでAWSのIaCを始める・始めたばかりの人へ」
https://dev.classmethod.jp/articles/for-terraform-newbies-devio2024/
「AWS SSO ProfileをTerraformで使う」
https://dev.classmethod.jp/articles/using-terraform-with-sso-profile/
「TerraformのStateファイル(tfstate)管理方法の比較とTerraform Cloudをおすすめしたい理由」
https://dev.classmethod.jp/articles/terraform_tfstate_management_tfc/
同じカテゴリーの記事
同じカテゴリの記事を読む