1. はじめに
オンプレ歴5年以上のサーバ・NW インフラエンジニアです。(クラウド未経験)
AWS構築におけるIaC 化 (自動化)について記述していきます。
現現場ではオンプレミスや仮想サーバが1システム100台前後あるため、 Ansible を用いて構成管理を行ってます。
これにより、手作業によるパラメータミスや環境差分を防ぎ、どのサーバにも均等かつ確実に設定を入れる自動化を進めてきました。
配布元を直せば一瞬で複数台サーバに展開できます。
さて以前のAWSハンズオンでは AWS コンソールからの手動操作でサーバーレス環境を構築し、設計の基礎を学びました。
AWSにもTerraformという構成管理ツールがあります。
一度手動で構築したサーバーレス構成を 100% コード化し、デプロイまで完全自動化する構成を作ってみたいと思い、実際にTerraform を用いてやってみました。
2. Terraform とは何か
Terraform は HashiCorp 社が開発した「インフラのプロビジョニング(リソース作成)」に特化した宣言型の IaC ツールです。
AWS の S3・Lambda・API Gateway といったクラウドのリソースそのものを API 経由でゼロから定義・生成・破棄することを得意としています。
またマルチクラウド対応となっており、Azure, GCP, Datadog などといった他クラウドにも応用できます。
Terraform は.tf ファイルにやりたいことを書きます。
ファイル名は任意で、展開時はディレクトリ内のすべての .tf ファイルを合算して読み込みます。
一例として、以下はS3にindex.htmlを配置するコードです。
なんとなくなにをするコードなのか、読みやすいと感じました。
# S3 バケットの作成
resource "aws_s3_bucket" "frontend" {
bucket = "my-portfolio-frontend-bucket-12345"
}
# index.html のアップロード
resource "aws_s3_object" "index_html" {
bucket = aws_s3_bucket.frontend.id
key = "index.html"
source = "${path.module}/../frontend/index.html"
content_type = "text/html"
etag = filemd5("${path.module}/../frontend/index.html")
}
他にもAWS系のIaC ツールとして、AWS CDK もありますが、こちらはTypeScript や Python などの「プログラミング言語で抽象化して書く」アプローチを取ります。
以下はAWS CDKで先ほどと同じく、S3にindex.htmlを配置するコードです。
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
import { Construct } from 'constructs';
import * as path from 'path';
export class MyFrontendStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 1. S3 バケットの作成
const bucket = new s3.Bucket(this, 'FrontendBucket', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
// 2. ローカルフォルダ(frontend)から S3 への自動デプロイ
new s3deploy.BucketDeployment(this, 'DeployWebsite', {
sources: [s3deploy.Source.asset(path.join(__dirname, '../frontend'))],
destinationBucket: bucket,
});
}
}
いやー読みづらいですね。(;'∀')
オンプレで Ansible などの構成管理ツールに触れてきた私にとっては、インフラの構造がコードの見た目通りに直感的に把握できる Terraform の方が親しみやすいと感じましたので今回はTerraformをつかって IaC 化してみます。
3. Terraformを使用するにあたって必要な準備
今回、Windows環境にてTerraformを使った構築を進めるにあたり、以下の準備を行いました。
(1) 事前準備・前提条件
-
AWS CLI のインストールと認証情報の設定
Terraform が AWS API を操作するために、ローカル端末に AWS CLI を導入し、事前にアクセスキーをセットしておきます。AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY-
AWS_DEFAULT_REGION(例:ap-northeast-1)
💡 ポイント:
.tfコード内にアクセスキーを直書きすると GitHub 公開時などに重大なインシデントに繋がるため、必ずaws configureや環境変数経由で認証情報を読み込ませます。
上記、AWS CLI 設定しない場合は、ターミナルで環境変数を一時設定することも可能です。
set AWS_ACCESS_KEY_ID=取得したアクセスキーID
set AWS_SECRET_ACCESS_KEY=取得したシークレットアクセスキー
set AWS_DEFAULT_REGION=ap-northeast-1
terraform plan
(2) Terraform のインストール(ポータブル利用手順)
今回は環境依存を減らし、手軽にセットアップできる**ポータブル版(zip解凍配置)**の手順を採用しました。
-
ZIPファイルのダウンロード
Terraform 公式ダウンロードページ から Windows 用の executable ZIP ファイルをダウンロードします。 -
任意のフォルダへ配置
ZIPを解凍し、中にあるterraform.exeを任意のディレクトリ(例:C:\terraform\やプロジェクト用フォルダ)へ配置します。 -
環境変数(PATH)の通し込み
コマンドプロンプトや PowerShell のどこからでも呼び出せるよう、terraform.exeを配置したフォルダのパスをシステムの「環境変数 (PATH)」に追加します。
バージョン確認:
ターミナルで以下のコマンドを実行し、バージョンが表示されればセットアップ完了です。
terraform -v
# 例: Terraform v1.x.x
4. 本プロジェクトのディレクトリ構成
Terraformでデプロイするために、Windows環境にてディレクトリ・ファイルを作成しました。
今回構築した環境の全コード(Terraform / HTML / Python)は、以下の GitHub リポジトリで公開しています。
- GitHub リポジトリ: finestar43/aws-terraform-form-portfolio
インフラコード(terraform/)とバックエンド(backend/)、フロントエンド資材(frontend/)を明確に分け、保守しやすい構成に設計しました。
https://github.com/finestar43/aws-terraform-form-portfolio
.
├── backend/
│ └── src/ # Lambda バックエンド処理 (Python)
│ ├── submit/index.py # 問い合わせ登録処理 (ユーザー用)
│ └── admin/index.py # 問い合わせ一覧取得処理 (管理者用)
├── frontend/
│ ├── index.html # お問い合わせフォーム (API_URL 自動置換対象)
│ └── index2.html # 管理者画面 (API_URL 自動置換対象)
├── terraform/
│ ├── main.tf # S3, CloudFront, 自動アップロード・置換設定
│ ├── lambda.tf # Lambda, API Gateway, DynamoDB 設定
│ ├── variables.tf # リージョン等の変数定義
│ └── outputs.tf # デプロイ後の完成URL出力
├── .gitignore
└── README.md
各ディレクトリ・ファイルの役割
-
backend/: Python で記述した Lambda 関数。ユーザーからの投稿処理(submit)と管理者用一覧取得(admin)を格納。
backend/src/ 配下の Python コード(index.py)は、手動構築時に Lambda エディタで実行していたコードと同一です。
Terraform 化にあたっては、コードをローカルファイル化し、lambda.tf 側の archive_file データソースを用いて自動で ZIP 圧縮・配備する仕組みを取り入れています。 -
frontend/: フォームおよび管理画面の HTML。
main.tf内のreplace()関数によって API Gateway の URL が動的に挿入される対象となります。
そのため、各htmlファイル内のAPI Gateway の URL部分には変数を入れてます。 -
terraform/: インフラのリソース定義。lambda.tf内で../backend/src/のコードを参照し、自動で ZIP 化して Lambda へ配備します。
main.tf: S3 や CloudFront の作成に加え、replace()関数を用いて API Gateway のエンドポイント URL を HTML 内へ動的注入するメインロジックです。
lambda.tf: バックエンド処理を担う Lambda、エンドポイントとなる API Gateway (HTTP API)、データを保持する DynamoDB、および必要な IAM ロールを一括定義しています。
variables.tf: デプロイ先リージョン(ap-northeast-1)などを定義し、コードの再利用性を高めています。
5. まとめ
今回は「環境構築準備編」として、以下を整理しました。
- Ansible 運用経験からの着想(クラウドでも手動ミスを防ぐ自動化が必要)
- Terraform と他ツール(CDK等)の違い(HCLによる直感的な宣言型記述の親しみやすさ)
- ローカル環境のセットアップ
- 自動デプロイを見据えたディレクトリ構成の設計
手動構築(コンソール操作)では毎回パラメータを確認しながら時間をかけて作成していましたが、Terraform で構成をコード(HCL)にしておけば、事前に terraform plan で変更差分を確認でき、チーム内でのナレッジ共有も格段に容易になります。
次回【実践・自動デプロイ編】では、実際に terraform apply を実行し、API Gateway の URL が HTML 内に自動挿入されて一発で環境が立ち上がる挙動や、工夫したコードのポイントについて解説します!
