Using modules in Terraform and managing the state of infrastructure

Purpose of using modules in Terraform -

As per Terraform documentation, Modules are containers for multiple resources that are used together. A module consists of a collection of .tf files kept together in a directory.

Modules are the main way to package and reuse resource configurations with Terraform.

Challenge:

We need to deploy infrastructure across three environments: production, development, and testing. Without modules, this requires duplicating similar Terraform code for each environment, leading to inefficiency and inconsistency.

Solution:

By using Terraform modules, we can avoid redundant code and ensure uniformity. Modules package infrastructure components, allowing easy reuse across environments. This promotes consistency, eases maintenance, and enhances collaboration.

Below are the steps -

Create the Main Configuration: Start by creating a terraform.tf file in your main project directory. This file will house the main Terraform configuration.

Declare Provider for AWS: Inside the terraform.tf file, define the provider block to specify that you are using AWS as your cloud provider.

Infrastructure Configuration and Variables: Create a my_infra.tf file in the main directory. Within this file, declare variables like the region, s3_bucket (for state storage), and state_table (for DynamoDB lock).

Module Directory Setup: Create a folder named infra_project to hold your modules. Inside this folder, place separate .tf files for each module: my_bucket.tf, my_server.tf, my_table.tf, and a variable.tf file for module-level variables.

Define Main Configuration Using Modules: In the main directory, create a main.tf file. Within this file, use the module blocks to instantiate the modules you defined earlier. Provide values for the source attribute, and set module-specific variables such as my_env, instance_type, and ami.

Declare Variables in Modules: Inside the infra_project folder, in the variable.tf file, define the variables that will be used in our modules. This step ensures a clear structure and consistency in variable usage.

Reuse Modules for Infrastructure: Utilize the variables defined earlier to create the bucket, server, and table across all your modules. This reuse simplifies the Terraform configuration and promotes consistency.

Initialize and Apply: Run terraform init in your main project directory. This command initializes Terraform and installs the necessary providers and modules. Then, execute terraform apply to create your infrastructure. Notice that the initialization phase prioritizes module setup. The infrastructure was created successfully. Now, we need to create the backend using the backend block under Terraform. (Pasting the end of output due to long screenshot - 14 objects created)

Backend Configuration: After successful infrastructure creation, it's time to set up the backend. In your terraform.tf file, add a backend block. This specifies the configuration for where your state files will be stored.

Init for Backend Initialization: Run terraform init once again. This time, Terraform will configure the backend and start saving state files in the S3 bucket you've specified.

With the backend setup, your Terraform workflow is now efficient and well-organized. We've created infrastructure modules that can be reused and managed independently, while state management is also streamlined through the S3 backend.

By following these steps, we've structured our Terraform project in a clear and systematic manner, making it easier to collaborate, maintain, and manage infrastructure as code.

Thank you :)