Terraformを自分なりにメモる
Terraform を自分なりに整理する
自分用にメモしたものなので、責任は追えませんのでご了承ください。
ディレクトリ構造
以下のような感じにつくるとよさげ
$ tree
.
├── environments
│ ├── production
│ │ ├── backend.tf
│ │ ├── main.tf
│ │ └── outputs.tf
│ └── staging
│ │ ├── backend.tf
│ │ ├── main.tf
│ │ └── outputs.tf
└── modules
├── ec2
│ ├── main.tf
│ ├── output.tf
│ ├── provider.tf
│ └── variables.tf
└── ...
└── ...
一部ファイルの説明
- main.tf
モジュール、ローカル、およびデータソースを呼び出してリソースを作成 - variables.tf
main.tf で使用される変数を宣言 - outputs.tf
main.tf で作成されたリソースの出力 - versions.tf
Terraform とプロバイダーのバージョン要件を指定
詳しくは公式を見るとよし
tfstateファイル
Terraformで管理しているインフラの状態を記録するためのファイル
自動的にこのファイルへ作成したリソースの状態が記録されます
複数人で作業をする場合は、S3等のストレージに保存して共有できるようにしておく
※バケットのバージョニング推奨
backend機能を使うことで、tfstateファイルをローカルではなく別のストレージに保存することが可能になる
(つまり、S3などのパブリッククラウドサービスのストレージに保存が可能)
書き方は公式を参考すると良し
environments
環境ごとに管理するために用意する
※backendは省略
main
変数の指定とどのモジュールを扱うかを設定するために使う
ローカル変数を使って汎用的に使う変数を指定できる
もちろん、varialbesファイルを別途用意してやってもよいが、environmentごとにファイルを分けてやるパターンであれば、変数用にファイルを分ける必要がない気がする
locals {
common = {
environment = "production"
region = "ap-northeast-1"
}
vpc_id = "vpc-xxxxxxxxxxxxxxxxxxxxxx"
}
モジュールを読み込む場合は、以下のようにする
- local変数
local.{変数名}
- モジュールの値
module.module名.output値
module "ec2" {
source = "../../modules/ec2"
# 1つの変数に1つの値
environment = local.common.environment
vpc_id = local.vpc_id
# 1つの変数に複数の値(変数名は適当です)
properties = {
property1 = "terraform"
property2 = 111
property3 = [
"memo1",
"memo2"
]
}
outputs
各モジュールでoutputした値を出力できます
Moduleの名前までにしておくことで、Module側でOutputした値がまとまった形で出力されます
output "ec2_ids" {
value = module.ec2
}
modules
ec2などの単位で作成するリソースを分けておく。
provider
クラウド プロバイダー、SaaS プロバイダー、およびその他の API と対話するために指定する必要がある
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
}
variables
変数を宣言するファイル。
ディレクトリ構造に書いたやり方だと、各環境のmain.tfで指定した変数をこのファイルで受け取る必要がある。
例として、object型?のやつを受け取るときの書き方
variable "environment" {
type = string
}
variable vpc_id {
type = string
}
variable "properties" {
type = object({
property1 = string
property2 = number
property3 = list(string)
})
}
main
variables.tfに記載された変数にアクセスする場合は、var.{変数名} と書きます
resource "aws_instance" "example" {
vpc_id = var.vpc_id
tags = {
Environment = "${var.environment}"
Name = "sample-${var.environment}"
CreateBy = "Terraform"
Test = "${var.properties.property1}"
}
}
${var.environment} のように ${} で括っているのもあれば、var.vpc_id のように括らなくても問題ない。ただし、文字列と一緒に使う場合は ${} で括る必要がある。
v0.12 から ${} はつけなくてもよくなったみたいです
object型の変数は多分 "${var.properties.property1}" の形でいいはず。
おまけ(loopを使う場合)
main.tf からリストを渡してあげる
id
は parameter.id
で使うため設定している
properties = [
{
id = 1
property1 = 1234,
property2 = "terraform",
property3 = "hogehoge",
property4 = 5678
},
{
id = 2
property1 = 4321,
property2 = "terraform",
property3 = "hoge",
property4 = 8765
}
]
変数は以下のようにリストでオブジェクトを受け取るようにしておけばOK
variable "properties" {
type = list(object({
property1 = number
property2 = string
property3 = string
property4 = number
}))
}
for_eachで受け取る。
注意として、parameter.id
ってところにユニークな値が入ってくるため、作成するリソースにユニークな値が無い場合は自分で用意する必要がある(多分)
resource "aws_instance" "sample" {
for_each = { for parameter in var.properties : parameter.id => parameter }
property1 = each.value.var1
property2 = each.value.var2
property3 = each.value.var3
property4 = each.value.var4
}
outputs
リソースの値を出力させることで、別のモジュールで参照出来るようになる
(出力できる値は使うリソースごとに異なるためドキュメントを確認すること)
使うリソース名.論理名.対象
のような形で指定する
output "property1_id" {
description = "Id of property1"
value = aws_instance.sample.id
}
Discussion
ftstate は誤字で tfstate が正
ありがとうございます。訂正しました。