5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

terraform初学者がAWSリソースをデプロイする 前編

5
Last updated at Posted at 2025-12-14

開発環境

  • OS:Windows 11
    • WSL2(Ubuntu 24.04.3 LTS)
  • Terraform:v1.14.2
  • AWS CLI:v2

1. はじめに

雰囲気で使えている気分になっているterraformについて、ちゃんと学んでみようという記事です。

この記事では S3,EC2,Lambda の作成、実務っぽい管理を実施していきます:hammer_pick:

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 の基本的な操作は、以下のコマンドで行われます。

  1. terraform init
    Terraform環境の初期化を行い、provider などのプラグインをダウンロードする

  2. terraform plan
    これから作成・変更されるリソースを確認する

  3. terraform apply
    plan の内容を実際に反映し、AWSリソースを作成する

  4. terraform destroy
    作成したリソースを削除する。
    (環境を片付ける際によく使います)

3. 事前準備

Terraform を実際に動かすために、WSL, AWS CLI, Terraform の実行環境を整えます。

3-1. WSL(Ubuntu)の準備

WSLの準備は、以下の3手順です。

  1. インストール (+再起動)
  2. ユーザ作成
  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 コンソールから以下を作成します。

  1. IAM → ユーザー

  2. 新規ユーザー作成

  3. プログラムによるアクセスを許可
    個人の学習用途なので、AdministratorAccessを設定
    ※実務では細かい権限分離を行うことが推奨されます!
    image.png

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

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 にまとめています。

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>" { ... }

main.tf
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 とあり、作成されるリソースの数を示しています。

image.png

4-3. terraform apply で S3 バケットを作成

問題なければ、terraform apply を実行します。

terraform apply

確認メッセージが表示されるので、yes を入力します。
処理が完了し、S3 バケットが AWS 上に作成されているのを確認できれば成功です!

  • AWS マネジメントコンソールのS3画面

image.png

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 に追記する

参考

5-2. VPC設定(data source)

AWS にあらかじめ用意されているデフォルト VPC を参照します。
data ブロックは、すでに存在する AWS リソースを参照するために使います。

main.tf
# デフォルト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)ルールは設定しません。

main.tf
# セキュリティグループ設定
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 ロールを割り当てます。

main.tf
# 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 パラメータから取得します。

main.tf
# SSMパラメータ設定(公式から参照)
data "aws_ssm_parameter" "al2023_ami" {
  name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"
}

5-6. EC2インスタンス設定

最後に、EC2 インスタンスを作成します。

main.tf
# 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 のインスタンスが起動していることを確認できたら成功です!

※画面のスクショ撮る前にリソース削除してしまったため、画像無しです:cry:

6. Lambda作成

リソース作成として最後に、AWS Lambda 関数を作成します。

4〜5章では、S3 や EC2 のような「インフラ(構成要素)」を Terraform で作成しました。
一方 Lambda は、コードを AWS 上にデプロイして動かす「実行リソース」です。

Terraform がインフラだけでなく、アプリケーションコード(デプロイ物)を含むリソースも管理できるのを Lambda の作成で確認します。

6-1. Lambda のコード作成

Lambdaコード用のディレクトリを作成、index.pyを作成します。

mkdir -p lambda
lambda/index.py
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.tfterraform.required_providers ブロックに archive を追記する

main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    # 追加
    archive = {
      source  = "hashicorp/archive"
      version = "~> 2.0"
    }
  }
}

main.tf に zip生成設定を追加します。

main.tf
# 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 に出力するための基本権限を付与します。

main.tf
# 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 関数を作成します。

main.tf
# 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 が作成されていれば成功です!

image.png

※テスト実行すれば、"Hello from Terraform Lambda!" が出力される
image.png

7. まとめ・次にやること

1記事にまとめる予定だったんですが、構成整理やState管理まで含めるとあまりに長いので、前後編とすることにしました。(書くのもしんどい

前編では、Terraform を使って AWS リソースを作成する一連の流れを、環境構築から実際のデプロイまで段階的に確認しました。

ここまででは、以下を理解するのを目的としています。

  1. Terraform の基本的なコマンドと実行フローを理解する
  2. AWS の主要なリソース(S3 / EC2 / Lambda)を Terraform で定義・デプロイ
  3. インフラだけでなく、実行コードを含むリソースも Terraform で扱える(Lambda)

一方で、この時点ではすべての設定を main.tf に記述しており、実務的には構成として整理が必要な状態です:frowning2:
普通に読みづらいし、、、

なので後編では、以下のような題材で実務に近い運用を説明します。

  • Terraform の構成整理(ファイル分割・変数化)
  • state 管理

では、後編に続く。。。


後編:coming soon

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?