『実践Terraform AWSにおけるシステム設計とベストプラクティス』等を読んで考えた作戦のメモ (2022年11月ころ)
作成日: 2024/8/16
最終更新日: 2024/8/16
Scrapbox に転記したのは今日ですが、実際に読んで書いたのは 2022年11月以前です。
その後、会社のひとに教えてもらって、環境ごとの管理には Terragrunt を使うことにしました。
tfstate は AWS S3 + DynamoDB で管理しています。(Terragrunt が作ってくれるのでらくちん。)
書籍・リファレンス
実践Terraform AWSにおけるシステム設計とベストプラクティス
https://speakerdeck.com/tmknom/terraform-module-designs
https://developer.hashicorp.com/terraform/tutorials/modules/pattern-module-creation
ざっくり作戦
インストールするもの
tfenv
Terraform のバージョン管理ツール
Mac は brew でインストールできる
Terraform
tfenv でバージョン指定でインストールできる
Terraformer
すでにある AWS 環境 (Management Console からぽちぽち作ったやつ) を Terraform のファイルに出力してくれるやつ
git-secrets
コードに credentials が含まれていないかチェックしてくれるツール
うっかり秘匿情報を push しちゃわないように
TFLint
不正なオプション値も検知できる
tfsec
静的解析 -> セキュリティ問題を検出できる
チーム向けには Docker image にまとめて提供する?
Terraform 公式 Image: https://hub.docker.com/r/hashicorp/terraform
M1マック使えないらしい...
tfstate は S3 で管理する
バージョニング: 有効
暗号化: 有効
独立した GitHub リポジトリに置く
アプリケーションとは別リポジトリ
xxx-env とか xxx-infrastructure とか?
環境ごとの管理は?
環境ごとに独立した tfstate ファイルで管理すべき
環境ごとにディレクトリ作る?
Workspace で切り替える?
ブランチで切り替える?
main: production Workspace
staging: staging Workspace
環境依存の値は variable として別に定義しておくとよろし
variables.tf に定義しておく
実際のリソース定義ファイルからは var.heyhey のように参照できるらしい
結局どうしたらいいだろな?
Terraform のファイル分けかた・構成
こう??
main.tf : Terraform の基本設定?
versions.tf : いりそう
terraform のバージョンを書いとくやつ
provider.tf :
provider 情報 (e.g. aws) とそのバージョン情報を書いとく
backend.tf : tfstate ファイルの管理場所
outputs.tf : 実行後に出力される変数を定義する
variables.tf : 変数を定義する
modules/ : モジュールたち
iam_role/
main.tf
security_group/
main.tf
rds/
main.tf
network.tf これはここで良いんだろうか??
alb.tf
ecs.tf
{リソース名}.tf
environments/ : tfstate は S3管理
prod/
xxx.tfstate ?
stg/
dev/
本に書いてあることをやってみたメモ
code:main.tf
terraform {
# できる限り指定しておく
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.38"
}
}
# Terraform のバージョン
# 実行可能な Terraform バージョンを保証するために使うと良い
required_version = ">=1.3.4"
# S3 などに保存できる
backend "保存先" {保存先の設定など}
}
provider "aws" {
# provider は常に書くのが良い
# 複数AWS profile 使い分けている場合は、ここに使う profile 書く
profile = "fumi23"
region = "ap-northeast-1"
}
code:network.tf
#-------------------------------------------------------
# VPC
#-------------------------------------------------------
# resource "リソース種別" "リソース名"
# リソース種別: プロバイダから提供されるリソース種別
# リソース名: 構築するインフラ環境内で一意の名称
# * リソース名は、他のリソースから「リソース種別.リソース名」で参照できる
# * 環境に応じて命名規則を決めておくとよろし
resource "aws_vpc" "tf_trial_vpc" {
cidr_block = "10.1.0.0/16"
enable_dns_hostnames = true # DNS ホスト名: 有効
enable_dns_support = true # DNS 解決: 有効 (デフォルトも有効)
tags = {
Name = "tf-trial-vpc"
}
}
#-------------------------------------------------------
# Subnet
#-------------------------------------------------------
resource "aws_subnet" "tf_trial_subnet_a" {
vpc_id = aws_vpc.tf_trial_vpc.id
cidr_block = "10.1.0.0/24"
availability_zone = "ap-northeast-1a"
# サブネットに起動されたインスタンスにパブリック IP アドレスを割り当てる
map_public_ip_on_launch = true
tags = {
Name = "tf-trial-subnet-a"
}
}
#-------------------------------------------------------
# Internet GateWay
#-------------------------------------------------------
resource "aws_internet_gateway" "tf_trial_igw" {
vpc_id = aws_vpc.tf_trial_vpc.id
tags = {
Name = "tf-trial-igw"
}
}
#-------------------------------------------------------
# Route Table
#-------------------------------------------------------
resource "aws_route_table" "tf_trial_route_table" {
vpc_id = aws_vpc.tf_trial_vpc.id
tags = {
Name = "tf-trial-route-table"
}
}
# Route
# ルートは aws_route_table のインラインとしても書けるよ〜
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table#example-usage
resource "aws_route" "tf_trial_route" {
route_table_id = aws_route_table.tf_trial_route_table.id
destination_cidr_block = "0.0.0.0/0" # 宛先 CIDR ブロック
gateway_id = aws_internet_gateway.tf_trial_igw.id
}
# Route Table と Subnet の関連付け
resource "aws_route_table_association" "tf_trial_route_table_assoc" {
route_table_id = aws_route_table.tf_trial_route_table.id
subnet_id = aws_subnet.tf_trial_subnet_a.id
# TODO: サブネットは複数紐付けたい、変数使うみたい (← 2024/8/16注: count とか for_each のことを言ってるんだろうか)
}