The previous blog post explained the fundamentals of using Terraform and how to get started. Giving you a short summary, we learnt what Terraform is and why it is useful. We also set up our own Virtual Machine on AWS and went over the basic Terraform commands and the Terraform block all using Infrastructure as a Code (IaaS).
The depths of Terraform are unfathomable, and what we covered only scratched the surface. We hope to close this knowledge gap and get you one step closer to the next level of proficiency. In this course, you will learn Terraform thoroughly, with an emphasis on its block and variables.
Consequently, let’s get into action.
Terraform Settings, Providers and Resources Block
Terraform Settings Block
Terraform settings block is used to configure behavior of your Terraform manifests. Each terraform block can have a variety of Terraform-related settings. Only constant values may be used within a Terraform block; arguments may not relate to named objects such as resources, input variables, and so on, nor may they use any of the Terraform language’s built-in functions. Terraform Settings block include Terraform version, list of required providers and Terraform backend.
The required version variable allows for the addition of a version constraint string, which outlines which versions of Terraform are compatible with your setup and must be utilized.
If the version of Terraform that is running does not conform to the requirements that have been stated, Terraform will generate an error and then leave without carrying out any more operations.
In order for Terraform to be able to successfully install and make use of the various providers, each Terraform module is required to indicate which providers are necessary. The required providers block is where the requirements for the providers are defined.
A local name, a source location, and a version constraint are the three components that make up a provider requirement.
The location of the state data files that Terraform uses is specified by a backend.
Terraform makes use of data that is persisted in the state it is now in in order to maintain a record of the resources it maintains. The vast majority of non-trivial Terraform setups either interact with Terraform Cloud or make use of a backend in order to save state in a distant location. Because of this, multiple users are able to access the data that the state maintains and collaborate on the gathering of infrastructure resources.
Provider Block is the heart of the Terraform. Here, we define the rules that interact with the remote system(basically, cloud provider). Provider configurations reside in the root module of terraform. The configuration residing in the Terraform provider block differs according to the provider. For example, Google provider block is very different from AWS.
As you can see each provider block requires the provider, in our case aws. If you intend to create/delete/modify a resource you need to specify the region where this operation will take place. Needless to say, Terraform internally calls AWS API to execute the actions defined in the resource block.
But, Terraform needs to authenticate you to do so. This is done using Access keys. There are two ways to do this. You can either pass the keys directly into the block, which is not recommended and is called static configuration. Other way round you can configure your credentials by running aws configure command and pass these credentials as a profile name.
Each resource block describes one or more Infrastructure Objects. A resource block specifies the local name and resource type (in this case, “aws instance”) of a resource (“web”). While the name is relevant inside the context of the same Terraform module, it has no meaning outside of it.
The combination of a resource’s type and name serves as its identification; this identifier must be distinct across all instances of the module.
The resource’s configuration parameters are located in the block’s body, between and. The resource type determines the relevance of most of the arguments in this section; for example, the ami and instance type arguments in this example are unique to the aws instance resource type.
Resource type is required while creating a resource. It defines the resource we are creating.
Resource local label
Resource local label as the name suggests is the local variable name with which we will be referencing this resource object. This has to be unique for obvious reasons, as it will be used with functions.
Terraform State Files
Terraform state is the database for the terraform. Terraform must store information about your managed infrastructure and configuration. Terraform uses this state to map real-world resources to your configuration, keep track of metadata, and make large infrastructures run faster.
By default, this state is kept in a local file called “terraform.tfstate,” but it can also be kept remotely, which is better in a team setting.
Terraform uses this local state to make plans for your infrastructure and make changes to it. Before any operation, Terraform does a refresh to make sure that the state matches the real infrastructure.
Terraform state’s main job is to keep track of the connections between objects on a remote system and resource instances that you’ve set up in your configuration. When Terraform creates a remote object in response to a change in configuration, it stores the identity of that remote object with a specific resource instance. If the configuration changes again, the object could be updated or deleted.
Terraform Input Variables
With the help of input variables, certain aspects of Terraform modules can be changed without having to change the source code of the module itself. You can use the same modules in different Terraform setups because of this feature. This makes your module something that can be added to and used again.
Using command-line interface (CLI) options and environment variables, you can change the values of variables you define in the root module of your configuration.
Each input variable accepted by a module must be declared using a variable block.
Terraform CLI defines the following optional arguments for variable declarations:
default – A default value which then makes the variable optional.
type – This argument specifies what value types are accepted for the variable.
description – This specifies the input variable’s documentation.
validation – A block to define validation rules, usually in addition to type constraints.
sensitive – Limits Terraform UI output when the variable is used in configuration.
nullable – Specify if the variable can be null within the module.
By specifying a type argument within a variable block, you can limit the data types that can be used to fill up the variable’s value. When no type restriction is in place, any value may be used. Supported type keywords are: string,number, and bool
You can use the type constructors to define intricate types like collections:
- object(ATTR NAME> = TYPE>,…, )
The description should briefly explain the variable’s function and the anticipated value. For inclusion in documentation, this string should be written from the module’s end user’s point of view rather than the developer who created it. Comments are intended to provide context for module maintainers.
One can specify custom validation rules for a particular variable by adding a validation block within the corresponding variable block. This is to check correct formatting/values expected by the providers.
Setting a variable as sensitive prevents Terraform from showing its value in the plan or apply output, when you use that variable elsewhere in your configuration. These values are hidden in plan and apply stages.
The nullable argument in a variable block controls whether the module caller may assign the value null to the variable.
Output variables provide a convenient way to get useful information about your infrastructure. As you might have noticed, much of the server details are calculated at deployment and only become available afterwards. Using output variables you can extract any server-specific values including the calculated details.
It’s really not hard to set up output variables. All you have to do is give the output a name and tell it what value it should have. For example, you could use the output variable below to make Terraform show the IP address of your server after deployment.
Note that the place of the public network interface on the list of network interfaces depends on the order the NICs are defined in the resources.
The public IP address would then be shown at the end of the apply command process by Terraform. Alternatively, output variables can also be called on-demand using the Terraform output command. Set up a variable file for the server configuration next.
Defining variables in a file
You should already have a Terraform project set up with a simple plan. If not, follow our guide to getting started with Terraform. Go to the folder that holds your Terraform project.
Variables for Terraform can be set up in the infrastructure plan, but it’s best to keep them in their own variables file. All of the.tf files in your Terraform directory will be automatically loaded when you run an operation.
Make a file called variables, like variables.tf. This is what variables look like when declared in a file.
Managing infrastructure with Terraform variables has several benefits. Setting up separate files for your deployment strategy and configuration information will help you stay organized. Variables keep your manifests clean and help you get the task done without having to write manifest for each task, in short it makes your manifest agnostic. This is what variables are for.
We will be covering more topics and demo projects in the blogs to come. We can now move towards complex projects. Do suggest any project that you think we can take up in the next blog. Stay Tuned!