Overview
Terraform is an automation tool focused on infrastructure provisioning. The product is developed by HashiCorp, and the command line version is provided as an Open Source Project available on GitHub.
Terraform has the following core components:
- Terraform CLI: stand-alone app that provides the run-time environment for Terraform Scripts and maintains build-state information of Managed Resources.
- Terraform Script: text file with Terraform Language code used to describe the required end-state of the Managed Resources.
- Managed Resource: logical representation of a real infrastructure resource in the target infrastructure.
- Terraform Provider: stand-alone apps (plugins) that are used by the Terraform CLI to interact with Managed Resources.
- Terraform Workspace: working directory in which Terraform Scripts are located and the Terraform CLI stores data files (state, temporary, plugins, etc.)
Using Terraform
CLI Installation
The recommended method for production environments is to add HashiCorp’s package repository to the OS package manager and install it using native tools.
For more relaxed environments the binary package provides a simpler alternative that does not require root privilege:
|
|
Running scripts
The execution process of Terraform Scripts is divided into stages:
init
: prepares the Terraform Workspace, sets run-time parameters, downloads, and installs providers.plan
: creates/updates state information of managed resources and executes a dry-run to create the change plan. For already existing resources, if the provider is unable to modify attributes on the fly it will propose a destructive change (remove and recreate the resource with the new end-state).apply
: executes the change plan, and updates resource state information. The provider will modify the target infrastructure by creating, updating and removing resources until the end-state is reached.
To execute the script the Terraform CLI must be already inside the workspace directory:
Notice that the user running the process doesn’t need root privilege, just write permissions to the workspace path.
Script structure
The first thing to understand about Terraform Scripts is that the Terraform Language is not for general-purpose development. Based on HCL (Hashicorp Configuration Language), it’s specifically designed to describe infrastructure resources.
Terraform Scripts are developed by defining blocks: a complex data structure that describes a configuration object through its attributes.
Use the following template for declaring blocks:
- BLOCK_TYPE: defines what type of configuration object is going to be described. Notice that Blocks can have any number of attributes and other blocks (nested).
- RESOURCE_TYPE: optional field used to select object subtypes. Not all objects will require one.
- RESOURCE_LABEL: optional field to assign a label (ID) to the object.
- ATTRIBUTE: name of the object’s attribute.
- VALUE: value that will be assigned to the object’s attribute.
The following list shows common built-in block types:
variable
: declare input parameter.output
: declare module output variable.local
: declare local variable.terraform
: provide project-wide terraform configuration settings.provider
: define and configure a terraform provider.resource
: configure a provider’s resource.data
: provided run-time information for a provider’s resource
Additional types and subtypes are implemented through Terraform Providers. For example:
Scripts can have comments anywhere:
//
: single-line comment. Anything at the right is ignored.#
: single-line comment. Anything at the right is ignored./* */
: multi-line comment. Anything between the delimiters is ignored.
As a good practice, after the script is created/updated run the built-in linter and code-formatter:
Using Variables
Declaration
As everything in Teraform, variables are also a block type. Use the following template to declare variables:
Data Types
Both variables and attributes have types:
string
: a sequence of Unicode characters.number
: integer or float numbers.bool
: boolean values.list
: indexed sequence of values. The index is numerical and starts at cero. VALUEs can be of any type.map
: group of key + value pairs. VALUEs can be of any type.null
: empty value.
Types are inferred from the value (i.e. no explicit data type declaration). For example:
Parameters
Parameters are variables that are used to provide run-time data to Terraform Scripts. They are declared using the variable
block type:
They are different from regular variables as they allow attributes to further describe the parameter:
default
: value that is assigned if none is provided.description
: text message that is used to describe the parameter.type
: expected variable type. This is not used to declare the type, but rather to constrain the provided value.validation
: validation block used to perform additional checks.sensitive
: flag to restrict script output. Used to mask sensitive values such as passwords.nullable
: flag to indicate if the value can be null.
For example:
Output
In addition to the local
and variable
block types, Terraform provides the output
type to define variables that will be exported and made available to external apps and scripts. The following attributes are available:
value
: the value assigned to the variable.description
: describe what the value represents.sensitive
: flag to restrict script output. Used to mask sensitive values such as passwords.
For example:
Retreive variable’s value
In general, block attributes (variables) can be referenced from within other blocks by using the following structure: BLOCK_TYPE.ATTRIBUTE
or BLOCK_TYPE.BLOCK_LABEL.ATTRIBUTE
In addition to the generic format there are special cases to consider:
- Locals: use
local
instead oflocals
:local.ATTRIBUTE
- Parameters: use the short form
var
instead of the full type namevariable
:var.ATTRIBUTE
- Outputs: prepend
module
to module name where the output is declared:module.MODULE_NAME.OUTPUT_NAME
- Data: prepend
data
to the data block name that provides the attribute:data.DATA_BLOCK_NAME.ATTRIBUTE
Variables can also be used in String Templates (simple programming code that can be embedded inside string declarations): "${BLOCK_TYPE.ATTRIBUTE}"
. The resulting string will replace the ${}
expression with the value of the variable.
The following example shows the three variable types seen so far:
|
|
Next Steps
Continue reading the second part of the tutorial: Terraform Scripting Concepts: Part 2 of 2
Copyright information
This article is licensed under a Creative Commons Attribution 4.0 International License. For copyright information on the product or products mentioned inhere refer to their respective owner.
Disclaimer
Opinions presented in this article are personal and belong solely to me, and do not represent people or organizations associated with me in a professional or personal way. All the information on this site is provided “as is” with no guarantee of completeness, accuracy or the results obtained from the use of this information.