#Terraform is #Easy #2: Structure of Terraform Configuration Language and its Syntax
Neelesh Ranjan Srivastava
Senior DevOps Engineer @IBM Cloud | Kubernetes & AWS Admin | Linux Fan | Cloud & Platform Specialist
Terraform Configuration Language (TCL) is Terraform’s primary user interface. Configuration files you write in Terraform language tell Terraform what plugins to install, what infrastructure to create, and what data to fetch. Terraform language also lets you define dependencies between resources and create multiple similar resources from a single configuration block.
Terraform Configuration Language (TCL) is essentially a subset of Hashicorp Configuration Language (HCL). The main purpose of the Terraform language is declaring resources, which represent infrastructure objects. All other language features exist only to make the definition of resources more flexible and convenient.
A configuration can consist of multiple files and directories. The Terraform language is declarative, describing an intended goal rather than the steps to reach that goal. The ordering of blocks and the files they are organized into are generally not significant; Terraform only considers implicit and explicit relationships between resources when determining an order of operations.
Syntax of Terraform Configuration Language
The syntax of the Terraform language consists of only a few basic elements:
Syntax:
<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
??# Block body
??<IDENTIFIER> = <EXPRESSION> # Argument
}
Example:
AWS VPC resource: resource "aws_vpc" "main" {
??cidr_block = var.base_cidr_block
}
Structure of Terraform Configuration
Terraform has a limited number of? predefined blocks that are used to declare a particular type of entity in your infrastructure:
Some of these blocks are:
Terraform Block
The terraform {} block contains Terraform settings, including the required providers Terraform will use to provision your infrastructure.?
For each provider, the source attribute defines an optional hostname, a namespace, and the provider type. Terraform installs providers from the Terraform Registry by default.?
In the example configuration below, the aws provider's source is defined as hashicorp/aws, which is shorthand for registry.terraform.io/hashicorp/aws.
terraform {
??required_providers {
????aws = {
??????source? = "hashicorp/aws"
?????version = "~> 4.16"
????}
??}
??required_version = ">= 1.2.0"
}
You can also set a version constraint for each provider defined in the required_providers block.?
The version attribute is optional, but is recommended so that Terraform does not install a version of the provider that does not work with your configuration.
?If you do not specify a provider version, Terraform will automatically download the most recent version during initialization.
Providers
A provider is a plugin that Terraform uses to create and manage your resources.
The provider block configures the specified provider, in this case aws.?
provider "aws" {
??region? = "us-west-2"
}
You can use multiple provider blocks in your Terraform configuration to manage resources from different providers. You can even use different providers together. For example, you could pass the IP address of your AWS EC2 instance to a monitoring resource from DataDog.
Resource
Resource blocks are used to define components of your infrastructure. A resource might be a physical or virtual component such as an EC2 instance, or it can be a logical resource such as a Heroku application.
Resource blocks also contain arguments which you use to configure the resource. Arguments can include things like machine sizes, disk image names, or VPC IDs.?
Resource blocks have two strings before the block: the resource type and the resource name.?
For example:
领英推荐
resource "aws_instance" "app_server" {
??ami ? ? ? ? ? = "ami-830c94e3"
??instance_type = "t2.micro"
??tags = {
????Name = "ExampleAppServerInstance"
??}
}
In this example, the resource type is aws_instance and the name is app_server.?
The prefix “aws” in “aws_instance”, maps to the name of the provider.?
Here, terraform is managing the aws_instance resource with the aws provider. Together, the resource type and resource name should form a unique ID for the resource. Here, its is? “aws_instance.app_server”.
You can always google and dive into your resources arguments, inputs or outputs.
Like for the above, you can visit the terraform registry on aws_instance, https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
Modules
Modules are containers for multiple resources that are used together. A module consists of a collection of .tf and/or .tf.json files kept together in a directory.
Modules are the main way to package and reuse resource configurations with Terraform.
The Root Module
The top level directory of your terraform config is the Root Module of your terraform project.?
With the above statement you could easily infer that every Terraform configuration has at least one module, known as its root module, which consists of the resources defined in the .tf files in the main working directory.
Child Modules
A Terraform module (usually the root module of a configuration) can call other modules to include their resources into the configuration. A module that has been called by another module is often referred to as a child module.
Child modules can be called multiple times within the same configuration, and multiple configurations can use the same child module.
Published Modules
In addition to modules from the local filesystem, Terraform can load modules from a public or private registry. This makes it possible to publish modules for others to use, and to use modules that others have published.
The Terraform Registry hosts a broad collection of publicly available Terraform modules for configuring many kinds of common infrastructure. These modules are free to use, and Terraform can download them automatically if you specify the appropriate source and version in a module call block.
Also, members of your organization might produce modules specifically crafted for your own infrastructure needs. HCP Terraform and Terraform Enterprise both include a private module registry for sharing modules internally within your organization.
For Example:
module "my_eks" {
??source? = "terraform-aws-modules/eks/aws"
??version = "20.8.5"
??cluster_name? ? = "my_lovely_cluster”
??cluster_endpoint_public_access ? ? ? ? ? = false
??enable_cluster_creator_admin_permissions = true
??cluster_addons = {
????aws-ebs-csi-driver = {
??????service_account_role_arn = module.irsa-ebs-csi.iam_role_arn
??????resolve_conflicts? ? ? ? = "OVERWRITE"
??????addon_version? ? ? ? ? ? = "v1.31.0-eksbuild.1"
????}
????aws-mountpoint-s3-csi-driver = {
??????service_account_role_arn = module.irsa-s3-csi.iam_role_arn
??????resolve_conflicts? ? ? ? = "OVERWRITE"
??????addon_version? ? ? ? ? ? = "v1.7.0-eksbuild.1"
????}
??}
Summary
These are all the syntax, structure and components you will encounter, in general, and play with in most of your terraform deployments.
It's all about the different variations/types of the above that will be actually used to define different infrastructure at different lengths. In the next iteration of the #Terraform is #Easy series, I will discuss more in-depth about the terraform modules, and how it is a very powerful tool to provision various kinds of Infrastructure. Till then, keep exploring and?
All the Best !! ????