はじめに
この記事はterraform初学者に向けてmoduleを自作する場合のやり方を載せていきます。
moduleの作成
今回はVPC moduleを作成していきます。
moduleに関する情報は以下になります。
- 作成するもの
- VPC
- public subnet
- private subnet
- internet gateway
- input
- project名
- environment名
- public subnetのcidrs
- private subnetのcidrs
- AZ
- tags
- output
- vpcのid
- public subnetのid
- private subnetのid
ファイル構成は以下のようになります
module/
├ examples/
└ main.tf
└ provider.tf
├ main.tf
├ outputs.tf
└ variables.tf
provider.tfは各々の環境次第なので割愛して、実際にそれぞれのファイルを作成していきます。
module本体
variables.tfには引数にとるものを書いていきます。
optionalな引数にはdefaultを定義します。
variable "project" {
description = "Project name"
type = string
}
variable "environment" {
description = "Environment name"
type = string
}
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
}
variable "public_subnet_cidrs" {
description = "CIDR blocks for public subnets"
type = list(string)
}
variable "private_subnet_cidrs" {
description = "CIDR blocks for private subnets"
type = list(string)
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
}
variable "tags" {
description = "Tags to be applied to all resources"
type = map(string)
default = {}
}
main.tfでは実際に作成するリソースを記述していきます。
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = merge(
var.tags,
{
Name = "${var.project}-${var.environment}-vpc"
}
)
}
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(
var.tags,
{
Name = "${var.project}-${var.environment}-public-subnet-${count.index + 1}"
Type = "Public"
}
)
}
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(
var.tags,
{
Name = "${var.project}-${var.environment}-private-subnet-${count.index + 1}"
Type = "Private"
}
)
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = merge(
var.tags,
{
Name = "${var.project}-${var.environment}-igw"
}
)
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = merge(
var.tags,
{
Name = "${var.project}-${var.environment}-public-rt"
}
)
}
resource "aws_route_table_association" "public" {
count = length(var.public_subnet_cidrs)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
outputsではmodule内で作成したリソースの中で、外部で使うものを書いていきます。
output "vpc_id" {
description = "ID of the created VPC"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "IDs of the created public subnets"
value = aws_subnet.public[*].id
}
output "private_subnet_ids" {
description = "IDs of the created private subnets"
value = aws_subnet.private[*].id
}
実際に使ってみる
では使ってみましょう。
examples配下のmain.tfに以下のような内容を記述します。
module "vpc" {
source = "../"
project = "example"
environment = "dev"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnet_cidrs = ["10.0.10.0/24", "10.0.11.0/24"]
availability_zones = ["ap-northeast-1a", "ap-northeast-1c"]
tags = {
Environment = "staging"
Terraform = "true"
}
}
> pwd
terraform-module/examples # example配下で以下のコマンドを実行します
> terraform init
> terraform plan
plan差分で9個のリソースが作成されることが期待値です
Plan: 9 to add, 0 to change, 0 to destroy.
実際に作成する場合には下記コマンドで実際のaws環境に反映させていきましょう。
> terraform apply
まとめ
今回はterraform moduleを実例を含めて作成してみました。
基本的には以下三つのファイルを作成することでmoduleを作成することができます。これだけ覚えておけばとりあえずmoduleの形だけは作れるはずです。
あとはmain.tfで記述している場所を例えばvpc.tf、 subnet.tfと分けるなりしてよりみやすい構成を目指すのも良いと思います。
- main.tf
- リソースを記述する
- variables.tf
- 引数や変数を記述する
- outputs.tf
- 作成したmoduleから使いたいものを記述する