Terraform Modulesはソースコードをモジュール化することでテンプレートとして使うことができるようになる機能です。
この記事では、Terraform Modulesを利用した本番・検証などの環境分割・切り替えの方法についてご紹介します。
Terraform の入門内容については以下の記事を参照してください。
Terraform Modulesとは
Terraform Modules は、ディレクトリなどにまとめた Terraform のコードをテンプレート・モジュールとして呼び出して利用することができる機能です。
以下のように呼び出します。
module "リソースの名前" {
source = "モジュールを定義したフォルダのパス"
パラメーター名 = "パラメーター値"
}
また、自身で作成した Module ではなく Terraform Registry で提供されているモジュールは以下のように呼び出すことができます。
AWS VPC Terraform module の例です。
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
// 以降、変数へ値を代入する
}
本記事では Terraform Modules を利用した環境分割方法について記載しますが、他にも Workspaces を利用した方法もあります。
命名規則
この記事でご紹介する例は下記の記事の命名規則に従っています。
環境分割方法
あくまで筆者独自の方法なので参考までにお願いします。
ディレクトリ構成は以下の通りです。
.
├── env # 環境差分用ディレクトリ
│ ├── prd # prd 環境用ディレクトリ
│ │ └── main.tf # 環境差分に応じたTerraformバージョン、Provider、Backend、変数、Module、Outputsの設定
│ ├── stg # stg 環境用ディレクトリ
│ │ └── main.tf
│
└── modules # 各環境共通で利用する resources をモジュール化
├── sample-vpc.tf # resource(sampleサービスのVPC) の設定を記述
├── ... # resource(その他) の設定を記述
├── variables.tf # Module 内で利用する変数定義
└── outputs.tf # outputし、他のリソースから tfstate ファイル経由で参照されるデータを記載
使い方は対応する環境をカレントディレクトリとして、 terraform
コマンドを実行するだけです。
# プロジェクトの初期化
$ cd env/[環境]
$ terraform init
# ファイルフォーマット
$ cd env/[環境]
$ terraform fmt ../../modules
$ terraform fmt
# 個別のリソースのterraform 初期化
$ cd env/[環境]
$ terraform init
# 個別のリソースの設定確認
$ cd env/[環境]
$ terraform validate
# 個別のリソースの差分確認
$ cd env/[環境]
$ terraform plan
# 個別のリソースの適用
$ cd env/[環境]
$ terraform apply
# 個別のリソースの削除
$ cd env/[環境]
$ terraform destroy
以降で個々のファイルについて説明していきます。
aws_vpc
を 1 つ構築する簡易な例になっています。
env/[環境]/main.tf
modules
の呼び出し元です。
../../modules
でモジュールを呼び出して modules/variables.tf
に定義した変数に値を代入します。
これによって環境差分を実現できます。
modules
の他にも必要に応じて変数を定義してください。
また、 output
でリソースの設定結果を出力する対象について記載します。
modules/outputs.tf
に記載した modules
の output
を実際に出力します。
#####################################
# Terraform Settings
#####################################
terraform {
required_version = "~> 1.1.0" // Terraform のバージョン
required_providers { // Provider の設定
aws = {
source = "hashicorp/aws"
version = "~> 3.0" // AWS Provider のバージョン
}
}
backend "s3" { // この設定で State ファイルが S3 に保存されます
bucket = "your-bucket-name" // State ファイルを配置するバケット
key = "terraform.tfstate" // State ファイルを配置するパス・ファイル名
region = "ap-northeast-1" // S3のリージョン
}
}
#####################################
# Provider Settings
#####################################
provider "aws" {
region = local.region
profile = var.profile
default_tags { // AWS リソースへのデフォルトタグの設定
tags = {
System = local.system
Env = local.env
Terraform = "true"
}
}
}
#####################################
# Variables
#####################################
variable "profile" {}
locals {
region = "ap-northeast-1"
system = "system"
env = "prd"
}
#####################################
# Module
#####################################
module "modules" {
source = "../../modules"
#####################################
# Common Variables
#####################################
system = local.system
region = local.region
env = local.env
base_name = "${local.system}-${local.env}"
#####################################
# VPC Variables
#####################################
vpc_cidr_block = "10.0.0.0/16"
}
#####################################
# Outputs
#####################################
output "sample_vpc" {
value = module.modules.sample_vpc
}
Provider の設定では default_tags
を変数で代入する形で設定しておくと非常に便利です。
modules/variables.tf
modules
内で利用される変数を管理するファイルです。
env/[環境名]/main.tf
にて変数に値を代入します。
これによって環境差分を実現できます。
#####################################
# Common Variables
#####################################
variable "region" {}
variable "system" {}
variable "env" {}
variable "base_name" {}
#####################################
# VPC Variables
#####################################
variable "vpc_cidr_block" {}
modules/outputs.tf
output
でリソースの設定結果を出力する対象について記載したファイルです。
なお注意しなければならないのは、このファイルはあくまで modules
からのアウトプットです。
env/[環境名]/output.tf
へ modules/outputs.tf
からのアウトプットをマッピングする必要があります。
#####################################
# VPC
#####################################
output "sample_vpc" {
value = aws_vpc.sample
}
modules/sample-vpc.tf
Amazon VPC のリソース定義を記載します。
#####################################
# VPC
#####################################
resource "aws_vpc" "sample" {
cidr_block = var.vpc_cidr_block
tags = merge(tomap({ "Service" = "sample" }), tomap({ "Name" = "${var.base_name}-sample" }))
}