zaki work log

作業ログやら生活ログやらなんやら

[Terraform] 変数を定義・参照する

ハードコーディングしていた変数を別ファイルに定義してみる。

記事中のCIDRが172.26.だったり172.25.だったりしてるのはあまり意味なくて例示用。

元の定義ファイル

zaki-hmkc.hatenablog.com

上記では、こんな内容のVPCを定義したTerraformのファイルを作成していた。

resource "aws_vpc" "practice" {
  cidr_block = "172.26.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-aws-study-example"
  }
}

なのですが、VPCに設定している、"172.26.0.0/16"というネットワークのCIDRは定義内に直接指定するより、変数ファイルに記述した方が再利用性高いよね、ということで変数を定義してみる。

variableで変数定義

learn.hashicorp.com

拡張子が.tfであれば(変数定義とか関係なくTerraformの定義ファイルとして)実行時に読み込まれるので特にファイル名は何でもよいが、ここではvariables.tfで以下の内容のファイルを作成。
定義ファイル内でvariableを使用することで変数定義ができる。

書式はvariable "変数名" { ... }

variable "vpc_cidr_block" {
    description = "CIDR Block of VPC"
    type        = string
    default     = "172.26.0.0/16"
}

変数を参照するVPCの定義部分は以下の通り。

resource "aws_vpc" "practice" {
  cidr_block = var.vpc_cidr_block
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-aws-study-example"
  }
}

これでplan実行すると、

[zaki@cloud-dev practice (main)]$ terraform plan
:
:
  # aws_vpc.practice will be created
  + resource "aws_vpc" "practice" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "172.26.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
:
:

今回はvariables.tfという変数定義用のファイルを別途作成したが、定義場所は別にどこでもよいので、変数を参照する同じファイルの先頭とかでも問題ない。

変数のセット

terraform.tfvarsで変数セット

variableに「デフォルト値」を定義できるけど、このデフォルト値を上書きする変数定義ファイルを別途使うこともできる。
ファイル名はterraform.tfvars固定。
(※ オプションでファイル名指定可能)

以下参照。
Assign values with a terraform.tfvars file

あくまでvariableを使って変数定義を行った変数に対して、指定の値をセットするというものなので、variableで定義していない変数は扱えないので注意。

追加で以下のvariableを定義。

variable "prac_public_cidr_block" {
    description = "CIDR Block of Public Subnet"
    type        = string
    default     = "172.26.10.0/24"
}
variable "prac_private1_cidr_block" {
    description = "CIDR Block of Private1 Subnet"
    type        = string
    default     = "172.26.20.0/24"
}
variable "prac_private2_cidr_block" {
    description = "CIDR Block of Private2 Subnet"
    type        = string
    default     = "172.26.30.0/24"
}

サブネットの変数の参照箇所は以下の通り。

resource "aws_subnet" "prac_public" {
  vpc_id            = aws_vpc.practice.id
  cidr_block        = var.prac_public_cidr_block
  availability_zone = "ap-northeast-1a"

  tags = {
    Name = "public-subnet-aws-study"
  }
}

で、terraform.tfvarsには以下のように変数セット。

vpc_cidr_block = "172.25.0.0/16"
prac_public_cidr_block = "172.25.10.0/24"

実行すると以下の通り。

[zaki@cloud-dev practice (main)]$ terraform plan

:
:

  # aws_subnet.prac_public will be created
  + resource "aws_subnet" "prac_public" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = "ap-northeast-1a"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "172.25.10.0/24"

:
:

  # aws_vpc.practice will be created
  + resource "aws_vpc" "practice" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "172.25.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)

コマンドライン引数でセット

以下参照。
Variables on the Command Line

terraform.tfvarsファイル以外に、-varオプションで変数セットもできる。
Ansibleでいうextra varsみたいな感じかな?

$ terraform plan -var='prac_public_cidr_block=172.26.60.0/24'

:
:

  # aws_subnet.prac_public will be created
  + resource "aws_subnet" "prac_public" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = "ap-northeast-1a"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "172.26.60.0/24"
      + id                              = (known after apply)

:
:

こんな感じ。

環境変数でセット

以下参照。
Set values with environment variables

環境変数も使用可能。
その場合、環境変数名はTF_VAR_をprefixに付与しておけば、そのあとの変数名をTerraform定義ファイル内で参照できる。

[zaki@cloud-dev practice (main)]$ export TF_VAR_prac_private2_cidr_block="172.26.120.0/24"
[zaki@cloud-dev practice (main)]$ terraform plan

:
:

  # aws_subnet.prac_priv2 will be created
  + resource "aws_subnet" "prac_priv2" {
      + arn                             = (known after apply)
      + assign_ipv6_address_on_creation = false
      + availability_zone               = "ap-northeast-1c"
      + availability_zone_id            = (known after apply)
      + cidr_block                      = "172.26.120.0/24"
      + id                              = (known after apply)
      + ipv6_cidr_block_association_id  = (known after apply)

変数参照の優先順位

以下参照。
Variable Definition Precedence

  1. 環境変数
  2. terraform.tfvarsファイル
  3. terraform.tfvars.jsonファイル
  4. *.auto.tfvarsファイルか*.auto.tfvars.jsonファイルを辞書順
  5. -var-var-fileによる指定

環境変数が一番弱く、設定されていてもterraform.tfvarsファイルがあれば上書きされる。

-varはやっぱAnsibleのextra varsと同じって認識でよさげね。

環境

[zaki@cloud-dev practice (main)]$ terraform -version
Terraform v0.15.1
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.37.0

サンプルコード

github.com