🥨
Terraformで複数環境の共通部分をモジュール化する
development
と production
の2環境のため、VPCを構築する例を考えてみます。
$ tree
.
├── development
│ └── main.tf
└── production
└── main.tf
2 directories, 2 files
普通に書くと、 local.environment
以外、同内容の main.tf
が2つ作成されます。
development/main.tf
locals {
environment = "development"
}
terraform {
required_version = "~> 1.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
profile = "example"
region = "ap-northeast-1"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = local.environment
}
}
output "vpc_id" {
value = aws_vpc.main.id
}
production/main.tf
locals {
environment = "production"
}
terraform {
required_version = "~> 1.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
profile = "example"
region = "ap-northeast-1"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = local.environment
}
}
output "vpc_id" {
value = aws_vpc.main.id
}
この程度なら何とかなりますが、環境やリソースや変更が増えていった場合、手に負えなくなっていきます。
上記の例をモジュール化した場合、次のようなファイル構成になると思います。
$ tree
.
├── development
│ └── main.tf
├── module
│ └── main.tf
└── production
└── main.tf
3 directories, 3 files
モジュール化した共通部分です。
module/main.tf
variable "environment" {
type = string
}
variable "profile" {
type = string
default = "default"
}
variable "region" {
type = string
default = "ap-northeast-1"
}
terraform {
required_version = "~> 1.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
profile = var.profile
region = var.region
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = var.environment
}
}
output "vpc_id" {
value = aws_vpc.main.id
}
各環境の定義ファイルです。
development/main.tf
locals {
environment = "development"
profile = "example"
}
module "main" {
source = "../module"
profile = local.profile
environment = local.environment
}
output "vpc_id" {
value = module.main.vpc_id
}
production/main.tf
locals {
environment = "production"
profile = "example"
}
module "main" {
source = "../module"
profile = local.profile
environment = local.environment
}
output "vpc_id" {
value = module.main.vpc_id
}
上記の例では元々のリソース定義が短いため、一見したところ記述量が減っていないように見えます。
各環境の main.tf
に注目すると、半分以下に減っていることがわかります。また、モジュール部分が長くなっています。
通常、環境ごとの差分より共通部分の方がかなり大きくなりますので、簡潔性と保守性は増していくと思います。
Discussion