Parameterizing Terraform
Note
The code for this section is in chap01/parameterizing-terraform
.
So far, we have provisioned a server that doesn’t really do anything. To conclude this first chapter, let’s expand on it to demonstrate the power of IaC. First, we add variables to make our code more generic. In Terraform, you need to declare variables in a variable block. While you can declare variables anywhere in your code, by convention, it is best to declare them in a file called variables.tf
. No argument is required for a variable declaration, but it is a good idea to define the type and a description and, if useful, to add a default value. You can also add validation and specify that the variable contains a sensitive value, but more on that later:
variables.tf
variable "project_id" { type = string description = "ID of the Google Project" } variable "region" { type = string description = "Default Region" default = "us-central1" } variable "zone" { type = string description = "Default Zone" default = "us-central1-a" } variable "server_name" { type = string description = "Name of server" } variable "machine_type" { type = string description = "Machine Type" default = "e2-micro" }
Variables are referenced using the var.<variable_name>
syntax. Thus, our parameterized main.tf
file now looks like this:
main.tf
resource "google_compute_instcance" "this" { name = var.server_name machine_type = var.machine_type zone = var.zone boot_disk { initialize_params { image = "debian-cloud/debian-11" } } network_interface { network = "default" access_config { // Ephemeral public IP } } metadata_startup_script = file("startup.sh") tags = ["http-server"] }
We made two minor additions to the google_compute_instance
resource. We added the access_config
block to the network_interface
block, which assigns a public IP address to the server, and added an http-server
network tag. This allows HTTP traffic to reach the server using the default-allow-http
firewall rule. (Please note that this firewall rule is created the first time you provision a compute instance and enable Allow HTTP traffic
in the web console or in gcloud
. Thus, if you haven’t done so in your current project, please do so, as Google Cloud automatically creates this firewall rule. Later, we show how to create firewall rules using Terraform).
There are multiple ways to assign a value to a variable. First, you can specify a default value in the declaration. Second, you can pass it as a value either interactively or via the command-line flag. One of the common ways to specify variable values is in the variable definitions file or .tfvars
file. This file contains only variable assignments for the form variable = value
form. You will learn the usefulness of tfvars
in the third chapter:
terraform.tfvars
project_id = <PROJECT_ID> server_name = "parameterizing-terraform"
Note
You need to replace <PROJECT_ID>
with the ID of your Google Cloud project.
The second change we can make is to configure a web server automatically. As we said earlier, there is some overlap between IaC and configuration management. You can include startup scripts to perform some configuration code once the server is deployed. Configuration management tools provide much more functionality, and you should use the startup scripts only for basic configuration. Alternatively, you can use the startup script to run the configuration management tool. Our startup script installs the Apache web server and adds the obligatory “Hello
World
” text:
startup.sh
#! /bin/bash apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Hello World!</p></body></html>
Lastly, we can use the output block to output the public IP address of the server (don’t worry about the syntax—we elaborate on that later). Again, we use the convention to place the output block in a file named outputs.tf
:
outputs.tf
output "instance_ip_addr" { value = google_compute_instance.this.network_interface.0.access_config.0.nat_ip }
Thus, you should now have the following files in your current directory:
├── main.tf ├── outputs.tf ├── provider.tf ├── startup.sh ├── terraform.tfvars └── variables.tf
Terraform provisions the server, and then output its IP address. Copy the IP address and paste it into a browser. If you get a timeout error, ensure that the default-allow-http
firewall rule is set.
While we defined the default machine type as e2-micro
, we can override any variable value on the command line using the -
var
flag.
Thus, the following command provisions the equivalent server but with an e2-small
machine type:
$ terraform destroy $ terraform apply -var machine_type=e2-small
As we conclude this chapter, it is a good idea to clean up your environment and remove servers and resources you don’t need anymore. So, if you have not done so, run the following command:
$ terraform destroy
Confirming that you removed all unnecessary servers using the web console is also a good practice.