0% found this document useful (0 votes)
16 views15 pages

Terraform Locals

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views15 pages

Terraform Locals

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 15

Chapter 8 - Locals

Locals in detail
A local is Terraform’s representation of a normal programming languages’s variable.
Confusingly
Terraform also has a concept called a variable which is really an input, variables
are covered in
chapter 10. A local can refer to a fixed value such as a string or it can be used
to refer to an expression
such as two other locals concatenated together or the attribute of a resource that
you have created.
Lets dive into an example. Create a new folder in your workspace and create a
single file inside it
called main.tf and copy in the following code (or if you want to grab the code from
the samples
repository copy the folder local_example_01):
1 provider "aws" {
2 region = "eu-west-1"
3 }
4
5 locals {
6 first_part = "hello"
7 second_part = "${local.first_part}-there"
8 bucket_name = "${local.second_part}-how-are-you-today"
9 }
10
11 resource "aws_s3_bucket" "bucket" {
12 bucket = local.bucket_name
13 }
In the code above we define a local block by using the keyword locals and then an
opening {.
We then define each local on a new line by giving it a name. The first local we
define is called
first_part. You then follow it with an = and then give it a value. For the
first_part local we
are giving it the value of the string literal hello. For the second local
second_part we are using
the value "${local.first_part}-there". As the whole expression is inside quotes we
need to use
the ${ and } around our expression so Terraform evaluates it. To reference a local
you use the
expression syntax local.local_identifier. So the second_part local will be set to
“hello-there”.
In the bucket_name local we are using the second_part local in the expression "$
{local.second_-
part}-how-are-you-today" which will evaluate to hello-there-how-are-you-today.
At the bottom of the project we are defining an S3 bucket and setting the name to
local.bucket_-
name, so this will create an S3 bucket with the name hello-there-how-are-you-today.
Note we
do not need the ${ and } as we are not inside quotes here. We could also have set
the bucket to
Chapter 8 - Locals 29
"${local.bucket_name}", which would have evaluated to the same thing. But since
Terraform 0.12>
we can now omit the ${ and } for a single line expression where we are using the
whole value. Which
I think makes the code cleaner and easier to read. As we are defining our
infrastructure as code the
easier it is to read the better.
To run the project go to the terminal and cd into the folder where you created the
file main.tf.
Run terraform init and then terraform apply. When prompted say yes if you want to
run in the
project. This will create the S3 bucket with the name hello-there-how-are-you-
today. To destroy
this infrastructure run terraform destroy and then confirm.
Locals referencing resources
Locals can reference the output of a resource or a data source by using the
expression syntax we
have learnt. This allows you to give something a more meaningful name or to combine
outputs from
different resource and data source attributes to build up a more complex value.
Chapter 9 - Templates and Files
Files
We have seen in a previous chapter how you can place a multi line string as a value
for a property.
This is useful for something like an IAM policy. It can be even cleaner to move the
value out into
a file and then reference that file from your project. Doing this can remove the
clutter from your
project and make it much more readable.
Lets see an example of using files, create a new folder, create a file called
main.tf (or copy the code
from the folder file_example_01 in the examples repository) and paste in the
following code:
1 provider "aws" {
2 region = "eu-west-1"
3 version = "~> 2.27"
4 }
5
6 resource "aws_iam_policy" "my_bucket_policy" {
7 name = "list-buckets-policy"
8 policy = file("./policy.iam")
9 }
Next if you are creating the code yourself, create another file called policy.iam
and paste in:
1 {
2 "Version": "2012-10-17",
3 "Statement": [
4 {
5 "Action": [
6 "s3:ListBucket"
7 ],
8 "Effect": "Allow",
9 "Resource": "*"
10 }
11 ]
12 }
This IAM policy creates a policy that gives list bucket permission to any bucket.
If you look at the
Terraform code you will see we are configuring the AWS provider as we are going to
be connecting
Chapter 9 - Templates and Files 31
to AWS. Then we are defining an AWS IAM policy. Instead of placing the policy
inline as we did in
a previous chapter, we are referencing the policy from the file policy.iam. To do
this we are calling
the file function and passing in the argument as to where the file is. Note this is
a relative file path
from our current location.
When we run this project by doing terraform init and terraform apply and confirm by
typing
yes, Terraform will create the IAM policy you can see in the file and name it list-
buckets-policy.
Templatefile function
Sometimes we want to use a file but we do not know all of the values before we run
the project or
some of the values are dynamic and generated as a result of a created resource. To
be able to use
dynamic values in a file we need to use the templatefile function.
The templatefile function allows you to define placeholders in a template file and
then pass their
values at runtime.
Lets dive into a simple example to see how it works… Create a new folder and create
a file called
main.tf (or copy the templatefile_example_01 folder from the examples repository)
and paste in
the following code:
1 locals {
2 rendered = templatefile("./example.tpl", { name = "kevin", number = 7})
3 }
4
5 output "rendered_template" {
6 value = local.rendered
7 }
Next if you are creating the code yourself and not using the examples repository
then create another
file in the directory called example.tpl and place the following text:
1 hello there ${name}
2 there are ${number} things to say
Lets walk through the code we have written so we can understand what is going on.
We are defining
a local (as we learnt in the previous chapter) called rendered. We are setting the
value of the local
(remember a local can have a value that is an expression) to the result of calling
the templatefile
function. The template file function takes two arguments. The first argument is the
path to the
template file, in this example we are using the relative path between the main.tf
and the template
file example.tpl so the path is ./example.tpl. The next parameter is a set of
variables that you want
replacing in your template. We are passing in a value for name (kevin) and number
(7). Note you could
Chapter 9 - Templates and Files 32
set the value of these variables to any expression such as another local or an
attribute from a created
resource or a data source.
If you look at the example template code we use the syntax ${<variable_name>} when
we want to
reference a passed in variable. Terraform will replace ${name} in our template with
the value passed
in for name, it will do the same with ${number}.
We are then using an output to output the rendered value of the template out to the
terminal. This
is an easy way for us to see how the templatefile function works.
Lets see templates in action. Go to your terminal, change directory into the new
project folder you
have just created and run terraform init and then terraform apply. You will see the
following
output rendered:
1 Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
2
3 Outputs:
4
5 rendered_template =
6 hello there kevin
7 there are 7 things to say
You can see that Terraform replaced the placeholders in our template with the
values that we
provided to the templatefile function. So you see the message with kevin and 7 in
it rather than
the placeholders.
Loops in a template
You can pass in an array of values into a template and loop round them. Lets take a
look at an
example of how to do that. Create a new folder, create a file called main.tf (or
grab the code from
the folder templatefile_example_02 in the examples repository) and paste in the
following code:
1 output "rendered_template" {
2 value = templatefile("./backends.tpl", { port = 8080, ip_addrs = ["10.0.0.1",
"10.\
3 0.0.2"] })
4 }
Next create a file called backends.tpl and paste in the following:
Chapter 9 - Templates and Files 33
1 %{ for addr in ip_addrs ~}
2 backend ${addr}:${port}
3 %{ endfor ~}
This time we are just rendering the template straight to the output. Notice that we
are passing in
an array for ip_addrs. In the template we are then looping around the ip_addrs
array by using a
foreach loop. To do a foreach loop you use the syntax %{ for <var> in
<variable_name #} where
<var> is any identifier you want to use to reference the current looped item and
<variable_name>
is the name of the array that is passed into the template. All of the lines you now
write are inside
the loop until you signal the end of the loop by putting %{ endfor #}. Notice that
inside the loop
we are using the current value from the ip_addr array and we are always referencing
the port.
When we run the above project (by doing terraform init and terraform apply) you
will notice
the following output is rendered for the template:
1 backend 10.0.0.1:8080
2 backend 10.0.0.2:8080
The word backend is constant as that is just text so we see that for each iteration
around the loop. The
current element of the ip_addr array is then printed followed by the passed in
port, which always
has the value 8080.
The fact that we can combine loops with interpolated values means that you can
write some quite
elaborate templates. These can be really useful for programmatically generating
things like IAM
policies, where you can pass in the ARN of resources that Terraform creates and use
them as part
of the template.
Chapter 10 - Variables
Variables
A Variable in Terraform is something which can be set at runtime. It allows you to
vary what
Terraform will do by passing in or using a dynamic value.
Our first Variable
Lets dive into an example of how to use variables, so we can learn how they work.
Create a new
folder and create a file called main.tf inside that folder (or simply grab the code
from the examples
repository in the folder variables_example_01) and copy in the following code:
Chapter 9 - Templates and Files 34
1 provider "aws" {
2 region = "eu-west-1"
3 version = "~> 2.27"
4 }
5
6 variable "bucket_name" {
7 description = "the name of the bucket you wish to create"
8 }
9
10 resource "aws_s3_bucket" "bucket" {
11 bucket = var.bucket_name
12 }
You declare a variable by using the keyword variable then you specify the
identifier for the variable
in quotes, we are using "bucket_name" as the identifier. Inside the variable block
we are adding a
description to describe to the user what this variable is used for. The description
parameter is
completely optional, we could have defined the variable as follows:
1 variable "bucket_name" {}
The reason that it is a good idea to provide a description as it gives the user
some instruction as to
what values to use and what the variable is used for.
To use the value of a variable in your Terraform code you use the syntax
var.<variable_-
identifier>. You can see that we are setting the bucket property on the
aws_s3_bucket resource
to the value of our variable var.bucket_name. This means that whatever value we
give our variable
Terraform will use as the name of the S3 bucket.
Run the project by opening your terminal, changing into the directory where you
have created the
project and running terraform init and then terraform apply. Terraform will pause
and you will
see the following output:
1 var.bucket_name
2 the name of the bucket you wish to create
3
4 Enter a value:
Terraform has paused because it is asking you to provide a value for the variable.
The variable name
is printed to the screen and underneath is the description we provided. Note if you
do not set a
description then only the variable name will be shown here. Type in a bucket name
that you think
will be unique. I used kevholditch-variable-bucket but it really doesn’t matter
what value you
use. Press enter and then you will notice that Terraform will pause again and ask
if you want to
apply the changes. Type yes and create the bucket. Terraform will have created the
bucket with a
name of whatever value you gave it.
Chapter 9 - Templates and Files 35
Once you have run the project go ahead and destroy it again by running terraform
destroy.
Terraform will ask you for a value for the variable again, it doesn’t actually
matter what value
you give it this time as the variable is not needed for Terraform to destroy the
bucket. Press enter
and then type yes when Terraform asks you if you really want to destroy the
project.
Variable defaults
Create another project and create a file called main.tf (or copy the code from
variables_example_-
02) and paste in the following code:
1 provider "aws" {
2 region = "eu-west-1"
3 version = "~> 2.27"
4 }
5
6 variable "bucket_name" {
7 description = "the name of the bucket you wish to create"
8 }
9
10 variable "bucket_suffix" {
11 default = "-abcd"
12 }
13
14 resource "aws_s3_bucket" "bucket" {
15 bucket = "${var.bucket_name}${var.bucket_suffix}"
16 }
We have extended the first example and added a second variable "bucket_suffix" and
we have set
its default to "-abcd". Setting a default on a variable means that if you do not
provide a value for
that variable then the default will be used. We are then using the value of the
bucket_name variable
concatenated with the value of the bucket_suffix variable for the value of the
bucket name. As
we are using the values inside a string we need to surround our variables with $
{ and }. Otherwise
Terraform will not use the value of the variable and instead would just print the
string var.bucket_-
name.
Run the project (terraform init, terraform apply). Terraform will ask you to
provide a value for
bucket_name as before. Enter a name for the bucket and press enter. Notice that
Terraform will now
ask you to confirm the run by typing yes. Confirm the run and press enter.
Terraform will then
go and create the bucket. You may be wondering why Terraform never asked you for a
value for
bucket_suffix, well it is because Terraform does not need a value for bucket_suffix
as you already
gave it a default value of -abcd. The end result is that a bucket will be created
with whatever name
you enter for the bucket name with -abcd on the end of it.
Chapter 9 - Templates and Files 36
Setting a variable on the command line
Lets continue working with the project we have just created (variables_example_02
in the examples
repository). We are now going to learn how we can change the value of
bucket_suffix. As when
you run the project Terraform does not ask you for a value for it as we have just
learnt.
The first way we can set a value for bucket_suffix is by providing it on the
command line. Run
the following command terraform apply -var bucket_suffix=hello. Terraform will ask
you for a
value for bucket_name as you haven’t given it one and it does not have a default.
When the project
runs Terraform will now create a bucket with whatever name you gave it with hello
on the end.
To set the value of a variable on the command line you use the -var flag followed
by the variable
name and the value you wish to use. If we want to set both of the variables on the
command line
then we can do that with the command terraform apply -var bucket_name=kevholditch -
var
bucket_suffix=foo. In this command we are giving a value to both the bucket_name
and bucket_-
suffix. If you runrun the project with the command to set both variables then
Terraform will not
stop to ask you a value for the bucket_name. This is because you have now provided
one. Terraform
will stop and ask for a value of any defined variable that does not have a default
value or a value
set via the command line or one of the other ways we are going to learn.
Setting a variable using an environment variable
Another way you can set the value of a variable is by using an environment
variable. To do this set
an environment variable in your terminal using the convention
TF_VAR_<variable_identifier>. So
for our project (variables_example_02 in the examples repository) lets set
environment variables
for each of the variables. Follow the instructions below based on your OS:
Mac OS/Linux
1 export TF_VAR_bucket_name=kevholditch
2 export TF_VAR_bucket_suffix=via_env
Windows
1 set TF_VAR_bucket_name=kevholditch
2 set TF_VAR_bucket_suffix=via_env
Once you have set the environment variables run terraform apply. You will see that
now Terraform
will not ask you for a value for either variable and will use the values from your
environment
variables.
Chapter 9 - Templates and Files 37
Setting a variable using a file
The next way that you can set the value of variables is by using a file. Create a
new file in the project
called terraform.tfvars (or you can copy the project variables_example_03 from the
samples
repository). We are going to use the same Terraform code in the main.tf we had
before.
Inside the terraform.tfvars file place the following:
1 bucket_name = "kevholditch"
2 bucket_suffix = "from_file"
terraform.tfvars is a special file name that Terraform looks for to discover values
for variables.
Terraform will look in this file and use any values given for a variable. To set
the value of the variable
you simply put the variable identifier and then an equals sign and the value you
want to give it. We
are setting the value of both bucket_name and bucket_suffix in our file. So now
when we run the
project, Terraform will use those values for the variables and not ask us for them.
The other way we could have named our file was anything ending in .auto.tfvars.
Terraform
examines files with that ending for variables being set. It is also possible to
define multiple files and
put the value for different variables in each of them.
More complex variables
Lets look at a more complex example using a map and selecting a value from it with
variables. To do
this create a new project and create a file called main.tf (or copy the folder
variables_example_04
from the examples repository) and paste in the following code:
1 variable "instance_map" {}
2 variable "environment_type" {}
3
4 output "selected_instance" {
5 value = var.instance_map[var.environment_type]
6 }
Next create a file called terraform.tfvars where we can give these variables
values:
Chapter 9 - Templates and Files 38
1 instance_map = {
2 dev = "t3.small"
3 test = "t3.medium"
4 prod = "t3.large"
5 }
6
7 environment_type = "dev"
In our variables file we are setting instance_map to a map. A map is a collection
of values indexed
by a key name. We have set 3 keys in our map dev, test and prod. The values we have
given for
each of these keys are instance types to use in AWS. This map could be used to set
the instance
size based on the type of environment you are creating. Next we are setting the
environment_type
variable to dev. Look at the Terraform code we have written and you will see that
we are defining
the two variables instance_map and environment_type. At the bottom we are
outputting the value
in the map for the key specified by the environment_type variable.
If you run this project as is then it will output selected_instance = t3.small.
This is because
t3.small is the value in the map for the key dev and we have set the
environment_type to dev.
Change the environment type to one of the other values in the map, run the project
again and you
will see the output change.
As the map of instances is a variable we could dynamically change this too. So we
could have a
different terraform.tfvars file per department for example. Allowing us to vary the
instance sizes
used for different environment types by department.
Type constraints - Simple Types
So far we have been setting variables and not specified the type. This means that
whatever type you
pass to a variable will be the type that the variable assumes. A type constraint
allows you to specific
the type of a variable. There are 3 simple types string, number and bool.
To specify a type constraint use the type property when defining a variable. Lets
see an example of
using the 3 simple types. Create a new folder and a file called main.tf and paste
in the following
code (or grab the code from variables_example_05 if you are using the examples
repository):
Chapter 9 - Templates and Files 39
1 variable "a" {
2 type = string
3 default = "foo"
4 }
5
6 variable "b" {
7 type = bool
8 default = true
9 }
10
11 variable "c" {
12 type = number
13 default = 123
14 }
15
16 output "a" {
17 value = var.a
18 }
19
20 output "b" {
21 value = var.b
22 }
23
24 output "c" {
25 value = var.c
26 }
In this project we are defining 3 variables a, b and c. We are using the type
parameter to define a as
a string, b as a bool and c as a number. We are using defaults to set initial
values for these variables
so we do not have to worry about setting them using one of the techniques described
earlier is this
chapter and then we are outputting them by using outputs so we can see the values
of them.
By using a type constraint you make it illegal to set the variable to anything
other than the type
defined. So for example if you try and set b to "hello" or 123 and run Terraform
then Terraform will
print an error saying that the value you have provided is not compatible with the
type constraint.
There are a few interesting quirks with how the value you give is interpreted that
are worth knowing.
When you define the type to be bool then the following values will be valid true,
false, "true",
"false", "1" (evaluated to true), "0" (evaluated to false). The interesting part is
that "1" is valid but
1 (without the quotes) is not valid. Which may be puzzling at first. The reason
that this is the case
is that when you define a string (by using quotes) then Terraform will attempt to
evaluate what
is inside that string whereas if you do not use quotes then Terraform will just see
1 as a number
and not attempt to convert it to a bool. With a number any valid number will be
allowed with or
without quotes. If you specify quotes then you are essentially defining a string
but as long as the
Chapter 9 - Templates and Files 40
string only contains digits, Terraform will realise this and implicitly convert the
value to a number.
With a string any value in quotes will be allowed.
The fact that Terraform coalesces variables (attempts to see what a variable is) is
one of the reasons
that its a good idea to use a type constraint. Another reason is that it guides the
person using the
Terraform code as to what value to use for the variable and eases code readability.
As well as the 3 simple types above these types can be combined into the following
more complex
types:
• list(<TYPE>)
• set(<TYPE>)
• map(<TYPE>)
• object()
• tuple([<TYPE>, …])
For each of the complex types you can use another complex type type or simple type
where you see
the word <TYPE>. So you can have a list of number or a list of string or a list of
map of string.
Type constraints - List
A list is a list of a type. So you can have a list of strings like ["foo", "bar"]
or a list of number [2,
4, 7]. The type means that every element in the list will be that type.
Create a new folder and file called main.tf and paste in the following code (or
copy the code from
variables_example_06 in the examples repo):
1 variable "a" {
2 type = list(string)
3 default = ["foo", "bar", "baz"]
4 }
5
6 output "a" {
7 value = var.a
8 }
9
10 output "b" {
11 value = element(var.a, 1)
12 }
13
14 output "c" {
15 value = length(var.a)
16 }
Chapter 9 - Templates and Files 41
In the above code we are defining a list in variable "a". We are defining the list
to be a list of string.
To do this we use the word list and then put the type we want in brackets. Then to
set the value
for a list, you put the elements in between square brackets.
In the output variables the output variable "a" is simply printing the list.
Variable "b" is using
the inbuilt function element that can operate on lists. The HCL language provides
various inbuilt
functions to allow you to manipulate data. The element function takes a list as its
first argument and
a number for its second argument. The function will return the item at the element
given. Because
lists in HCL start from element 0 the value of output b will be "bar". In output
"c" we are using
another inbuilt function length. The length function takes a list and returns the
length of the list, so
the "c" will output 3. You can verify the output values by running the project by
doing terraform
apply. Play with the values so you get a feel for how lists work and how the
functions work.
Type constraints - Set
A set is almost exactly the same as a list, the key difference is that a set only
contains unique values.
Create a new folder and file called main.tf and paste in the following code (or
copy the code from
variables_example_07 in the examples repo):
1 variable "my_set" {
2 type = set(number)
3 default = [7, 2, 2]
4 }
5
6 variable "my_list" {
7 type = list(string)
8 default = ["foo", "bar", "foo"]
9 }
10
11 output "set" {
12 value = var.my_set
13 }
14
15 output "list" {
16 value = var.my_list
17 }
18
19 output "list_as_set" {
20 value = toset(var.my_list)
21 }
In the above example we are defining a variable called my_set and initialising it
to the set [7, 2, 2]
as I said above a set only contains unique values. So when you run this project by
doing terraform
Chapter 9 - Templates and Files 42
apply you will set that the output value set will print [7, 2]. Terraform removes
one of the 2 values
as it was a duplicate. To show how sets can be useful we are defining a list called
my_list where we
are repeating the value foo twice. The value of the list output will be ["foo",
"bar", "foo"] this
is because we are just outputting the value of my_list which is of type list and
lists can contain
duplicate values. For the output list_as_set we are using the toset function to
convert the my_list
variable to a set. The value of this output will be ["foo", "bar"]. Because we are
converting the
list to a set Terraform removes the duplicate value "foo".
Type constraints - Tuple
A tuple are a strongly typed collection of one or more values. So for example you
could define a
tuple of three values string, number, number or two values string, string. Once a
tuple is defined
it always has to contain the number of values as defined in that tuple. The values
also have to be
the correct type and in the correct order based upon type.
Create a new folder and file called main.tf and paste in the following code (or
copy the code from
variables_example_08 in the examples repo):
1 variable "my_tup" {
2 type = tuple([number, string, bool])
3 default = [4, "hello", false]
4 }
5
6 output "tup" {
7 value = var.my_tup
8 }
In the above Terraform code we are defining a tuple variable my_tup with 3 values
number, string,
bool. The syntax for defining a tuple uses the form tuple([TYPE, TYPE...]). As
stated above
because we are defining a tuple with 3 values we have to set it to a value with 3
values, hence
why we are initialising it to 4, "hello", false. If you run this example by doing
terraform apply
you will see that the output looks exactly like a list. You can kind of think of a
tuple as a defined list
where each element will always have a certain type and it will always be of a set
length.
Try adding another value to the default for my_tup e.g. set it to [4, "hello",
false, "hey"]. If you
try doing a terraform apply on this you will see that Terraform gives you an error.
This is because
the value you are giving the tuple no longer matches the definition.
Type constraints - Map
A map as we have already covered in this chapter is a set of values indexed by key
name. You can
give a map a type, the type will be the type of the values.
Chapter 9 - Templates and Files 43
Create a new folder and file called main.tf and paste in the following code (or
copy the code from
variables_example_09 in the examples repo):
1 variable "my_map" {
2 type = map(number)
3 default = {
4 "alpha" = 2
5 "bravo" = 3
6 }
7 }
8
9 output "map" {
10 value = var.my_map
11 }
12
13 output "alpha_value" {
14 value = var.my_map["alpha"]
15 }
In this project we are creating a map of type number. We are initialising the map
to have two keys
alpha and bravo, the values for the keys are 2 and 3 respectively. The fact that we
have specified
that the map is of type (number) means that all of the values have to match the
number constraint.
The map output value is going to print the whole map. We are also selecting a value
out of a map by
key using the [] syntax (as we have done previously in this chapter). The
alpha_value output will
print the value for the alpha key in the map which will be 2. Feel free to run the
project by using
terraform apply and get a feel for how the code is working.
Type constraints - Object
An object is a structure that you can define from the other types listed above. It
allows you to define
quite complex objects and constrain them to types. I think the easiest way to
explain it is to dive
straight into an example.
Create a new folder and file called main.tf and paste in the following code (or
copy the code from
variables_example_10 in the examples repo):
Chapter 9 - Templates and Files 44
1 variable "person" {
2 type = object({ name = string, age = number })
3 default = {
4 name = "Bob"
5 age = 10
6 }
7 }
8
9 output "person" {
10 value = var.person
11 }
12
13 variable "person_with_address" {
14 type = object({ name = string, age = number, address = object({ line1 = string,
li\
15 ne2 = string, county = string, postcode = string }) })
16 default = {
17 name = "Jim"
18 age = 21
19 address = {
20 line1 = "1 the road"
21 line2 = "St Ives"
22 county = "Cambridgeshire"
23 postcode = "CB1 2GB"
24 }
25 }
26 }
27
28 output "person_with_address" {
29 value = var.person_with_address
30 }
In the project above we are are first defining a variable called person. This
variable has two fields
a name which is of type string and an age which is of type number. To define the
object we specify
each field inside {} brackets. Each field has the form fieldname = type. We are
giving person some
default values. If you run this project by doing terraform apply you will see that
the person output
will contain the values we gave it Bob, 10. These values are constrained to the
types give so if you
tried to assign a string to the age field you would get a type constraint error.
One interesting thing
to point out here is that you are allowed to have different items with the same
name in Terraform.
In this project we have a variable with the identifier person and we have an output
with the same
identifier. This is allowed because one is a variable and the other is an output.
You are not allowed
to have two variables with the same identifier or two outputs.
Next we are defining a variable called person_with_address to show how you can nest
objects
to build up even more complex structures. The person structure is the same as
before except we
Chapter 9 - Templates and Files 45
have added the field address. The field address is in itself an object which
contains four strings
line1, line2, county, postcode. You can see when we initialise the variable we set
the address
by wrapping the values in a set of {} brackets. When you run the project you will
see the person_-
with_address structure printed out.
By using the same technique as above you can build up structures which are
arbitrarily complex.
Type constraints - Any type
The any type is a special construct that serves as a placeholder for a type yet to
be decided. any itself
is not a type, Terraform will attempt to calculate the type at runtime when you use
any.
Lets go into an example of using the any type. Create a new folder and file called
main.tf and paste
in the following code (or copy the code from variables_example_11 in the examples
repo):
1 variable "any_example" {
2 type = any
3 default = {
4 field1 = "foo"
5 field2 = "bar"
6 }
7 }
8
9 output "any_example" {
10 value = var.any_example
11 }
In the above example we are defining an object with the any type. Because we are
initialising the
object to a default value, Terraform will use this default value to figure out the
type of our variable
any_example. Terraform will give our variable the type object({ field1 = string,
field2 =
string}). We are then printing out the any_example variable using an output.

You might also like