はじめに
この記事ではIaC(Infrastructure as Code) ツールである Terraform を用いて、AWSによるインフラ構築を行うための事前準備について解説します。
前提環境
- Windows11
- WSL2( Ubuntu24.04 )
- AWSアカウント・IAMユーザー作成済み(MFA設定済み)
- Bugetsにて予算の設定済み
記事の内容
- IaC(Infrastructire as Code)とは
- Terraformとは
- AWS CLIのセットアップ
- ディレクトリの準備
- Terraformのインストール
- State管理・ロック用のS3バケット作成
IaC (Infrastructure as Code)とは
IaC は、サーバー・ネットワーク・データベースといったインフラの構成を、手作業ではなくコード(設定ファイル)で定義・管理する手法です。
従来のようにGUIでポチポチ操作して1つずつリソースを立ち上げたり、サーバーに SSH でログインしてコマンドを叩いたりする代わりに、インフラの「あるべき姿」をテキストファイルに記述します。
IaC のメリット
- 再現性 — 同じコードから、同じ構成の環境(開発・検証・本番)を何度でも作れる
- バージョン管理 — Git で変更履歴を残せ、誰がいつ何を変えたか追える。レビューやロールバックも可能
- 自動化 — 手作業のミスを減らし、構築・変更を高速に行える
- ドキュメント化 — コード自体が「現在のインフラ構成」を示すドキュメントになる
Terraform とは
Terraform は HashiCorp 社が開発した、代表的な IaC ツールです。AWS・Azure・Google Cloud をはじめ、多数のクラウド・サービスに対応しています。
特徴
- 宣言的(Declarative) — 「どうやって作るか(手順)」ではなく「最終的にどうあってほしいか(状態)」を記述する。差分は Terraform が自動で計算してくれる
- マルチクラウド対応 — 「プロバイダー」というプラグインを通じて、複数のクラウドを共通の書き方で扱える
- HCL — HashiCorp Configuration Language という専用の記述言語を使う(読み書きしやすい)
-
状態管理(State) — 現在のインフラ状態を
terraform.tfstateというファイルで管理し、コードとの差分を把握する
基本的なワークフロー
-
書く —
.tfファイルにインフラ構成を記述 -
terraform init— プロバイダーなどを初期化 -
terraform plan— 何が作成・変更・削除されるか事前に確認(差分表示) -
terraform apply— 実際にインフラへ反映 -
terraform destroy— 不要になったら一括削除
AWS CLIのセットアップ
なぜCLIが必要か
- 稼働中のリソースを確認する際、CLIからも確認できる
- state管理・ロックをする
S3を手作業で立ち上げる際にCLIを使用する(コンソールからでも可) - Terraformを使うときにAWS CLIの認証情報を流用して、IAMユーザーへアクセスするため
AWS CLIをインストール
WSL2のUbuntuターミナルで以下を実行
# 既存確認
which aws
# unzipの確認
unzip --version
# unzipが無ければ
sudo apt update && sudo apt install -y unzip
# 公式インストーラをダウンロード
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# 解凍してインストール
unzip awscliv2.zip
sudo ./aws/install
# 確認
aws --version
# → aws-cli/2.x.x ...のような出力が出たらOK
# インストーラを削除
rm -rf aws awscliv2.zip
IAMユーザーのアクセスキー発行と設定
CLIから操作するにはIAMユーザーのアクセスキー(プログラム用の鍵)が必要。
本来は IAM Identity Center や OIDC が推奨だが、最初の一歩としては見やすいアクセスキー方式で進める。
アクセスキー発行手順
- IAMユーザーでログイン
- 右上のユーザー名 → 「セキュリティ認証情報」
- 下にスクロール → 「アクセスキー」 → 「アクセスキーを作成」
- ユースケース: 「コマンドラインインターフェイス (CLI)」
- 確認チェックボックスにチェック → 「次へ」
- 説明タグ(任意):
wsl2-localなど - 「アクセスキーを作成」
-
シークレットアクセスキーはこの画面でしか表示されない
「.csvファイルをダウンロード」推奨
AWS CLIでIAMユーザーに接続
WSL2ターミナルで
aws configure
# 対話形式で以下を入力
AWS Access Key ID [None]: #さっき作ったアクセスキーID
AWS Secret Access Key [None]: #さっき作ったシークレットキーID
Default region name [None]: ap-northeast-1 #東京リージョン
Default output format [None]: json
動作確認
aws sts get-caller-identity
# 期待する出力
{
"UserId": "自分のID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/admin"
}
Arn の末尾が :user/admin(作ったIAMユーザー名)であることを確認。
:root ならルートのキーを使っているのでやり直し。
アクセスキーの取り扱い注意
aws configure で入力した内容は ~/.aws/credentials に平文で保存される:
# 確認
cat ~/.aws/credentials
Gitへの混入事故を防ぐ
-
.gitignoreに必ず.aws/や*.pem、.envを含める - 公開リポジトリにアクセスキーを置くと 数分で発見されて不正利用される
(GitHubをスキャンするbotがいる) - 万一漏れたら:
- IAM コンソール → そのキーを「非アクティブ化」
- 削除
- CloudTrailで不正利用がないか確認
ディレクトリを準備する
今回はIaCによるAWSでのインフラ構築が本筋なので、Laravelなどで環境構築をしただけのプロジェクト(例:my-app)を用意。(環境構築の手順に関しては今回は解説しません)
- ルートディレクトリ
my-appの直下に/infraを作成wslcd ~/my-app # アプリのルートへ mkdir infra cd infra
- 先に
.gitignoreを作成しておく
機密情報をうっかりコミットする事故を防ぐのが最優先wsl# CLIで作成する場合は以下(IDEから作成しても良い) cat > .gitignore \ << 'EOF' # Terraformが落としてくるプロバイダ等(巨大、再取得可能) .terraform/ .terraform.lock.hcl # stateファイル(DBパスワード等が平文で入る。絶対に上げない) *.tfstate *.tfstate.* # 変数の実値(パスワード等を入れる) *.tfvars *.tfvars.json # クラッシュログ crash.log EOF-
.terraform/ — terraform init時にAWSプロバイダのプラグイン(数百MB)がここに落ちてくる(再取得できるのでGit不要) -
.terraform.lock.hcl— これは逆にコミットすべきという意見も多い(プロバイダのバージョンを固定する依存ロックファイル)ただ個人学習では一旦無視でOK -
*.tfstate*— これが一番大事でstateにはRDSのパスワードなどが平文で記録される(GitHubに上げたら一発アウト) -
*.tfvars— 後でDBパスワードを書くファイル(これも平文なので除外)
-
Terraformをインストール
HashiCorp公式のaptリポジトリを使う
WSLのパッケージマネージャーでバージョン管理が容易なため
# 1. HashiCorpのGPG鍵を登録(パッケージが本物だと検証するため)
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
# 2. リポジトリを追加
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
# 3. インストール
sudo apt update && sudo apt install terraform
# 4. 確認
terraform -version
最後の terraform -version で 1.11以上が出ればOK(use_lockfile を使うのに1.11以上が必要)
TerraformはAWSへの接続に鍵の作成はおこなわず、AWS CLIと同じ認証情報(~/.aws/credentials)を自動で使うため以下のコマンドでaws CLIが使えるかも再度確認しておく
aws sts get-caller-identity
# 自分のIAMユーザーのARNが返ればOK
S3によるstateの管理・ロックについて
Terraformは自分が作ったリソースをstate(状態)として記録し、terraform apply(リソース生成コマンド)実行時には、最新のstateとの差分を生成する
なぜローカルではなくS3で管理するのか?
このstateをS3(Amazon Simple Storage Service) で管理することで以下のようなメリットがある
- 常に最新のインフラ状態をチーム全体で共有できる
-
.tflockファイルによる状態のロック機能(競合防止)複数人が同時にterraform applyを実行して競合するのを防ぐ - バージョニング機能を有効にすることで、誤ってリソースを削除してしまったり、Stateファイルが破損してしまった場合でも、過去の状態に簡単にロールバック(復元)可能
- Amazon S3は99.999999999%のデータ耐久性を誇り、ファイル消失のリスクが極めて低い
S3での管理はTerraformの公式ドキュメントでも推奨されているベストプラクティスである
S3バケットを作成する
-
リージョンを
アジアパシフィック(東京)に変更 -
コンソールからS3を検索
-
「汎用バケット」→「バケットを作成」
-
以下のように設定
設定項目 何を選ぶか:理由 バケットタイプ 汎用:
標準のS3 もう一方の「ディレクト」は超低レイテンシ用途の特殊なやつで、state保存には不要バケット名前空間 アカウントのリージョナル名前空間:
バケット名は全世界で一意でなければならず、この設定は自動でアカウントIDを末尾に足す
例:my-app-tfstate-123456789-ap-northeast-1-cバケット名 任意の名前:
例my-app-tfstateなど、分かりやすくオブジェクト所有者 ACL無効:
簡単に言うと自身のアカウントでしかバケットや中身にアクセスできないようにするブロックパブリックアクセス設定 パブリックアクセスをすべてブロック:
stateにはパスワードが入るので、間違っても公開されないよう全ブロックバケットのバージョニング 有効:
これは必須
stateが壊れたり誤って上書きされたとき、過去バージョンに巻き戻せる以降の設定 デフォルトのままでOK -
「バケットを作成」
AWS CLIを使用した場合
#==========================================
# 自分のAWSアカウントIDを取得
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
#==========================================
# 変数に入れておく(以降のコマンドで使い回す)
BUCKET="fameal-tfstate-${ACCOUNT_ID}"
REGION="ap-northeast-1"
echo "$BUCKET" # 確認。fameal-tfstate-123456789012 のように出る
#==========================================
# バケットを作成
aws s3api create-bucket \
--bucket "$BUCKET" \
--region "$REGION" \
--create-bucket-configuration LocationConstraint="$REGION"
#==========================================
# バージョニングを有効化
aws s3api put-bucket-versioning \
--bucket "$BUCKET" \
--versioning-configuration Status=Enabled
#==========================================
# パブリックアクセスを全ブロック
aws s3api put-public-access-block \
--bucket "$BUCKET" \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
#==========================================
# 省略可能だが年の為、デフォルト暗号化を明示(SSE-S3)
aws s3api put-bucket-encryption \
--bucket "$BUCKET" \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256" },
"BucketKeyEnabled": true
}]
}'
#==========================================
# 確認
aws s3api get-bucket-versioning --bucket "$BUCKET"
# → { "Status": "Enabled" } が返ればOK
aws s3api get-public-access-block --bucket "$BUCKET"
# → 4つとも true が返ればOK
aws s3api get-bucket-encryption --bucket "$BUCKET"
# → AES256 が返ればOK
#==========================================
さいごに
今回はTerraformを用いてAWSによるインフラ構築をするための、AWS CLIセットアップ・Terraformインストール・State管理の準備行いました!
次回は実際にTerraformで簡単なインフラ構築をやってみたいと思います。
ご覧いただきありがとうございました🔥