このブログ記事では、Terraformにおける変数と出力について紹介します。

前回の記事では、シンプルな例を使用してTerraformでクラウドインフラストラクチャを簡単にセットアップする方法について説明しました。 その例からTerraformのIaCツールとしての有用性を既に観察できましたが、例のコードは多くのパラメータがハードコードされており、 コードが再利用不可能で柔軟性と安全性に欠けていた為、これはIaCツールとしてのTerraformを十分に活用的ていませんでした。 そこで、この記事では、HCLにおける変数と出力を活用してTerraformをより有効活用する方法について説明します。
変数
HCLでは、variable
ブロックを使用して変数を定義できます。このブロックは説明、型、
そしてデフォルト値と変数が機密情報かどうか(環境変数用)を含み、定義された変数はvar.<var_name>
で使用できます。
変数はリソースが定義されている同じmain.tf
ファイルで定義することもできますが、
変数定義用に別のvars.tf
ファイルを設定することが多いです。以下はvars.tf
での変数定義の例です。
variable "ami" {
description = "Amazon Machine Image for EC2 instance"
type = string
}
variable "instance_type" {
description = "EC2 instance type (default: t4.micro)"
type = string
default = "t4.micro"
}
variable "db_password" {
description = "SENSITIVE DB password"
type = string
sensitive = true
}
ハードコードされた文字列の代わりに、適切な場所でvar.ami
やvar.instance_type
のような変数を使用できます。
Terraformでは、変数に値を提供する多くの方法があります。例えばplan
とapply
を実行する際、
Terraformはまず-var
と-var-file
引数をチェックし、必要なすべての変数に値が提供されていることを確認します。
引数が提供されていない場合、または値が不十分な場合、*.auto.tfvars
とterraform.tfvars
ファイルを探します
(tfvars
ファイルには各行に<var_name> = <value>
を含みます)。
次に、TF_VAR_<name>
環境変数をチェックし、その後デフォルト値をチェックします。
それでも値が不十分な場合、CLIで手動で値を入力するよう求められます。
通常、非機密変数(ami
やinstance_type
など)の値は.tfvars
ファイルで定義し、
機密変数(db_password
など、sensitive
パラメータをtrue
に設定してCLIに表示されないようにする)は.env
ファイルまたは-var
引数で定義します。
このセットアップを使用することで、インフラストラクチャの要件とフェーズ(開発、ステージング、本番)に応じて異なる.tfvars
ファイルを編集または使用でき、
リポジトリで共有される可能性のあるファイルにハードコードされた秘密情報を避けることができるため、
コードを再利用可能で柔軟性と安全性のあるものにすることができます。
ローカル変数と出力
コードの再利用性のためではなく、より良いコード構成と繰り返しを避けるために変数を使用したい場合があります。
例えば、ローカル変数ec2_port
を作成してEC2インスタンスのポート番号8080
をハードコードすることを避けたい場合があります。
このような場合、定義されたファイル内でのみ適用されるローカル変数を使用でき、以下のようにlocals
ブロックを使用して定義できます。
locals {
ec2_port = 8080
lb_port_in = 80
lb_port_out = 0
}
上記のように、特定のファイルのすべてのローカル変数は同じlocals
ブロック内で定義されます。
その後、local.ec2_port
、local.lb_port_in
などのようにこれらの変数を使用できます。
また、apply
コマンド後に属性の出力値を取得したい場合もあります。
例えば、ネットワーキングの設定(Kubernetesクラスターなど)でEC2インスタンスのIPアドレスを使用する場合などです。
このような場合、output
ブロックで定義される出力を使用できます。
このブロックには、取得したいリソースの属性を指定する値(オプションで説明、型、sensitive
パラメータ)が含まれます。
出力は通常、変数がvars.tf
で定義されるのと同様に、outputs.tf
ファイルで定義されます。
output "instance_1_ip_addr" {
type = string
values = aws_instance.instance_1.public_ip
}
apply
コマンドを使用してリソースが準備完了後、非機密出力がCLIに表示されます。
また、terraform output -json
を使用してすべての出力パラメータを確認したり、terraform output <output_name>
を使用して特定の出力の値をチェックしたりできます。
これらは、後続の手動または自動のインフラストラクチャ設定のためにログ記録やパイプ処理が可能です。
言語機能とメタ引数
変数と出力以外にも、HCLにはより良いコードを書くことを可能にする多くの言語機能があります。
例えば、リソース定義でテンプレート文字列("AMI used: ${var.ami}"
)、
演算子(!
、==
など)、条件文(<cond> ? true : false
)、forループ([for i in var.list: i]
)などを使用できます。
また、ハッシュ化、型変換、日付と時刻などに関する便利な定義済み関数もあるため、
詳細については記事の最後に引用されている公式ドキュメントをチェックすることを強く推奨します。
リソースブロックでメタ引数を使用することもでき、これによりインフラストラクチャプロビジョニングをより細かく制御できます。
例えば、depends_on
引数を用いて、この引数を持つリソースが構築される前に作成される必要があるリソースをリストで定義できます。
また、同じリソースの複数のレプリカを作成し、count.index
を使用して個別に参照できるcount
メタ引数、
リスト(またはセット)を反復処理して各要素に対してリソースを作成し、each.key
で参照できるfor_each
引数、
ライフサイクルでの動作を設定できるlifecycle
引数(可用性のためのcreate_before_destroy
や変更を避けるためのignore_changes
など)も使用できます。
Terraformには他にも多くの有用なメタ引数があるため、詳細については公式ドキュメントをチェックすることを推奨します。
結論
この記事では、IaCツールとしてTerraformをより活用するための変数、ローカル変数、出力、その他の有用な言語機能とメタ引数を紹介しました。 練習としてこれらの機能を使用して前回の記事のTerraformコードを書き直してみたり、他のプロジェクトでも活用してみることを強く推奨します。 これらの機能の詳細と説明については、以下に引用されているリソースをチェックすることを強く推奨します。
リソース
- DevOps Directive. 2022. Complete Terraform Course - From BEGINNER to PRO! (Learn Infrastructure as Code). YouTube.
- HashiCorp. n.d. Terraform Language Documentation. Terraform.