自動化ツールの一つである「Terraform」について、これから学ぼうという方、使っていきたい方を対象に、Terraformの導入方法や、基本的な使い方を紹介していきます。今回は、Terraformにおける変数の使用方法を解説します。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
クラウド環境の構築において、インスタンス名やストレージのボリュームサイズを設定するときは、値を直接入力して設定することができます。しかし、複数のインスタンスの設定を変更する場合、関係する全ての値を変更する必要がありますし、変更作業漏れといったミスが発生することも考えられます。
Terraformを使用する場合、変数で設定値を定義しておき、コードやコマンド上でその変数を参照することで、見栄えも良く、メンテナンス性にも優れる形で、クラウド環境を構築したり運用したりできるようになります。今回は、Terraformにおける変数の概要や使用方法を解説します。
まずは簡単な例で使用する際のイメージをつかんでいただければと思います。ここでは、Amazon EC2インスタンスを作成するTerraformのコードを基に変数を使用してみます。
locals { instance_name = "example" } resource "aws_instance" "example" { ami = "ami-0f9816f78187c68fb" instance_type = "t2.micro" root_block_device { tags = { Name = local.instance_name } } tags = { Name = local.instance_name } }
最初にlocalsというブロックが現れました。この中に変数を定義していくわけですが、今回はinstance_nameという名前の変数を定義し、「example」という文字列を設定しています。
この変数を下のaws_instance.exampleリソースで参照していますが、参照するときはlocal.という接頭辞を付けて変数名を指定しています。この例では、ルートブロックデバイスの「Name」タグとインスタンス自体の「Name」タグに、変数に設定してある文字列を使うよう設定しています。
先ほどの例では、変数に設定した文字列をそのまま設定値として使用していましたが、設定値の一部として使いたいときは少し違う表記になります。
resource "aws_instance" "example" { ami = "ami-0f9816f78187c68fb" instance_type = "t2.micro" root_block_device { tags = { Name = "instance-${local.instance_name}" } } tags = { Name = "block-${local.instance_name}" } }
これは第3回で紹介したcount変数を使用したインスタンス名の設定と同じような方法です。このように、文字列の一部として変数の値を使用したい場合は、変数名を${}で囲み、文字列の一部として表記します。
先ほど示した例では、変数に文字列を指定していました。変数に設定できるのは文字列だけではありません。Terraformで定義できる変数の型として、次のようなものがあります。
型名 | 表記例 |
---|---|
string | "example" |
number | 123 |
bool | trueまたはfalse |
list | ["a", "b", "c"] |
object | { key = "value" } |
上の表だけでは使用イメージが湧きにくいと思いますので、具体的な使用例を交えながら解説します。
冒頭の変数の定義と使用方法は、あくまでTerraformのコード内で閉じて変数を使い回すことを目的としていて、変数の値を別ファイルで管理したり、コマンド実行時に設定したりするといったことは想定していません。
変数の値を別ファイルで管理する場合、変数の定義方法は次のようになります。
variable "example_string" { type = string default = "example" } variable "example_number" { type = number } variable "example_bool" { type = bool } variable "example_list" { type = list(string) } variable "example_object" { type = object({ key1 = string key2 = number }) }
変数はvariableリソースとして定義して、その次に変数名を宣言します。variableブロックの中に変数の型をtypeパラメーターで指定します。上記のうち、string型の変数であるexample_stringにはdefaultというパラメーターが存在しますが、これはデフォルト値を設定するパラメーターで、必須ではありません。必要に応じて指定します。
次に、変数の値を設定する別ファイルですが、ファイル名をterraform.tfvarsとしておくと、Terraformのコードと同じディレクトリに存在すればデフォルトで変数定義ファイルとして読み込んでくれます。このファイルを作成して、次のように記述すると変数の値を設定することができます。
example_string = "example" example_number = 123 example_bool = true example_list = ["a", "b", "c"] example_object = { key1 = "example" key2 = 456 }
別ファイルで定義した変数をTerraformのコード上で使用する場合、var.を変数名の先頭に付けて使用します。
resource "aws_instance" "example" { ami = "ami-0f9816f78187c68fb" instance_type = "t2.micro" tags = { String = var.example_string Number = var.example_number Bool = var.example_bool List0 = var.example_list[0] ObjectKey1 = var.example_object.key1 ObjectKey2 = var.example_object.key2 } }
最後に、terraformコマンドを実行する際に変数の値を設定する方法を解説します。
コマンド実行時に値を設定する変数は、前述の別ファイルで管理する場合と同様にvariableブロックを使って定義しておきます。そして、コマンド実行時に-varというオプションを付けて変数の値を設定します。
$ terraform apply -var="example_string=example" \ -var="example_number=123" \ -var="example_bool=true" \ -var='example_list=["a","b","c"]' \ -var='example_object={"key1":"example","key2":456}'
設定した値の使用方法も、前述の別ファイルで管理する場合と同様です。なお、別ファイルで定義した上で、同時にコマンドで変数の値を指定した場合は、コマンドで指定した値が優先されます。
変数として定義したいものの中には、「Amazon Relational Database Service(Amazon RDS)」の認証情報など、機密情報を含むことがあるかと思います。そこで、次のようにTerraformのコードを書いてみましょう。ユーザー名とパスワードを変数扱いにして、どちらも機密情報として扱います。
variable "db_username" { type = string } variable "db_password" { type = string } resource "aws_db_instance" "example" { db_name = "example" engine = "aurora-mysql" engine_version = "5.7" instance_class = "db.t3.small" username = var.db_username password = var.db_password }
このTerraformのコードに対してterraform planを実行するとどうなるでしょうか。次のような出力結果になります。
$ terraform plan -var="db_username=example" -var="db_password=examplepassword" Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_db_instance.example will be created + resource "aws_db_instance" "example" { (中略) + password = (sensitive value) (中略) + username = "example" + vpc_security_group_ids = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ─────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
passwordについては「(sensitive value)」という表示になっていますが、usernameはそのまま表示されています。ここも、passwordと同様に「(sensitive value)」という表示で内容を隠したいと思います。db_usernameの定義部分を次のように修正します。
variable "db_username" { type = string sensitive = true }
これで、先ほどと同じterraform planコマンドを実行すると、username部分の値が「(sensitive value)」という表示になり、意図した通り隠すことができました。
$ terraform plan -var="db_username=example" -var="db_password=examplepassword" Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_db_instance.example will be created + resource "aws_db_instance" "example" { (中略) + password = (sensitive value) (中略) + username = (sensitive value) + vpc_security_group_ids = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ─────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
今回紹介した変数を活用することでTerraformのコードの再利用性を高め、より実践的なクラウド環境の構築が可能になります。ぜひ、変数を駆使してより高度で、大規模な環境の構築にチャレンジしてみてください。
サイオステクノロジー所属。OSS よろず相談室でサポート対応をしているテクニカルサポートエンジニア。Ansible に出会ってから自動化に取り憑かれ、自身の業務やプライベートであらゆるものの自動化に取り組む。プライベートでは Java でちょっとしたツールの開発を趣味にしている。
Copyright © ITmedia, Inc. All Rights Reserved.