Pushing on with Mastermndio's free Terrform course!
- It would help if you did the previous classes
- Input variables can be applied across multiple environments/workspaces
- Input Variables
- Modules
- Output Variables
- Practice!
HCL allows you to use variables for making dynamic configurations
These variables can be used to specify values for parameters and args that may change, depending on how you're using the config. They can be placed in files with these formats:
- variables.tf
- terraform.tfvars
- terraform.tfvars.json Then you reference the variables contained within, in your main config file
Environment variables are prefixed with TF_VAR_
We declare variables like a resource in our configuration
We're going to have a play with variables and how they integrate with the Terraform.
The relevant documentation
HCL is stongly typed, so you need to remember to declare this too, e.g.:
variable "image_id" {
type = string
}
You can also set a default:
variable "availability_zone_names" {
type = list(string)
default = ["us-west-1a"]
}
We're going to set a variable in the main infrastructure.tf
file, and call it with var.<variableName>
- In this case, it's
ami = var.machine_image
If nothing is passed to the machine_image variable, the default gets passed instead.
You can also add custom validation (syntax in documentation linked above), e.g. checking an AMI image by counting the chars in the passed variable, checking it begins with "ami"...
- Create
variables.tf
in the root and link from there
- Assign variables here:
machine_image = "ami-xyz"
instance_size = "t3.small"
server_num = 5
Any variables in here will override anything else. You can only assign variables, not declare them.
- Run
terraform plan
to see which vars make it to the execution plan (spoiler: it's the variables in the.tfvars
file)!
variables.tf
is where the variables are created, and terraform.tfvars
is where you assign them.
A .tfvars file is used to assign values to variables that have already been declared in .tf files, not to declare new variable. To declare variable "test", place this block in one of your .tf files, such as variables.tf
To nest a value for this variable in terraform.tfvars, use the definition syntax instead:
test = <value>
A module is a container for multiple resources that are used together. Every Terraform config - when you run plan
or apply
- form the root module, which consists of the resources defined in the .tf files in the main working directory.
You can grab modules from the Terraform Registry.
Modules are self-contined packages of Terraform configurations that are managed as a group.
- Put a .tf file in a folder, in the root directory.
- Call the module from the root module
This is like using a function/method/class in software development. Whenever you make changes, you can do it in the module (not the root)
- Make a folder and file called
blog/blog.tf
- Copy and paste your resources (S3 bucket, in our case) from
infrastructure.tf
into the blog file - import the module:
module "blog" {
source = "./blog"
}
-
Run
terraform apply
to see the module's resources now included in the execution plan. -
Create a module for the EC2 instances, then import the module
At this point the input variables stopped working on the EC2 instance, and I reverted back to hard-coding the values (as Aaron did in his tutorial)
UPDATE: Scoping applies to modules, and vars would need to be moved to their respective module folders.
Used to pass info between modules, and for debugging.
e.g. (known after apply) messages - once known, we can get the info held and pass them to modules as variables
They only output after apply
, not after a plan
.
If you now run terraform output
the variable and value will be returned to the terminal.
Let's find out what that public ip address is!
In the relevant module (in this case, the one for the EC2 instance, devInstances.tf
). We have to go there because that's where the resource we want the output for is being created:
output "test_var" {
value = aws_instance.developmentServer[*].private_ip
}
In the root (i.e. infrastructure.tf
) add this to the file:
output "real_test" {
value = module.devInstances.test_var
}
- Lots of practice writing variables and learning the order of precedence they're applied in:
.tfvar
>.tf
>default
- We learned about modules - isolating the code from the root file, how to create and call them
- Output variables - how to extract values and pass them around, how they only get applied after changes have taken effect, for debugging
- Terraform's Registry to find already existing modules.
Part 4, of course!