terrafrom
variables.tf vs terraform.tfvars
variables.tf simply defines the variables used in your project.
Every variable requires two things:
The declaration of the variable, which is what variables.tf is doing. In other words, telling Terraform & the reader, what variables you need.
Initializing the variable, which is what terraform.tfvars is doing. In other words, every variable NEEDS a value. terraform.tfvars simply populates the variable with values.
As /u/ArieHein mentioned, you can use the .tfvars extension to populate the variable with values, but one key difference with terraform.tfvars vs. like, dev.tfvars, is that terraform.tfvars is automatically loaded when you run terraform plan, apply or destroy.
Variables.tf is for the declaration of variables, name, type, description, default values and additional meta data.
*.tfvars
is for giving the actual variable values during execution. It allows you to customize the specific execution. A good example will be variable values that are specific to an environment like number to vms or the type/tier/sku of a database and similar.
Since you can supply files on the command line you can have scenarios where you supply different *.tfvars
file like
terraform plan --file-name dev.tfvars
terraform plan --file-name prod.tfvars
Dynamic configuration
How to write this configuration shorter
host {
name = "mysql-node-a"
zone = "ru-central1-a"
subnet_id = yandex_vpc_subnet.private-a.id
}
host {
name = "mysql-node-b"
zone = "ru-central1-b"
subnet_id = yandex_vpc_subnet.private-b.id
}
host {
name = "mysql-node-c"
zone = "ru-central1-c"
subnet_id = yandex_vpc_subnet.private-c.id
}
Do this
locals {
zones = {
central_a = {
zone_name = "ru-central1-a"
private_subnet = ["192.168.20.0/24"]
}
central_b = {
zone_name = "ru-central1-b"
private_subnet = ["192.168.21.0/24"]
}
central_c = {
zone_name = "ru-central1-c"
private_subnet = ["192.168.22.0/24"]
}
}
dynamic "host" {
for_each = local.zones
content {
zone = host.value.zone_name
subnet_id = yandex_vpc_subnet.private[host.key].id
name = "db-host-${host.key}"
}
Note: Local values are created by a locals block (plural), but you reference them as attributes on an object named local (singular). Make sure to leave off the "s" when referencing a local value!
A local value can only be accessed in expressions within the module where it was declared.
Terraform local using each
locals {
zones_k8s = {
a = {
zone_name = "ru-central1-a"
public_subnet = ["192.168.10.0/24"]
private_subnet = ["192.168.50.0/24"]
}
b = {
zone_name = "ru-central1-b"
public_subnet = ["192.168.11.0/24"]
private_subnet = ["192.168.51.0/24"]
}
c = {
zone_name = "ru-central1-c"
public_subnet = ["192.168.12.0/24"]
private_subnet = ["192.168.52.0/24"]
}
}
}
resource "yandex_vpc_subnet" "public" {
for_each = local.zones_k8s
zone = each.value.zone_name
network_id = yandex_vpc_network.vpc-0.id
v4_cidr_blocks = each.value.public_subnet
}
Terraform create two workspaces
To create two Terraform workspaces, "stage" and "prod", with separate configurations, you can follow these steps:
- Navigate to your working directory /home/username/terraform.
- Initialize your Terraform configuration by running terraform init in the working directory.
- Create the "stage" workspace by running terraform workspace new stage. This will create a new workspace and switch to it.
- Create a subdirectory named "stage" within the working directory to store the specific configuration files for the "stage" workspace.
- Place the desired Terraform configuration files for the "stage" workspace inside the "stage" subdirectory.
- Repeat steps 3-5 to create the "prod" workspace and its respective subdirectory.
Each workspace can have its own separate configuration files, allowing you to manage different sets of infrastructure resources independently. Remember to switch between workspaces using terraform workspace select
Terraform variable from environment
In Terraform, environment variables can be used to set variables. The environment variables must be in the format TF_VAR_variablename
and these will be used as the default value for the corresponding variable if no other value is provided.
Then, in your main.tf file, you can then reference this value like a normal variable:
variable "variablename" {}
In the above, var.variablename
will have the value of the TF_VAR_variablename
environment variable.