Removing duplication with modules

Modules in Terraform are used to group multiple resources. You can reuse this grouping multiple times. You can also configure modules with variables, and modules can return outputs that you can pass to other resources and modules.

To get started with modules, create a folder named modules in the same folder as the template.tf. Inside this folder, create another one, named application. In this folder, we will keep the module, responsible for creating all resources required by a single application, be it MightyTrousers, CrazyFoods, or anything else.

A module is a regular Terraform template, so just create the ./modules/application/application.tf file with the following contents:

resource "aws_security_group" "allow_http" { 
  name = "allow_http" 
  description = "Allow HTTP traffic" 
  vpc_id = "${aws_vpc.my_vpc.id}" 
  ingress { 
    from_port = 80 
    to_port = 80 
    protocol = "tcp" 
    cidr_blocks = ["0.0.0.0/0"] 
  } 
 
  egress { 
    from_port = 0 
    to_port = 0 
    protocol = "-1" 
    cidr_blocks = ["0.0.0.0/0"] 
  } 
} 
resource "aws_instance" "mighty-trousers" { 
  ami = "ami-9bf712f4" 
  instance_type = "t2.micro" 
  subnet_id = "${aws_subnet.public.id}" 
  vpc_security_group_ids = ["${aws_security_group.allow_http.id}"] 
} 

Now, with this module in place, let's actually call it inside our template.tf. Remove everything related to MightyTrousers application and add the following module configuration:

module "mighty_trousers" { 
  source = "./modules/application" 
} 

The name of the module (mighty_trousers) is only used to reference this module in other places in the template. We can name modules any way we like, as long as they are unique.

Now, let's try to apply this template as usual: terraform apply:

Error downloading modules: module mighty_trousers: not found, may need to be 
downloaded using 'terraform get' 

Even though we specified source, Terraform still can't find our module. It requires you to run the terraform get command first.

When you run this command, Terraform downloads the module to the .terraform folder inside your project's folder. If your module is local to your laptop, Terraform will simply create a symlink from it to the .terraform folder.

There are other types of sources for modules. You could specify a Git repository, HTTP URL, GitHub, and BitBucket links as a module source. In large organizations, there are probably many different Terraform modules, and it's convenient to store them outside of project-specific repository. Every time you run get command, it will pull it from the source and save it inside the .terraform folder.

Note

Segment.com, an analytics and data platform company, open sources their Terraform modules: https://github.com/segmentio/stack. As they claim, it's a set of Terraform modules to configure production infrastructure with AWS.

There is also a terraform-comunity-modules GitHub organization, https://github.com/terraform-community-modules, which has many different modules you could reuse or get inspired by.

In future, as Terraform adaption among companies grows, we might see many more open source, third-party reusable, ready for production modules, just like we use Puppet modules or Chef Cookbooks today.

If you run the terraform get command, you will get the following output, with errors:

$> terraform get
Get: file:///home/kshirinkin/work/packt-terraform-rewrites/modules/application
Error loading Terraform: module mighty_trousers.root: 2 error(s) occurred:
* resource 'aws_security_group.allow_http' config: unknown resource 
'aws_vpc.my_vpc' referenced in variable aws_vpc.my_vpc.id
* resource 'aws_instance.mighty-trousers' config: unknown resource 
'aws_subnet.public' referenced in variable aws_subnet.public.id

This is nothing to be surprised about: we blindly copied and pasted our MightyTrousers application configuration. This configuration references resources defined in the main template.tf. But these resources are not available inside the module template! We need a way to pass required values down to the module. Module variables are exactly what we need.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.173.112