Open13

terraformファイル分割検討

not75743not75743

terraformのmain.tfの見通しが悪いので、いろいろ試します。
main.tfにすべてが記載されている状態からスタート

terraform
└── main.tf
not75743not75743

リソースごとにファイル分割

ファイルが多くなりましたが、コードは見やすくなりました

terraform
├── ec2.tf
├── ecs.tf
├── main.tf
└── network.tf

main.tfにはプラグインやtfstate(s3格納)の情報を記載し、
それ以外は役割ごとに分割

not75743not75743

変数を別ファイルに移動①

リソースと一緒に変数を書いていたため、見やすさのため分割します。

terraform/
├── ec2.tf
├── ecs.tf
├── main.tf
├── network.tf
├── terraform.tfvars ## new
└── variables.tf ## new

dataも分割検討できますが、あまり多くないので今回は分けずでやります。

not75743not75743

変数を別ファイルに移動②

各ファイルの詳細

variables.tf

変数を定義する

variables.tf
variable "instanceip" {
  description = "instanceip"
}

terraform.tfvars

変数に入れる値を設定

terraform.tfvars
instanceip = "t3a.medium"

EC2.tf

EC2.tf
resource "aws_instance" "test-ec2" {
  instance_type          = "${var.instanceip}"
not75743not75743

モジュールを試す

s3バケットを1つ作ります

.
├── main.tf
├── modules
│   └── s3_bucket
│       ├── main.tf
│       └── variable.tf
└── terraform.tfstate # 実行後に生成
modules/s3_bucket/main.tf
resource "aws_s3_bucket" "example" {
  bucket = var.bucket_name

  tags = {
    Name = "Example Bucket"
  }
}
modules/s3_bucket/variable.tf
variable "bucket_name" {
  description = "The name of the S3 bucket"
  type        = string
}
main.tf
provider "aws" {
  region = "ap-northeast-1"
}

module "example_bucket" {
  source      = "./modules/s3_bucket"
  bucket_name = "example-bucket-20230519"
}

moduleでパスを指定するんですね

https://developer.hashicorp.com/terraform/tutorials/modules/module?in=terraform%2Fmodules
https://developer.hashicorp.com/terraform/language/modules

not75743not75743

s3バケットをもう一つ作りたい場合は

main.tf
provider "aws" {
  region = "ap-northeast-1"
}

module "example_bucket" {
  source      = "./modules/s3_bucket"
  bucket_name = "example-bucket-20230519"
}

module "example_bucket2" {
  source      = "./modules/s3_bucket"
  bucket_name = "example-bucket-20230519-2"
}

このようにもう一度moduleで呼び出して異なるbucket_nameをつけるだけ。
便利だね

not75743not75743

環境別に作ってみる

上記の記事を参考に作ってみる

.
├── environments
│   ├── dev
│   │   └── main.tf
│   └── prod
│       └── main.tf
└── modules
    └── s3_bucket
        ├── main.tf
        └── variable.tf

モジュール

modules/s3_bucket/main.tf
resource "aws_s3_bucket" "example" {
  bucket = "${var.bucket_name}-${var.environment}"

  tags = {
    Name        = "${var.bucket_name}-${var.environment}"
    Environment = var.environment
  }
}
modules/s3_bucket/variable.tf
variable "bucket_name" {
  type        = string
}

variable "environment" {
  type        = string
  default     = "dev"
}

あとは環境別に作るだけ

environments/dev/main.tf
provider "aws" {
  region = "ap-northeast-1"
}

module "prod_bucket" {
  source      = "../../modules/s3_bucket"
  bucket_name = "example-bucket-20230519"
  environment = "dev"
}
environments/prod/main.tf
provider "aws" {
  region = "ap-northeast-1"
}

module "dev_bucket" {
  source      = "../../modules/s3_bucket"
  bucket_name = "example-bucket-20230519"
  environment = "prod"
}

これでdev環境とprod環境のs3がそれぞれできる

not75743not75743

感想

便利
tfstateが環境ごとに貯まるのが大変そう