Terraform 入門から精通まで（variable）

## 概要
Terraformで変数（variable）の使い方をご紹介させていただきます。

## 1.tfファイルに定義
```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region = "ap-northeast-1"
  access_key = "xxxxxx"
  secret_key = "xxxxxx"
}
resource "aws_vpc" "test-vpc" {
  cidr_block       = "10.0.0.0/16"
  tags = {
    Name = "test-vpc"
  }
}

variable "test-subnet-cidr-block" {
    description = "cidr block for subnet"
    default = "10.0.1.0/24"
    type = string
  
}

resource "aws_subnet" "test-subnet" {
  vpc_id     = aws_vpc.test-vpc.id
  cidr_block = var.test-subnet-cidr-block
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "test-subnet"
  }
}
```
subnetのcidr_blockの値を変数(test-subnet-cidr-block)として、定義します。
terraform applyを実行すると
```
% terraform apply

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_subnet.test-subnet will be created
  + resource "aws_subnet" "test-subnet" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "test-subnet"
        }
      + tags_all                                       = {
          + "Name" = "test-subnet"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.test-vpc will be created
  + resource "aws_vpc" "test-vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_classiclink                   = (known after apply)
      + enable_classiclink_dns_support       = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name" = "test-vpc"
        }
      + tags_all                             = {
          + "Name" = "test-vpc"
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_vpc.test-vpc: Creating...
aws_vpc.test-vpc: Creation complete after 2s [id=vpc-0ac4ffc8acc29bf57]
aws_subnet.test-subnet: Creating...
aws_subnet.test-subnet: Creation complete after 1s [id=subnet-072e2d3252f4d9bd7]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
```
AWSのコンソールに確認すると、subnetを正常作成しました。
![截屏2022-07-12 12.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/909334c6-c465-b420-0384-f75dfb6830c7.png)

実は変数のdefault値を設定しなくても、大丈夫です。terraform applyを実行際に、コンソールで変数を渡せます。
例えば、変数（test-subnet-cidr-block）のdefault値をコメントアウトします。
```
variable "test-subnet-cidr-block" {
    description = "cidr block for subnet"
    #default = "10.0.1.0/24"
    type = string
  
}

resource "aws_subnet" "test-subnet" {
  vpc_id     = aws_vpc.test-vpc.id
  cidr_block = var.test-subnet-cidr-block
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "test-subnet"
  }
}
```

terraform applyを実行すると以下のメッセージが表示されます。
```
terraform apply                 
var.test-subnet-cidr-block
  cidr block for subnet

  Enter a value: 
```
10.0.2.0/24を渡します。AWS側で10.0.2,0/24サブネットを作成しました。
![截屏2022-07-12 12.09.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/0182be1f-a46b-4422-4284-fedf161c4f7e.png)

## 2.コマンド引数による指定
```
terraform apply -var "変数名=value"
```
test.tf内容
```
resource "aws_vpc" "test-vpc" {
  cidr_block       = "10.0.0.0/16"
  tags = {
    Name = "test-vpc"
  }
}

variable "test-subnet-cidr-block" {
    description = "cidr block for subnet"
    #default = "10.0.1.0/24"
    type = string
  
}

resource "aws_subnet" "test-subnet" {
  vpc_id     = aws_vpc.test-vpc.id
  cidr_block = var.test-subnet-cidr-block
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "test-subnet"
  }
}
```
以下のコマンドを実行すると
```
terraform apply -var "test-subnet-cidr-block=10.0.100.0/24"

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_subnet.test-subnet will be created
  + resource "aws_subnet" "test-subnet" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.100.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "test-subnet"
        }
      + tags_all                                       = {
          + "Name" = "test-subnet"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.test-vpc will be created
  + resource "aws_vpc" "test-vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_classiclink                   = (known after apply)
      + enable_classiclink_dns_support       = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name" = "test-vpc"
        }
      + tags_all                             = {
          + "Name" = "test-vpc"
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_vpc.test-vpc: Creating...
aws_vpc.test-vpc: Creation complete after 2s [id=vpc-0ea24cdeffdec3418]
aws_subnet.test-subnet: Creating...
aws_subnet.test-subnet: Creation complete after 1s [id=subnet-0455e13a3df198517]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
```
AWS側で確認すると10.0.100.0/24サブネットを作成しました。

![截屏2022-07-12 14.41.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/d9721128-ccd6-f4f8-83ea-d3757705d377.png)


## 3.設定ファイルによる変数を指定
terraform.tfvarsというファイルを作成します。以下のコードをterraform.tfvarsに書き込みます。

```
test-subnet-cidr-block = "10.0.200.0/24"
```
test.tfファイルに以下のコードを書き込みます。
```
resource "aws_vpc" "test-vpc" {
  cidr_block       = "10.0.0.0/16"
  tags = {
    Name = "test-vpc"
  }
}

variable "test-subnet-cidr-block" {
    description = "cidr block for subnet"
    #default = "10.0.1.0/24"
    type = string
  
}

resource "aws_subnet" "test-subnet" {
  vpc_id     = aws_vpc.test-vpc.id
  cidr_block = var.test-subnet-cidr-block
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "test-subnet"
  }
}
```

terraform applyを実行すると10.0.200.0/24サブネットを作成しました。
![截屏2022-07-12 17.40.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531066/23b14856-c734-0aef-5b53-4fb218a0ea77.png)

### --var-fileで変数定義ファイルを指定できます。

例えば
terraform1.tfvarsというファイルを作成します。以下のコードを書き込みます。
```
test-subnet-cidr-block = "10.0.199.0/24"
```


変数ファイルを指定します。
```
terraform apply --var-file terraform1.tfvars

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_subnet.test-subnet will be created
  + resource "aws_subnet" "test-subnet" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "ap-northeast-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.0.199.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "test-subnet"
        }
      + tags_all                                       = {
          + "Name" = "test-subnet"
        }
      + vpc_id                                         = (known after apply)
    }

  # aws_vpc.test-vpc will be created
  + resource "aws_vpc" "test-vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.0.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_classiclink                   = (known after apply)
      + enable_classiclink_dns_support       = (known after apply)
      + enable_dns_hostnames                 = (known after apply)
      + enable_dns_support                   = true
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name" = "test-vpc"
        }
      + tags_all                             = {
          + "Name" = "test-vpc"
        }
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

```
以上となります。