Reputation: 12213
I am fairly new to terraform. I am trying to understand what is the right way to spin up resources using terraform. I have come across two different ways to do it.
module "vpc" {
source = "terraform-google-modules/network/google"
version = "~> 6.0"
project_id = var.project_id
network_name = var.network_name
routing_mode = var.routing_mode
auto_create_subnetworks = var.auto_create_subnetworks
delete_default_internet_gateway_routes = var.delete_default_internet_gateway_routes
mtu = var.mtu
subnets = var.subnets
firewall_rules = var.firewall_rules
}
resource "google_compute_network" "network" {
name = var.network_name
auto_create_subnetworks = var.auto_create_subnetworks
routing_mode = var.routing_mode
project = var.project_id
delete_default_routes_on_create = var.delete_default_internet_gateway_routes
mtu = var.mtu
}
Both these approaches work fine and they give me desired output but I would like to know which one should be used when? When should I use Terraform Module directly and when should I use resource?
Upvotes: 1
Views: 1850
Reputation: 6862
As you may read in the documentation, modules are a way of organising Terraform scripts, it makes them more reusable, sharable and publishable.
In general, when working with Terraform you want to have an infrastructure that's portable and that can be transferred and deployed on multiple environments.
It would have been harder to maintain a complex infrastructure where you only use resources that will be sitting in the same codebase.
modules
allows you to group one, to multiple resources
, so you can break your infrastructure code to reusable and configurable portions of code, where you can enforce certain defaults. These modules can be used in the main infrastructure codebase making it easily readable and maintainable since it abstracts the details of each part of the infrastructure.
And with this abstraction, you can afford using different patterns to deploy your infrastructure on different environments (example: 'dev', 'staging', and 'prod') since you may only pass different (and less) values for your variables, or your can just duplicate your infrastructure folder (dev-infra) for example to create another (stg-infra), the cost of this code duplication is cheaper than duplicating many files in case of using only ressources.
TLDR; as you shared in your example:
module "vpc" {
source = "terraform-google-modules/network/google"
version = "~> 6.0"
project_id = var.project_id
network_name = var.network_name
routing_mode = var.routing_mode
auto_create_subnetworks = var.auto_create_subnetworks
delete_default_internet_gateway_routes = var.delete_default_internet_gateway_routes
mtu = var.mtu
subnets = var.subnets
firewall_rules = var.firewall_rules
}
Does more than creating the VPC on GCP. As you can see in their source-code, it is composed on many other modules, in which they use the google_compute_network
resources along others to setup networks, firewall rules, subnets and more.
You may have a very complex VPC network that can be done only by using the module that abstracts the usage of the resources. That same VPC setup might be re-used for other GCP projects for different environments. Or you can even build a module on top of this if you want to enforce some configurations, like you hardcode auto_create_subnetworks = true
.
In some organisations, it is recommended to use only the organisation's approved terraform module, where they apply certain patterns, and set some defaults/best-practices.
See more:
Hope this helps!
Upvotes: 4