A factory module accepts a small set of inputs and creates standardized infrastructure resources using opinionated defaults. It reduces repetitive configuration while preserving targeted customization, such as a subnet name or address range. section 3.3
Design a factory module around these practices:
- Minimize required parameters when resources share stable default attributes. section 3.3
- Transform inputs into standardized names, identifiers, addresses, or other resource attributes. section 3.3
- Balance reproducibility against evolvability: expose meaningful customization without making every attribute configurable. section 3.3
- Use factories for individual resources, then compose them in builder modules when users must select which resources exist. section 3.5 section 3.7
Network and database resources
A network factory can accept a network name and CIDR range, calculate subnet addressing, generate standardized subnet names, and create multiple subnet resources. Separate load-balancer and firewall factories can configure internal or external database access; a database builder composes the selected resources. section 3.3 section 3.5
Figure 3.5 A factory pattern module includes a set of defaults for a minimal resource configuration and enables customization by accepting input variables.
Use the factory diagram to see how minimal inputs combine with defaults while leaving selected attributes customizable. section 3.3
Listing 3.3 Creating three subnets in GCP by using a factory pattern
import json
import ipaddress
def _generate_subnet_name(address): #1
address_identifier = format(ipaddress.ip_network( #1
address).network_address).replace('.', '-') #1
return f'network-{address_identifier}' #1
class SubnetFactory: #2
def __init__(self, address, region):
self.name = _generate_subnet_name(address) #1
self.address = address #3
self.region = region #4
self.network = 'default' #5
self.resource = self._build() #6
def _build(self): #6
return {
'resource': [
{
'google_compute_subnetwork': [ #7
{ #7
f'{self.name}': [ #7
{ #7
'name': self.name, #7
'ip_cidr_range': self.address, #7
'region': self.region, #7
'network': self.network #7
} #7
] #7
} #7
] #7
}
]
}
if __name__ == "__main__":
subnets_and_regions = { #8
'10.0.0.0/24': 'us-central1', #8
'10.0.1.0/24': 'us-west1', #8
'10.0.2.0/24': 'us-east1', #8
} #8
for address, region in subnets_and_regions.items(): #8
subnetwork = SubnetFactory(address, region) #6
with open(f'{_generate_subnet_name(address)}.tf.json',
'w') as outfile: #9
json.dump(subnetwork.resource, outfile, #9
sort_keys=True, indent=4) #9
Inspect the Python SubnetFactory example for input handling, default network configuration, generated names, and resource construction. section 3.3










