Skip to content

4.0 - Modules and Workspaces

4.1 - DRY Principle

  • Focused on the aspect of software engineering - Don't Repeat Yourself
  • This aims to reduce the repetition of software patterns, such as defining functions for specific tasks where possible.
  • This can also be applied to Terraform, one can define resources as modules to be called repeatably.

  • Modules are typically defined in the following manner:

module "<module name>" {
    source = "/path/to/module"

    input_var = <value>
    ....
    ....
}
  • When Terraform is ran, it will check the defined source path to determine the configuration details.

4.2 - Module Implementation: EC2 Instance

  • Adopting the following Architecture:

  • Root

  • Modules
  • Projects

    • A
    • B
  • A sample EC2 Module can be created by adding the following to a file under modules

resource "aws_instance" "myec2" {
  ami           = "ami-0a13d44dccf1f5cf6"
  instance_type = "t2.micro"
  key_name      = "remote-exec-keypair"
  #configure provisioner with inline commands
  provisioner "remote-exec" {
    inline = [
      "sudo amazon-linux-extras install -y nginx1.12", #install nginx
      "sudo systemctl start nginx"
    ]
    connection {
      #connection method
      type = "ssh"
      user = "ec2-user"
      #private key for authentication
      private_key = file("./remote-exec-keypair.pem")
      host        = self.public_ip
    }
  }
}
  • This can then be referenced by any terraform files in the projects folder, which will pull all the required provider plugins alongside it.
  • Using modules makes things significantly easier for management and readability, as all configuration is stored and therefore managed in 1 place.
  • Similarly, any users unfamiliar to Terraform will not be overwhelmed when using the module, as they would only need to reference the module and add any required input variables.

4.3 - Variables and Terraform Modules

  • A common challenge with infrastructure management is the need to build environments, such as dev, staging, and production, with generally similar setups, but with slightly different variables.
  • Module variables cannot be overridden, if you wish to change the values of a property, you can create a variables.tf file to reference in the folder
  • Now, if a value is hardcoded in the source module, the variable value can be overwrote by any configuration referencing said module.
module "<module name>" {
    source = "/path/to/module"

    input_var = <value>
    ....
    ....
}

4.4 - Terraform Registry

  • A repository of modules written by the Terraform community.
  • Modules are typically developed by third parties, however some community-submitted providers are also available.
  • Hashicorp review modules for verification, and verified modules are actively maintained to remain up to date with Terraform and the respective providers.
  • In the Terraform registry, modules are typically supported with:
  • Usage examples
  • Documentation and Variable Usage Guidance
  • Using a module from Terraform Registry is similar to a standard module stored locally, just reference the source appropriately and specify any other parameters required.
  • terraform init will then reference this configuration and pull down the required files.

4.5 - Terraform Workspace

  • Workspace = Groupings of applications.
  • Terraform allows the use of multiple workspaces. Each workspace can use a set of environment variables.
  • This is often useful for running multiple environments on the same machine.

  • To utilize workspaces:

Command Definition
terraform workspace list List the existing workspaces
Current workspace denoted by *
terraform workspace select <workspace_name> Switch to a pre-existing workspace
terraform workspace new <workspace_name> Create a new workspace (automatically switches)
terraform workspace delete <workspace_name> Delete a particular workspace
Use -force to force deletion if not an empty workspace.
terraform workspace show Show current workspace details

4.6 - Implementing Terraform Workspace

  • Considering a scenario for a set of workspaces, with a variable that's subject to change from workspace-to-workspace.
  • Rather than having separate variables files, which would be hard to track and maintain, one can use a standalone variables file in a similar manner to the following:
variable "instance_type" {
    type = "map"
    default = {
        workspace1 = value1
        workspace2 = value2
        workspace3 = value3
    }
}
  • Using variables like this is achieved by: lookup(var.<var name>, terraform.workspace)

  • Each workspace's state file is stored in a new folder, terraform.tfstate.d. The default workspace's state file remains in the standard location.