Skip to content

Latest commit

 

History

History
183 lines (126 loc) · 6.1 KB

File metadata and controls

183 lines (126 loc) · 6.1 KB

6. The Hashicorp Programming Language


Primitive Data Types

Variables and locals are typed data There are three primitive data types

  • string: A Unicode string
  • numeric: Used for both integral and non-integral values (434 and 1.34)
  • boolean: true and false
  • null: a value that represents absence or omission. If an argument of a resource is null, evaluation of the the argument behaves as though had been completely omitted it.
    • A variable will use the argument's default value if it has one, or raise an error if the argument is mandatory.

For example, we could have the following locals definitions

locals {
    name = "App Server"
    port = 8080
    private = true
    }

Why Data Types

Type Safety

  • Error Checking: Allows type checking during plan and apply phases to catch errors early if an incorrect data type is passed to a parameter expecting a specific type
  • Predictable Behavior: Ensures that operations on these types behave as expected such as mathematical operations are meaningful with numeric types

Clarity and Intent

  • Clear Intent: Using the appropriate data type makes the intention of the code clearer to anyone reading it
  • Simplified Syntax: Numeric and boolean types allow for a more straightforward and concise syntax.

Efficiency

  • Optimized Performance: Operations on numeric and boolean types are generally more efficient than their string equivalents.
  • Resource Planning: Terraform directives that are conditional or need some form of counting work best with boolean and numeric yptes
  • Validation: Stricter validation rules can be enforced on on input variables and configuration parameters when types are explicitly defined
  • Terraform Functions: Terraform includes built-in functions that operate specifically on certain types

Heredoc Strings

Terraform haa "heredoc" string literal type which allows multi-line strings to be expressed clearly

A heredoc string consists of:

  • An opening sequence consisting of:
    • A heredoc marker (<< or <<- — two less-than signs, with an optional hyphen for indented heredocs)
    • A delimiter word of your own choosing
    • A line break
  • The contents of the string, which can span any number of lines
  • The delimiter word you chose, alone on its own line (with indentation allowed for indented heredocs)

Example

message = <--MSRT
this is the body of the message
and more stuff
MSRT

These are often useful for multiline directives like start up scripts.


Complex Data Types

These are similar to the equivalent types in most programming languages

list (or tuple): a sequence of values, like ["alpha", "bext"] indexed starting a 0/

set: a collection of unique values with no specific ordering.

map (or object): a group of values identified by named labels, like {name = "Server", port = 80}

We will explore data types and operations on them in more detail later on.


Directives

Declarative languages, like Terraform, normally do not have typical programming constructs like loops and conditional statements

However, there are many scenarios that require the conditional configuration of resources

  • For example, creating a module that creates resources only for certain users and not others
  • Or creating different sizes of VMs depending on the environment we are deploying into - a small one for "dev", two medium-sized ones for "test" and four large ones for "prod"

Terraform directives allow certain kinds of operations to enable dynamic and conditional configuration

  • While these constructs behave in analogous ways to the constructs in programming languages, they do look syntactically different

Loops

Terraform has several loop constructs to provide looping functionality in different scenarios

  • count parameter: to loop over resources
  • for_each expressions: to loop over resources and inline blocks within a functionality
  • for expressions: to loop over lists and maps
  • for string directive: to loop over lists and maps withing a string

Loops with "count"

The looping procedural code is implied and generated under the hood by terraform

We specify the number of iterations with the count, which often represents the number of copies of a resource

The following code creates three instances with the names VM-0 , VM-1 and VM-2

It also goes through a list of owners and assigns each owner to a machine. First in the variables.tf file, the list of owners is defined.

variable "server_owners" {
   description = "List of server owners"
   type = list(string)
}

Notice that the data type is a list of strings and is assigned a value in the terraform.tfvars file

ami_type = "ami-080e1f13689e07408"
inst_type = "t2.nano"
server_owners = ["accounting","marketing","R&D"]

in the main.tf file, the VM definition has the count directive set to 3. This means that there will be three copies of the VM created. For each iteration the value count.index contains the numeric current value of count

resource "aws_instance" "the_servers" {
  count = 3
  instance_type = var.inst_type
  ami           = var.ami_type
  tags = {
    owner = var.server_owners[count.index]
    Name = "VM-${count.index}"
  }
}

Running this code with terraform apply produces three servers.

aws_instance.the_servers[1]: Creating...
aws_instance.the_servers[0]: Creating...
aws_instance.the_servers[2]: Creating...

Referring to Instances

Because we defined three copies of the server with the Terraform name the_servers, we actually created a list of servers called [the_servers[0], the_servers[1], the_servers[2]]

To see this, we can output tags of the second server.

output "marketin_server_tag" {
    value = aws_instance.the_servers[1].tags
} 

And when we run terraform apply and ask for the tags, we get back a map of the tags.

Outputs:

marketin_server_tag = tomap({
  "Name" = "VM-1"
  "owner" = "marketing"
})

Conceptually, you can think of the the_servers directive being inside a for loop with a loop index count that starts at 0 and does three interations.