開発環境
- OS:Windows 11
- WSL2(Ubuntu 24.04.3 LTS)
- Terraform:v1.14.2
- AWS CLI:v2
1. はじめに
雰囲気で使えている気分になっているterraformについて、ちゃんと学んでみようという記事です。
この記事では S3,EC2,Lambda の作成、実務っぽい管理を実施していきます![]()
2. Terraformとは
Terraformは、HashiCorp社が開発したオープンソースのIaCツールです。
設定ファイルは HCL(HashiCorp Configuration Language) という形式で記述します。
Terraformの設定は、次の3つの概念を理解しておくとイメージ付きやすい(かも)
-
provider
AWS・GCP・GitHubなど、どのサービスに対して操作するかを定義するもの。
(この記事では AWS provider を利用します) -
resource
Terraformが作成・変更・削除する対象。
例:aws_s3_bucket(S3バケット)、aws_lambda_function(Lambda関数)など -
state
Terraform が「どのリソースがすでに作られているか」を管理するための情報。
これをもとに差分管理を行います。(詳細は後編で説明)
Terraform の基本的な操作は、以下のコマンドで行われます。
-
terraform init
Terraform環境の初期化を行い、provider などのプラグインをダウンロードする -
terraform plan
これから作成・変更されるリソースを確認する -
terraform apply
plan の内容を実際に反映し、AWSリソースを作成する -
terraform destroy
作成したリソースを削除する。
(環境を片付ける際によく使います)
3. 事前準備
Terraform を実際に動かすために、WSL, AWS CLI, Terraform の実行環境を整えます。
3-1. WSL(Ubuntu)の準備
WSLの準備は、以下の3手順です。
- インストール (+再起動)
- ユーザ作成
- 必要なパッケージのインストール
※WSL準備以降の作業はすべてWSL内で実施してください。
- インストール + 再起動
wsl --install
- ユーザ作成
wsl # wsl初回起動時にユーザー・パスワードの登録
- 必要なパッケージのインストール
sudo apt update && sudo apt upgrade -y
sudo apt install -y unzip curl gnupg
参考:https://learn.microsoft.com/ja-jp/windows/wsl/install
3-2-1. AWS アカウント / IAMユーザーの準備
AWS を操作するために、Terraform が利用する IAM ユーザーのアクセスキーを用意します。
※アカウント作成:https://aws.amazon.com/jp/register-flow/
AWS コンソールから以下を作成します。
-
IAM → ユーザー
-
新規ユーザー作成
-
プログラムによるアクセスを許可
個人の学習用途なので、AdministratorAccessを設定
※実務では細かい権限分離を行うことが推奨されます!

-
アクセスキーを発行(後で AWS CLI に設定します)
作成したIAMユーザーのアクセスキーを発行して、アクセスキー・シークレットアクセスキーをメモします。

3-2-2 AWS CLIの準備
- AWS CLI v2 インストール
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# インストール後確認
aws --version
IAMユーザーで発行したアクセスキーを設定
- 設定例
- AWS Access Key ID:メモしたアクセスキー
- AWS Secret Access Key:メモしたシークレットアクセスキー
- Default region name:ap-northeast-1
- Default output format:json
aws configure
- 設定確認
aws sts get-caller-identity
# 出力例
{
"UserId": "xxxxxxxxxx",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/test_user"
}
参考:https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
3-3. Terraformの準備
HashiCorp公式リポジトリ利用準備
# HashiCorp の GPGキーをインストール
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
# GPG キーのフィンガープリントを検証する
gpg --no-default-keyring \
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
--fingerprint
# HashiCorp リポジトリをシステムに追加
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
- インストール
sudo apt update
sudo apt-get install terraform
参考:https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
手順のコマンドでは、公式HashiCorpであるかの公開鍵検証・APIへ配布場所の登録を行っています。
3-4. 作業ディレクトリの作成
Terraform 用のディレクトリをWSL内に作成します。
# WSLに移動
cd ~
pwd
# /home/<user>
mkdir -p ~/terraform-tutorial
cd ~/terraform-tutorial
本記事は WSL 上の Linux ファイルシステム(/home/<user>)での作業を推奨です。
Terraform はファイルアクセスが多く、/mnt/c 配下では動作が遅くなったり、
権限周りのトラブルが発生することがあるためです。
main.tfを作成
※ Terraform の設定(terraform {} ブロック)は、 terraform.tf など別ファイルに分けることが多いですが、前編では理解しやすさのため、main.tf にまとめています。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.92"
}
}
required_version = ">= 1.2"
}
provider "aws" {
region = "ap-northeast-1"
}
- 初期化
terraform has been successfully initialized! と出力されたらOK
terraform init
参考:https://developer.hashicorp.com/terraform/tutorials/aws-get-started/aws-create
4. はじめてのリソース作成(S3)
長い準備お疲れ様でした、ようやく本題に入ります!
まずは Terraform を使って AWS S3 バケットを 1 つ作成します。
S3 を選んだ理由としては、ネットワーク設定や IAM の依存が少なく、
Terraform の resource を理解することに集中しやすいためです。
4-1. S3 の resource を記述する
先ほど作成したmain.tfに追記していきます。
resourceは、以下のような形式で記述します。
resource "<provider>_<resource_type>" "<name>" { ... }
resource "aws_s3_bucket" "terraform_sample" {
bucket = "terraform-sample-bucket-xxxxxx"
}
-
aws_s3_bucket:AWS の S3 バケット、とprovider, resource_typeを設定 -
terraform_sample:Terraform 内で参照するための名前
S3 バケット名("terraform-sample-bucket-xxxxxx")は、AWS 全体で一意である必要があります。
記事中の例をそのまま使うとエラーになるため、自分の名前・ランダムな文字列などを含めるようにしてください。
4-2 terraform plan で差分確認
リソースの設定が終わったので、次に、terraform plan を実行し、作成されるリソースを確認します。
terraform plan
出力は以下のような感じで、「これから作成するリソース」が表示されます。
※Plan: 1 to add とあり、作成されるリソースの数を示しています。
4-3. terraform apply で S3 バケットを作成
問題なければ、terraform apply を実行します。
terraform apply
確認メッセージが表示されるので、yes を入力します。
処理が完了し、S3 バケットが AWS 上に作成されているのを確認できれば成功です!
- AWS マネジメントコンソールのS3画面
5. EC2 作成
次に、Terraform を使って EC2 インスタンスを 1 台作成します。
EC2 はネットワークや IAM など複数の AWS リソースと関係するため、
Terraform でどのように組み合わせて構成するかを EC2の作成で確認していきます。
本章で作成する EC2 は起動している間、従量課金が発生します。
学習が終わったら、必ず terraform destroy を実行してください。
そもそもEC2とは?
EC2とは?
Amazon EC2(Elastic Compute Cloud)は、AWSが提供する仮想サーバーサービスです。
クラウド上でアプリケーションを実行するためのコンピューティングリソースを提供する。
ES2は、以下の要素で構成されます:
- AMI(Amazon Machine Image):OSや初期設定を含むテンプレート
- インスタンスタイプ:CPU・メモリなどのスペック(例:t3.micro)
- ネットワーク設定:VPC、サブネット、セキュリティグループ
- IAMロール:AWSサービスへのアクセス権限
- ストレージ:ルートボリューム(暗号化推奨)
AWS公式:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/concepts.html
5-1. EC2の作成方針
学習用途ですが、セキュリティに最低限配慮して以下の方針で作成します。
- 既存のデフォルト VPC を利用する
- SSH は利用せず、Session Manager(SSM)で接続する
- インターネットからの受信通信は許可しない
- EC2も
main.tfに追記する
参考
- Terraform公式
https://developer.hashicorp.com/terraform/tutorials/aws-get-started/aws-create - AWS公式
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html
5-2. VPC設定(data source)
AWS にあらかじめ用意されているデフォルト VPC を参照します。
data ブロックは、すでに存在する AWS リソースを参照するために使います。
# デフォルトVPC設定
data "aws_vpc" "default" {
default = true
}
data "aws_subnets" "default" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
5-3. セキュリティグループ設定
EC2 に適用するセキュリティグループを作成します。
※SSH を利用しないため、受信(ingress)ルールは設定しません。
# セキュリティグループ設定
resource "aws_security_group" "ec2_sg" {
name = "terraform-ec2-sg"
description = "Security group for Terraform EC2 (no inbound)"
vpc_id = data.aws_vpc.default.id
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
5-4. EC2 用 IAM ロール設定(SSM 接続用)
Session Manager を利用するため、EC2 に IAM ロールを割り当てます。
# EC2用IAMロール設定
resource "aws_iam_role" "ec2_role" {
name = "terraform-ec2-ssm-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ec2.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "ssm_core" {
role = aws_iam_role.ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_instance_profile" "ec2_profile" {
name = "terraform-ec2-ssm-profile"
role = aws_iam_role.ec2_role.name
}
5-5. AMI設定
EC2 に利用する AMI は、AWS が管理している SSM パラメータから取得します。
# SSMパラメータ設定(公式から参照)
data "aws_ssm_parameter" "al2023_ami" {
name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}
5-6. EC2インスタンス設定
最後に、EC2 インスタンスを作成します。
# EC2設定
resource "aws_instance" "terraform_ec2" {
ami = data.aws_ssm_parameter.al2023_ami.value
instance_type = "t3.micro"
subnet_id = data.aws_subnets.default.ids[0]
vpc_security_group_ids = [aws_security_group.ec2_sg.id]
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
metadata_options {
http_tokens = "required"
}
root_block_device {
encrypted = true
delete_on_termination = true
}
tags = {
Name = "terraform-ec2-sample"
}
}
5-7. terraform plan / apply
terraform plan で EC2 の構成を確認
以下5つが作成されることを確認してください。
- EC2 インスタンス
- セキュリティグループ
- IAM ロール
- IAM ロールポリシーアタッチメント
- IAM インスタンスプロファイル
terraform applyでEC2を作成・起動
S3 の時と同じ感じになればOK
AWS マネジメントコンソールの EC2 画面
Name=terraform-ec2-sample のインスタンスが起動していることを確認できたら成功です!
※画面のスクショ撮る前にリソース削除してしまったため、画像無しです![]()
6. Lambda作成
リソース作成として最後に、AWS Lambda 関数を作成します。
4〜5章では、S3 や EC2 のような「インフラ(構成要素)」を Terraform で作成しました。
一方 Lambda は、コードを AWS 上にデプロイして動かす「実行リソース」です。
Terraform がインフラだけでなく、アプリケーションコード(デプロイ物)を含むリソースも管理できるのを Lambda の作成で確認します。
6-1. Lambda のコード作成
Lambdaコード用のディレクトリを作成、index.pyを作成します。
mkdir -p lambda
def handler(event, context):
return {
"statusCode": 200,
"body": "Hello from Terraform Lambda!"
}
6-2. archive_file 設定(Lambda zip自動生成)
Lambda はデプロイ単位として zip(またはコンテナイメージ)が必要です。
この記事では、Terraform の archive_file 設定を使って zip を自動生成し、
手作業で zip を作らないで済むようにしています。
main.tfの terraform.required_providers ブロックに archive を追記する
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
# 追加
archive = {
source = "hashicorp/archive"
version = "~> 2.0"
}
}
}
main.tf に zip生成設定を追加します。
# zip生成設定
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "${path.module}/lambda"
output_path = "${path.module}/lambda.zip"
}
6-3. Lambda 実行用 IAM ロール設定
Lambda 関数は実行時に IAM ロールが必須です。
まずは CloudWatch Logs に出力するための基本権限を付与します。
# Lambda用IAM設定
resource "aws_iam_role" "lambda_role" {
name = "terraform-lambda-exec-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "lambda_basic" {
role = aws_iam_role.lambda_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
6-4. Lambda 設定
作成した zip, IAM 設定を指定して、Lambda 関数を作成します。
# lambda 設定
resource "aws_lambda_function" "terraform_lambda" {
function_name = "terraform-sample-lambda"
role = aws_iam_role.lambda_role.arn
handler = "index.handler"
runtime = "python3.11"
timeout = 10
filename = data.archive_file.lambda_zip.output_path
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
}
source_code_hash を指定することで、コードが更新された際に Terraform が差分を検知できるようになります。
6-5. terraform plan / apply
今回は、archive プロバイダを追加したため、terraform init は再実行します。
terraform init
terraform plan
terraform apply
AWS マネジメントコンソールの Lambda 画面
terraform-sample-lambda が作成されていれば成功です!
※テスト実行すれば、"Hello from Terraform Lambda!" が出力される

7. まとめ・次にやること
1記事にまとめる予定だったんですが、構成整理やState管理まで含めるとあまりに長いので、前後編とすることにしました。(書くのもしんどい)
前編では、Terraform を使って AWS リソースを作成する一連の流れを、環境構築から実際のデプロイまで段階的に確認しました。
ここまででは、以下を理解するのを目的としています。
- Terraform の基本的なコマンドと実行フローを理解する
- AWS の主要なリソース(S3 / EC2 / Lambda)を Terraform で定義・デプロイ
- インフラだけでなく、実行コードを含むリソースも Terraform で扱える(Lambda)
一方で、この時点ではすべての設定を main.tf に記述しており、実務的には構成として整理が必要な状態です![]()
(普通に読みづらいし、、、)
なので後編では、以下のような題材で実務に近い運用を説明します。
- Terraform の構成整理(ファイル分割・変数化)
- state 管理
では、後編に続く。。。
後編:coming soon


