Infrastructure as a Code using Terraform Modules (Part-I)

  • Configuration Orchestration is the tool that is used to build and provision server instances themselves, making them run on the cloud.
  • Then configure management tools could work and install certain dependencies and libraries used to run your application.
  • Orchestration is not required when we work on small nodes or containers, there we can use simple configuration management tools.
  • When we work on different clusters then we need an orchestration tool that keeps a check that all resources are working fine or not.
  • If there is any issue the orchestrator tool will remove the damaged resource and will replace it with another.
  • Terraform is considered as one of the best configuration orchestration tools which
  • Configuring Management is the tool that is used to install and manage the dependencies and software over the server instances.
  • After the configuration orchestration tools have set up the instances and resources these tools then come to function by installing certain dependencies, packages, scripts, config files on each instance.
  • These tools install dependencies on top of the infrastructure making it suitable to run our application.
  • There are many configuration management tools such as Chef, Puppet, Ansible which work on different nodes and manage the configurations.

Terraform — An orchestration Tool

  • Run terraform init. This command first checks whether there is a configuration file or not. If the file is present it initializes the backend means the environment on which terraform would run. Then it will download the plugins according to the provider you choose.
  • Run terraform plan. This command tells us prior that which actions are gonna be executed and which resources are gonna made after we applied this code.
  • Run terraform apply. This command will tell us the actions and resources which are gonna set up and asks for confirmation from the user. The + sign in the prefix of each resource states that these resources are gonna added. Answer YES and this command will start setting up the infrastructure. At last, if all goes good it will print the number of resources created.
  • Similarly, if you need to destroy your instances write terraform destroy. This command will tell us the actions and resources which are gonna remove and asks for confirmation from the user. The sign in the prefix of each resource states that these resources are gonna removed. Answer YES and this command will start destroying up the infrastructure. At last, if all goes good it will print the number of resources destroyed.

Terraform Modules

  • Understanding and navigating the configuration files will become increasingly difficult.
  • Updating the configuration will become riskier, as an update to one section may cause unintended consequences to other parts of your configuration.
  • There will be an increasing amount of duplication of similar blocks of configuration, for instance when configuring separate dev/staging/production environments, which will cause an increasing burden when updating those parts of your configuration.
  • You may wish to share parts of your configuration between projects and teams, and will quickly find that cutting and pasting blocks of configuration between projects is error-prone and hard to maintain.
$ tree minimal-module/ . 
├── LICENSE
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
  • Use the public Terraform Registry to find useful modules. By reading and studying the verified modules you could actually gain a lot of confidence and could help a lot in writing your own module.
  • Use local modules to organize and encapsulate your code. Even if you aren’t using or publishing remote modules, organizing your configuration in terms of modules from the beginning will significantly reduce the burden of maintaining and updating your configuration as your infrastructure grows in complexity.
  • Publish and share modules with your team. Most infrastructure is managed by a team of people, and modules are an important way that teams can work together to create and maintain infrastructure. You could publish your modules in a public or a private registry according to the requirements.

Terraform Public Modules

  • Open a file named asmain.tf and create a module block named ec2-instance and write the source and version from the web page. Then you also have to initialize some variables in the module so that you could provision your infrastructure in your environment.
  • In order to use most modules, you will need to pass input variables to the module configuration. The configuration that calls a module is responsible for setting its input values, which are passed as arguments in the module block. Aside from source and version.Some input variables are required, meaning that the module doesn’t provide a default value — an explicit value must be provided in order for Terraform to run correctly. Now create a variable.tf and initialize the variables which we used in the module.
  • Modules also have output values, which are defined within the module with the output keyword. You can access them by referring to module.<MODULE NAME>.<OUTPUT NAME>. Like input variables, module outputs are listed under the outputs tab in the terraform registry.Create an output.tf file and make the output variables initialized of your own choice or just copy the below file.
  • Run terraform init and initialize your terraform configuration. So it will first download the modules from the source which you initialized in your configuration file (Mine is with the name main.tf ).
  • Run terraform plan to know beforehand that everything is working fine or are there any errors. If there is an error fix it.
  • Run terraform apply to apply the changes in the cloud. Before applying changes terraform will ask about the confirmation. Say yes to confirm your changes.
  • You will see that resources will be created and it will print the output variables which we initialized in the output.tf.
  • Run terraform destroy to destroy changes in the cloud. Before destroying changes it will ask confirmation to destroy the infrastructure on the cloud. Answer yes to confirm it.
  • You will see that your resources will be destroyed from the cloud console as well.

Working Of Modules

├── ec2_module
│ └── terraform-aws-ec2-instance-2.13.0
│ ├── CHANGELOG.md
│ ├── examples
│ │ ├── basic
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── README.md
│ │ └── volume-attachment
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── README.md
│ ├── LICENSE
│ ├── main.tf
│ ├── Makefile
│ ├── outputs.tf
│ ├── README.md
│ └── variables.tf
└── modules.json
$ cat ec2_instance/terraform-aws-ec2-instance-2.13.0/main.tf 
locals {
is_t_instance_type = replace(var.instance_type, "/^t(2|3|3a){1}\\..*$/", "1") == "1" ? true : false
}
resource "aws_instance" "this" {
count = var.instance_count
ami = var.ami
instance_type = var.instance_type
user_data = var.user_data
user_data_base64 = var.user_data_base64
subnet_id = length(var.network_interface) > 0 ? null : element(
distinct(compact(concat([var.subnet_id], var.subnet_ids))),
count.index,
)
key_name = var.key_name
monitoring = var.monitoring
get_password_data = var.get_password_data
vpc_security_group_ids = var.vpc_security_group_ids
iam_instance_profile = var.iam_instance_profile
associate_public_ip_address = var.associate_public_ip_address
private_ip = length(var.private_ips) > 0 ? element(var.private_ips, count.index) : var.private_ip
ipv6_address_count = var.ipv6_address_count
ipv6_addresses = var.ipv6_addresses
ebs_optimized = var.ebs_optimizeddynamic "root_block_device" {
for_each = var.root_block_device
content {
delete_on_termination = lookup(root_block_device.value, "delete_on_termination", null)
encrypted = lookup(root_block_device.value, "encrypted", null)
iops = lookup(root_block_device.value, "iops", null)
kms_key_id = lookup(root_block_device.value, "kms_key_id", null)
volume_size = lookup(root_block_device.value, "volume_size", null)
volume_type = lookup(root_block_device.value, "volume_type", null)
}
}
dynamic "ebs_block_device" {
for_each = var.ebs_block_device
content {
delete_on_termination = lookup(ebs_block_device.value, "delete_on_termination", null)
device_name = ebs_block_device.value.device_name
encrypted = lookup(ebs_block_device.value, "encrypted", null)
iops = lookup(ebs_block_device.value, "iops", null)
kms_key_id = lookup(ebs_block_device.value, "kms_key_id", null)
snapshot_id = lookup(ebs_block_device.value, "snapshot_id", null)
volume_size = lookup(ebs_block_device.value, "volume_size", null)
volume_type = lookup(ebs_block_device.value, "volume_type", null)
}
}
dynamic "ephemeral_block_device" {
for_each = var.ephemeral_block_device
content {
device_name = ephemeral_block_device.value.device_name
no_device = lookup(ephemeral_block_device.value, "no_device", null)
virtual_name = lookup(ephemeral_block_device.value, "virtual_name", null)
}
}
dynamic "network_interface" {
for_each = var.network_interface
content {
device_index = network_interface.value.device_index
network_interface_id = lookup(network_interface.value, "network_interface_id", null)
delete_on_termination = lookup(network_interface.value, "delete_on_termination", false)
}
}
source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check
disable_api_termination = var.disable_api_termination
instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
placement_group = var.placement_group
tenancy = var.tenancy
tags = merge(
{
"Name" = var.instance_count > 1 || var.use_num_suffix ? format("%s-%d", var.name, count.index + 1) : var.name
},
var.tags,
)
volume_tags = merge(
{
"Name" = var.instance_count > 1 || var.use_num_suffix ? format("%s-%d", var.name, count.index + 1) : var.name
},
var.volume_tags,
)
credit_specification {
cpu_credits = local.is_t_instance_type ? var.cpu_credits : null
}
}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store