Technology

Terraform Meta-Arguments

Terraform Meta-Arguments

How to use Terraform Meta-Arguments

What is Terraform?

As an infrastructure as code tool, Terraform allows building, changing, and versioning infrastructure, including compute instances, storage, and networking; as well as DNS entries and SaaS features.

Why Meta-Arguments used?

Meta-arguments are used in Terraform to control how resources are created, updated, or destroyed. They are not specific to any particular resource type, but instead provide an interface for configuring behaviours across all resources.

A meta-argument in Terraform is used to control the dependencies between resources. Below are the different meta-arguments we used.

  1. depends_on
  2. count
  3. for_each
  4. provider
  5. lifecycle

depends_on:

Terraform has a feature of identifying resource dependency. this meta-argument can be used to specify that a resource depends on another resource. When creating resources, which require other resources to exist first.

 

 

In the above example, the “aws_instance” resource block contains a “depends_on” argument that references the “aws_s3_bucket” resource block.

By doing this, terraform will know that the instance resource depends on the bucket resource, so it should only be created or modified after the bucket resource is created or modified.

Depends_on only affects the order in which resources are created or modified.

It’s important to note that the depends_on argument only affects the order in which resources are created or modified. It does not affect the actual order of destruction. So, when you are going to destroy the resources, it will not wait for the dependent resources to be destroyed.

count: 

Resource blocks in Terraform configure only one infrastructure object by default. If we want multiple resources with same configurations, we can define the count meta-argument. Duplicating the resource block that number of times will reduce overhead.

count require a whole number and it will create the resource number of times, Using the count, we can identify each one, we use the count. index which is the index number corresponds to each resource. Indexes range from 0 to count-1.

Both resources and modules specify this argument. In addition, count meta-argument cannot be used with for_each.

 

 

If we run the code using terraform commands, then instances will be created like below.

aws_instance. techify_instance[1]: Creating…
aws_instance.techify_instance [0]: Creating…
aws_instance.techify_instance[3]: Still creating… [10s elapsed]
aws_instance.techify_instance[2]: Still creating… [10s elapsed]

How to use Count with conditional:

 

In this example, creating instance only when aws_region variable equals us-east-1. Hence, if it’s equal, the count value will be 1 and if it’s not, it will be zero, which means we won’t create that resource.

for_each:

An infrastructure resource can be replicated in a more flexible way using the for_each meta-argument. A resource block, a data block, or a module block can use it. It works with a map or a set of strings, and it creates an instance for each item in the set.



Here we have used another Terraform function toset. Lists are converted to sets, which are unordered collections of unique values.

The for_each meta-argument used in any block type also comes with each object available. A similar resource can be customized by using each object.

Additionally, this object has two properties:

  • each.key: for a set is the values of a set. it is the map’s key, e.g. {map_key: “map_value”}
  • each.value for a set is the same as each.key. it is the associated value for the key.

 

Here variable as set, there is no need for type conversation

 

 

The map type in Terraform is a type constructor that can be used to build up complex types. It is of the form map(<TYPE>), where TYPE can be a type constraint like a string or even a type constructor like an object.

In the example above, multiple AWS EC2 instances are created using a map of objects.

Each instance techify_one and techify_two consists of a string and a map of string as values. The object each.value in the resource block references the map keys like instance_type and tags.

provider: 

This meta-argument allows you to specify a specific provider configuration for a resource or module. The purpose of this is to associate a resource with a specific provider if you have defined multiple providers in your Terraform configuration.

 

 

For more info (https://developer.hashicorp.com/terraform/language/meta-arguments/resource-provider)

lifecycle:

In a resource block, there is a nested block called lifecycle. Lifecycle blocks and their contents are meta-arguments, available to all resource blocks.

The arguments available within a lifecycle block are create_before_destroy, prevent_destroy, ignore_changes, and replace_trigger_by.

create_before_destroy:

In Terraform, when an object needs to be destroyed and recreated, it will normally create the new object after the old one is destroyed. Using this attribute will create the new object first, then destroy the old one. It can help reduce downtime, but some objects have restrictions that might cause issues, preventing them from coexisting.

 

prevent_destroy:

The lifecycle option prevents Terraform from accidentally removing critical resources. It is useful to avoid downtime when a change would require destroying and recreating a resource. As this block will prevent certain configuration changes from being made, it should only be used when necessary.

 

ignore_changes:

Terraforms ignore changes feature is useful when resources are created with references to data that may change in the future, but those changes should not affect the resource after its creation.

 

 

Terraform to ignore changes to the tags.Name attributes. This means that if you were to update the Name tag value in the configuration and apply it with terraform apply, terraform would not attempt to update the EC2 instance resource. Instead, it would leave it as-is.

Conclusion:

Finally, meta-arguments are a powerful feature of Terraform that can be used to control the behavior of resources in a flexible and granular way. Terraform users can create more robust and scalable infrastructure as code by effectively using meta-arguments.