Modules Using a Sub Module
We will learn how to use a module within the module.
Submodules#
Modules can use modules inside themselves. We are going to go through an example of a three-way cross-talk module. The purpose of this module is to set up ingress and egress on a protocol and port of your choosing between three AWS security groups in both directions. To do this by hand would require twelve security group rules, but this can be shortened by using modules.
Project example#
Let’s dive straight into the example. If you are following along with the course, create a folder in your workspace and add the following file structure:
Cross-talk folder#
Let’s pause and discuss the cross-talk
module that we have just defined.
variables.tf
#
Looking at the variables.tf
, we have introduced a couple of new concepts. The first is that we are taking the whole security group resource as input. This ability was introduced in Terraform 0.12
and has made writing a module much easier. It means you can take the whole resource and simply pick off the properties you need from it rather than taking all of the fields you need as separate properties.
The next new concept is constraining a variable to a type. Since the port has to be a number, we can
constrain it by using type = number
. This gives the user of our module some guidance so they know
from the input that they must supply a number. It also means the IDE and tooling can
prompt the user that the variable must be a number.
main.tf
#
Inside the cross-talk/main.tf
, we define a security group ingress and egress pair of rules for
each security group passed in. This allows the traffic between them on the protocol to flow in both
directions. This module is useful in and of itself in that it allows two-way talking on a protocol and port for two security groups in AWS.
Cross-talk-3-way folder#
The next module, cross-talk-3-way
, has one extra variable (security_group_3
) to take the third
security group resource. It then simply has three instances of the cross-talk
module. Since we have three modules, there are three pairs that we need to open up rules between. By using a module to define
a cross-talk between two security groups and another module to define cross-talking between three, we can keep our Terraform code neat and compact. This is a good example where having sub-modules makes the code more readable.
Thought of school#
However, using too many sub-modules can make your code confusing and overly complex, and so ultimately come down to a matter of judgment. A good rule of thumb is not to go more than one level of nesting deep unless you have a good reason like ease of understanding and readability. If that is not the case, then it is probably not the place to use a module.
Top level main.tf
file code#
To finish our example, we’ll define the following main.tf
at the top level:
/
- main.tf
main.tf
code explanation#
-
In our
main.tf
, we configure our AWS provider with the region and pin it to a version (as per best practice, as we have learned). -
We then define three security groups.
-
Lastly, we use the
cross-talk-3-way
module to set up cross-talking between the security groups on TCP on port8500
. -
Using modules to implement the cross-talk functionality, our actual Terraform code (which is everything in the top-level folder) is short and concise.
If we wrote all of the code to implement cross-talking between the three security groups at the top level, we would end up with twelve security group rule resources.
We would have to make sure that we got each of those exactly right.
-
By using modules, we can define the logic in a simpler and easier way.
-
At first, we had a module that allowed cross-talking between two modules. That module was used to create a module that allows cross-talking between three security groups.
-
Again, at the top level, our code is much shorter and more readable.
📝Note: Don’t forget to destroy the Terraform infrastructure using
terraform destroy
after you have completed the task.