Terraformの基本的なリソース作成を学んできました。
ここまでは、
- VPCを作る
- Subnetを作る
- EC2を作る
- ALBを作る
- RDSを作る
- "count" で複数作る
- "for_each" で異なる設定を管理する
といった「AWSリソースを作る方法」を中心に学んできました。
今回から少しずつ、
«「Terraformをどうすれば使い回しやすくできるのか?」»
という設計の話に入っていきます。
今回のテーマは Variables(変数) です。
今日の実務シナリオ
会社でこんなことを言われたとします。
👨💼 上司
«「開発環境は "t3.micro" でいいよ。」»
5分後……
👨💼 上司
«「やっぱ本番は "t3.large" にして。」»
さらに……
👨💼 上司
«「検証環境は "t3.small" に変更ね。」»
今まで通り、EC2に直接書いていたら、
resource "aws_instance" "web" {
instance_type = "t3.micro"
}
環境が変わるたびに、この値を書き換える必要があります。
さらにEC2だけではなく、
- EC2
- RDS
- 別のEC2
- Auto Scaling
- その他のリソース
など、同じ設定値を複数箇所で使っていたらどうでしょう?
全部変更する必要があります。
これはかなり面倒です。
そこで登場するのが、
Variables
です。
まず覚えるコード
まず変数を定義します。
variable "instance_type" {
default = "t3.micro"
}
そしてEC2側では、
resource "aws_instance" "web" {
instance_type = var.instance_type
}
と書きます。
今回まず覚えるのは、
variable
と
var.
この2つです。
どういう仕組みなのか?
今までは、
EC2
↓
"t3.micro"
と直接指定していました。
つまり、
instance_type = "t3.micro"
です。
Variablesを使うと、
variable
↓
instance_type
↓
"t3.micro"
↓
EC2
という構造になります。
Terraformのコードで見ると、
variable "instance_type" {
default = "t3.micro"
}
で、
«「"instance_type" という変数を用意します」»
と宣言しています。
そして、
instance_type = var.instance_type
で、
«「EC2のインスタンスタイプには、"instance_type" という変数の値を使います」»
という意味になります。
"var.instance_type" を分解してみる
ここは大事です。
var.instance_type
は、
var
↓
Variablesを参照する
↓
instance_type
↓
その変数に入っている値を取得する
というイメージです。
つまり、
variable "instance_type" {
default = "t3.micro"
}
があれば、
var.instance_type
の中身は、
t3.micro
になります。
変数を使うメリット
例えば、
variable "instance_type" {
default = "t3.micro"
}
として、
EC2で、
instance_type = var.instance_type
とします。
さらに別のリソースでも、
some_setting = var.instance_type
のように同じ変数を使えます。
ここで、
default = "t3.micro"
を、
default = "t3.large"
に変更すると、
その変数を参照している箇所の値が、
t3.micro
↓
t3.large
へ変わります。
つまり、
«設定値を一か所にまとめて管理できる»
ということです。
これがVariablesの大きなメリットです。
今日の問題
Q1
なぜ、
instance_type = "t3.micro"
と直接書かずに、
var.instance_type
を使うのでしょうか?
Q2
もし、
default = "t3.large"
に変更したら、何が起きるでしょうか?
⭐ 今日一番重要な問題
会社には、
- 開発環境(dev)
- 検証環境(stg)
- 本番環境(prod)
など、複数の環境があります。
例えば、
開発環境 → t3.micro
検証環境 → t3.small
本番環境 → t3.large
としたいとします。
Terraformの基本的な構成は同じなのに、環境ごとに全部別のTerraformコードを書くのは大変です。
そこで質問です。
«毎回Terraformを3つ書くより、変数を使った方がいい理由は何でしょうか?»
今回の回答
Q1
«"instance_type = "t3.micro""を他のインスタンスタイプに変えたら、対応するEC2もRDSも変えないといけないけど、"var.instance_type"を書いてたら、"variable "instance_type""を変えるだけでEC2もRDSも全て変えられるから。»
Q2
«インスタンスタイプがt3.largeに変わる。»
⭐ 今日一番重要
«Terraformを3つ書いてそれのインスタンスタイプを変更したいときに3個変えないといけないけど、変数を変えたらデフォルトを変えるだけで変更が適応されるから。»
今回のレビュー
Q1:なぜ "var.instance_type" を使う?
回答
«"variable "instance_type""を変えるだけでEC2もRDSも全て変えられるから。»
評価:💯
ここはかなり良い理解です。
特に重要なのが、
«変更箇所を一か所にまとめられる»
という考え方です。
これはTerraformだけではなく、プログラミングやインフラ設計でも非常に重要です。
例えば、
instance_type = "t3.micro"
を10か所に直接書いていたとします。
本番環境を、
t3.micro
↓
t3.large
に変更したくなった場合、10か所確認する必要があります。
しかし、
variable "instance_type" {
default = "t3.micro"
}
としておけば、同じ変数を参照している箇所は、
var.instance_type
で統一できます。
そのため、
«設定値を一元管理できる»
というメリットがあります。
ここから出てくる重要な言葉が、
保守性
です。
設定変更が発生したときに、
«「どこを直せばいいんだ?」»
となりにくくなります。
Q2:"default = "t3.large"" にしたら?
回答
«インスタンスタイプがt3.largeに変わる。»
評価:💯
これも正解です。
例えば、
variable "instance_type" {
default = "t3.micro"
}
だったものを、
variable "instance_type" {
default = "t3.large"
}
に変更します。
そして、
resource "aws_instance" "web" {
instance_type = var.instance_type
}
なら、
Terraformから見ると、
変更前
t3.micro
↓
変更後
t3.large
という差分になります。
Terraformは現在の状態と設定ファイルの差分を確認し、必要な変更を計画します。
実際に反映するのは、
terraform apply
です。
つまり、
«変数を変えただけでAWS上のEC2が即座に変わる»
という意味ではありません。
正確には、
Variableを変更
↓
Terraformが差分を確認
↓
terraform plan
↓
変更内容を確認
↓
terraform apply
↓
AWSへ変更を反映
という流れです。
この違いは実務では大切です。
⭐ 今日一番重要な問題のレビュー
今回の回答は、
«Terraformを3つ書いて、それぞれ変更しないといけない。
↓
変数なら1か所変えれば全部反映できる。»
という考え方でした。
評価:💯
これもVariablesの本質を理解できています。
ただし、実務ではさらに一歩進みます。
実は、
«開発・検証・本番で毎回Terraformコードを書き換える»
という運用は避けたいです。
では、どうするのでしょうか?
実務では "default" を毎回書き換えない
例えば、
開発環境
dev.tfvars
instance_type = "t3.micro"
検証環境なら、
stg.tfvars
instance_type = "t3.small"
本番環境なら、
prod.tfvars
instance_type = "t3.large"
というように、環境ごとに変数の値を外から渡す設計ができます。
つまり、
Terraformコード
│
│ 同じ
↓
┌──────────────┐
│ Variables │
└──────────────┘
│
┌───┼───┐
↓ ↓ ↓
dev stg prod
↓ ↓ ↓
micro small large
という構造です。
Terraformのコード自体は同じ。
違うのは、
«環境ごとに渡す設定値»
です。
これがVariablesを使う大きな理由です。
Variablesの本当の目的
Variablesは、
«「値を変数に入れる機能」»
だけではありません。
もっと重要なのは、
«同じTerraformコードを、異なる環境・条件で再利用できるようにする»
ことです。
例えば、
開発環境
EC2 → t3.micro
RDS → 小さいサイズ
台数 → 1
検証環境
EC2 → t3.small
RDS → 中くらい
台数 → 2
本番環境
EC2 → t3.large
RDS → 大きいサイズ
台数 → 3
という違いがあっても、
Terraformの基本的な構成を共通化できます。
今回覚えること
今回覚えてほしいのは、まずこの2つです。
① "variable"
variable "instance_type" {
default = "t3.micro"
}
変数を定義する。
② "var."
var.instance_type
定義した変数を参照する。
今回のコードを完成させる
variable "instance_type" {
default = "t3.micro"
}
resource "aws_instance" "web" {
ami = "ami-xxxxxxxx"
instance_type = var.instance_type
}
ここで重要なのは、
instance_type = var.instance_type
です。
左側の、
instance_type
は、
«EC2のインスタンスタイプを設定する項目»
右側の、
var.instance_type
は、
«Variablesで定義した "instance_type" の値を使う»
という意味です。
同じ名前ですが、役割は違います。
Terraformを「書く」から「設計する」へ
ここまでの学習では、
AWSリソースをどう作るか?
を中心に学んできました。
しかしVariablesからは、
どうすれば同じコードを使い回せるか?
を考えるようになります。
これはTerraformを使う上でかなり重要な考え方です。
例えば、
開発
↓
検証
↓
本番
と環境が増えても、
Terraformコードを全部コピー
するのではなく、
共通コード
+
環境ごとの設定値
という考え方に変わっていきます。
🌟 今回の理解度
⭐⭐⭐⭐⭐ 5 / 5
今回の回答で特に良かったのは、
«「1か所を変更すれば複数箇所に反映できる」»
というVariablesの本質を、自分の言葉で説明できていたことです。
単に、
«「Variablesは変数です」»
と覚えるだけではなく、
変更箇所をまとめる
↓
保守しやすくなる
↓
同じコードを使い回せる
↓
環境ごとの設定を分離できる
というところまで理解できています。
ここからTerraformが一気に「プログラミングっぽく」なってきます。
🎓 次回予告
次回は……
第22回:Outputs
を学びます。
ここで新しい疑問が出てきます。
Terraformで、
aws_instance.web.id
や、
aws_lb.alb.dns_name
のような値を作ったとして、
«「じゃあ、その値をどうやってTerraformの実行結果として確認するの?」»
という問題です。
そこで登場するのが、
output
です。
例えば、
output "alb_dns_name" {
value = aws_lb.alb.dns_name
}
と書けば、
Terraform実行後にALBのDNS名を確認できるようになります。
さらに、
ALB DNS
RDS Endpoint
VPC ID
EC2 IP
など、作成したAWSリソースの重要な情報をTerraformから取り出せるようになります。
Variablesが、
«「外からTerraformへ値を渡す」»
仕組みなら、
Outputsは、
«「Terraformから外へ値を取り出す」»
仕組みです。
ここが分かると、Terraformのコードがさらに「システム」として見えてきます。
次回は Outputs へ進みます。🔥☁️