Terraformを突如見ることになったときのメモ
ファイルの種類
.tf
)
設定ファイル( 一番基本的なファイル。HCLという独自言語か、JSONで記述される。
Terraformは現在のディレクトリにある、.tf
で終わるすべてのファイルを読みこんでくれるので、役割に応じた名前をつけることが可能。
mainとかvariablesとかファイルが別れてることが多いけど気にすることはない。
.tfvars
)
変数定義ファイル(.tf
で宣言されている変数に対して値を設定するためのファイル。
terraform.tfvars
というファイル名にすると、Terraformが自動的に読み込む。
*.auto.tfvars
のようにauto
を接尾辞としてつけた場合もTerraformは自動的に読み込む。
その他ファイル名で作った場合、明示的に指定する必要がある。
terraform.tfstate
および terraform.tfstate.backup
)
状態ファイル(Terraformが管理しているインフラの状態を保存しているJSONファイル。これがないと現在のインフラの状況がわからなくなってしまうので反映でエラーになったりする。
terraform.tfstate
は最新の状態を保存しており、terraform.tfstate.backup
は前回の状態をバックアップとして保存しています。
デフォルトでは、ローカルに保存されるものの、共同作業をする場合などもあるので基本的にはTerraform CloudやAWS S3上に保存するのが一般的。
.terraform.lock.hcl
)
ロックファイル(いわゆるバージョン管理用のロックファイル。terraform init
を実行した際に意図しないプロバイダのバージョンがインストールされることを防ぎます。
初回のterraform init
の際に自動生成されるので自分自身で作成することはない。
override.tf
または*_override.tf
)
オーバーライドファイル (既存の設定ファイルの一部を上書きするためのファイル。このファイルはTerraformが最後に読み込むようになっている。
各種記述ブロック
tfファイルに記載される項目に関しての解説。
terraform
ブロック
terraformブロックは、名前の通りTerraform自体の動作設定や、必要なプロバイダーのバージョンなどを定義するブロックになっている。
terraform {
# Terraform CLIのバージョンの制約
required_version = ">= 1.0"
# 使用するプロバイダーとそのバージョンの制約
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
# backendは状態ファイルの保存先指定
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "global/s3/terraform.tfstate"
region = "ap-northeast-1"
}
}
provider
ブロック
各種プロバイダーの設定を行うのに利用します。
provider "aws" {
region = "ap-northeast-1"
profile = "my-aws-profile" # これはオプション
}
このプロバイダーブロックは、プロバイダーごとのDocumentationにかかれているので確認しましょう。
例としてAWSのドキュメント
resource
ブロック
Terraformで管理したいインフラストラクチャリソースを定義するブロック。(例えばEC2インスタンス、S3、VPCの設定など)
このブロックはproviderのドキュメントに記載があります。
resource "aws_instance" "example_server" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
tags = {
Name = "ExampleServer"
}
}
data
ブロック
dataブロックはTerraformの外に既に存在しているリソースの内容や、特定の計算結果などを読み込んで利用できるようにするブロックです。例えば、既存のAMI IDやVPCの情報を取得したりします。
data "aws_ami" "latest_amazon_linux" {
most_recent = true # 複数存在する場合は最新を選ぶか
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-default-x86_64"]
}
}
上記の例だと、最新のAmazon Linux 2023の最新カーネルでx86_64アーキテクチャのAMIを取得しようとします。
フィルターは複数記述することができるので、このあたりはプロバイダーのドキュメントを見つつ調整をしましょう。
variable
ブロック
Terraformコードへの入力値を定義します。これはコードを再利用しやすくして環境ごとの設定変更を楽にします。
variable "instance_type" {
description = "The type of EC2 instance to launch."
type = string
default = "t2.micro"
}
typeにはstring
、number
、bool
が基本として選ぶことができ、型コンストラクタを利用するとコレクションなどの複数の型を指定できる。(list(<TYPE>)
, set(<TYPE>)
, map(<TYPE>)
, object({<ATTR_NAME> = <TYPE>, ...})
, tuple([<TYPE>, ...])
)
一応、any
も存在しているが、まあ使わないほうが良いでしょう。
利用時は、var.変数名
で記述すると利用できます。
詳しい記述は公式を見たほうがわかるかと思います。
output
ブロック
Terraformが作成したリソースを実行後に出力したり、出力情報を他のTerraform設定で利用(子モジュールから親モジュールで利用する用途)したりできるようにします。
output "instance_public_ip" {
description = "Public IP address of the example_server instance."
value = aws_instance.example_server.public_ip
}
locals
ブロック
複雑な式や値をローカル変数として定義し、同じモジュール内で何度も参照可能にします。
locals {
common_tags = {
Environment = "production"
Project = "MyWebApp"
}
instance_name = "${local.common_tags.Project}-${local.common_tags.Environment}-server"
}
module
ブロック
他のTerraform設定(モジュール)を呼び出して利用します。これで共通のインフラ構成を再利用可能な部品として管理できるようになります。
モジュールもサイト上に公開されています。
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.21.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
// ... その他の入力変数 ...
}
moduleブロックの名前は自分で決めることができるので、わかりやすい名前をつけたほうが良いでしょう。
Discussion