Cookies Psst! Do you accept cookies?

We use cookies to enhance and personalise your experience.
Please accept our cookies. Checkout our Cookie Policy for more information.

Terraform Module Gotchas - Inline block example S3 AWS

Software is all about composition.

GitHub repository

Modules

Modules are the key ingredient for writing reusable, maintainable code. When planning to deploy AWS infrastructure, it's better to leverage this functionality and be aware of the common gotchas to avoid conflicts with other Terraform configurations.

Terraform

Terraform and Infrastructure as Code are no exceptions. We should use modules to create and compose our building blocks,
just as we use functions to compose and create our business logic.

There are two gotchas we need to be aware of when using modules in Terraform:

  • File paths
  • Inline blocks

Inline blocks

When we use modules, we should be careful with inline blocks, although they allow you to define some properties in the
resource, it comes with a trade-off.
We lose the flexibility to define and customize the resource properties in the root module.

Module structure

There are also the possibility of conflicts between the inline blocks and the module properties, which can lead to
unexpected results.

Finally, inline blocks have been deprecated in Terraform maybe for these reasons.

module "s3_bucket" {
  source = "../modules/separate-resource"
  name   = "jorgetovar"
}


resource "aws_s3_bucket_versioning" "versioning" {
  bucket = module.s3_bucket.bucket_name
  versioning_configuration {
    status = "Enabled"
  }
}

Defining Terraform configuration within both the module itself and the file that uses the module can lead to several issues

Deprecation

Complexity

We should organize our modules in a way that we can easily interact with a part of the infrastructure without having to
understand the whole system.
Our job is to remove the accidental complexity and make the system easier to understand. When we use inline blocks, we
are adding complexity to the system (properties and thing that we may not need to know about).

Abstractions

But we can also leverage abstractions and hide some details that are unnecessary, if all the buckets that we create have
versioning, maybe it makes more sense to move that resource to the module.

File Paths

By default, Terraform uses the path relative to the current working directory, in our case, the localhost root module.
Therefore, the module should be able to read files from its folder instead of the one where we are currently executing
the commands.

We can leverage the path variables of terraform to read the files that are in the module folder.The path variables are :

  • Path.module : The path to the module folder
  • Path.root : The path to the root module folder
  • Path.cwd : The path to the current working directory
templatefile("${path.module}/${element(local.templates, count.index)}"

Module structure

Conclusion

Terraform modules may be the best way to deploy our resources in AWS, but we must be aware of the challenges that come with this useful feature.

Modules allow us to create abstractions and reduce the complexity of our infrastructure.

If you enjoyed the articles, visit my blog jorgetovar.dev

Last Stories

What's your thoughts?

Please Register or Login to your account to be able to submit your comment.