diff --git a/generate.py b/generate.py
index a8f28c37cd5fa391e889d5d8347bf95c532f3c3d..d68d4694355163ee913850587f4e8a7fab7f4ab2 100644
--- a/generate.py
+++ b/generate.py
@@ -1,77 +1,22 @@
 #!/usr/bin/python3
 
 import sys
-import yaml
 import jinja2
 
-from modules.network_parser import add_networks, add_routers
-from modules.provider import print_prov_attributes
+from modules.device_creator import create_devices
 
 if (len(sys.argv) != 2):
     print ("Error: Expecting 1 argument (yml file).")
     sys.exit();
 
-
-# Loading external files
-try:
-    ymlfile = open(str(sys.argv[1]))
-    yml = yaml.safe_load(ymlfile)
-except IOError:
-    print ("Error: file does not exist.")
-
-try:
-    mapping_file = open("name_mapping/mapping.yml")
-    name_mappings = yaml.safe_load(mapping_file)
-except IOError:
-    print ("Error: cannot find mappings.")
-
-try:
-    flavors_file = open("name_mapping/flavors.yml")
-    flavors = yaml.safe_load(flavors_file)
-except IOError:
-    print ("Error: cannot find the list of flavors.")
-
-
-# Converts yaml attribute names to vagrant attribute names.
-def do_mapping(name, command_type):
-    return name_mappings[str(command_type)][name]
-
-def add_formated_command(key, value):
-    if (key in name_mappings['string']):
-        devices[host['name']].append(
-                'device.' + str(do_mapping(key, 'string'))
-                + ' = \"' + str(value) + '\"')
-    elif (key in name_mappings['integer']):
-        devices[host['name']].append(
-                'device.' + str(do_mapping(key, 'integer'))
-                + ' = ' + str(value))
-    elif (key in name_mappings['boolean']):
-        devices[host['name']].append(
-                'device.' + str(do_mapping(key, 'boolean'))
-                + ' = ' + str(value).lower())
-
-
-# Building "devices" structure that will be passed to Jinja2
-devices = {}
-
-for host in yml['hosts']:
-    devices[host['name']] = []
-    for key, value in host.items():
-        if (key != 'name'):
-            add_formated_command(key, value)
-    add_networks(host['name'], yml, devices)
-    print_prov_attributes(host, flavors
-            , name_mappings['need_provider'], devices)
-
-for router in yml['routers']:
-    devices[router['name']] = []
-    add_routers(router['name'], yml, devices)
-
+# A structure with formatted commands for each device
+devices = create_devices(str(sys.argv[1]))
 
 # Generating output via Jinja2
 templateLoader = jinja2.FileSystemLoader(searchpath="templates")
 templateEnv = jinja2.Environment(loader=templateLoader, trim_blocks=True)
 baseTemplate = templateEnv.get_template("base")
 output = baseTemplate.render(devices = devices)
+
 print (output)
 
diff --git a/modules/attribute_formatter.py b/modules/attribute_formatter.py
new file mode 100644
index 0000000000000000000000000000000000000000..6ad8d9e95c022d441f5cae95ee50fcfd5ad24374
--- /dev/null
+++ b/modules/attribute_formatter.py
@@ -0,0 +1,24 @@
+def _format_and_add(key, value, mappings, device_definition):
+    """ Formats and adds the definition of a simple attribute. """
+
+    if (key in mappings['string']):
+        device_definition.append(
+                'device.' + mappings['string'][key]
+                + ' = \"' + str(value) + '\"')
+    elif (key in mappings['integer']):
+        device_definition.append(
+                'device.' + mappings['integer'][key]
+                + ' = ' + str(value))
+    elif (key in mappings['boolean']):
+        device_definition.append(
+                'device.' + mappings['boolean'][key]
+                + ' = ' + str(value).lower())
+
+
+def add_simple_commands(device, mappings, device_definition):
+    """ Adds definitions of string, integer and boolean vagrant attributes. """
+
+    for key, value in device.items():
+        if (key != "name"):
+            _format_and_add(key, value, mappings, device_definition)
+
diff --git a/modules/device_creator.py b/modules/device_creator.py
new file mode 100644
index 0000000000000000000000000000000000000000..f1f37d1600d077838baa6f015050e669e4a12370
--- /dev/null
+++ b/modules/device_creator.py
@@ -0,0 +1,74 @@
+import yaml
+
+from .attribute_formatter import add_simple_commands
+from .provider import add_prov_attributes, add_router_specification
+from .network_parser import add_networks, add_router_ip
+
+
+def _open_yml(yml_file_name):
+    """ Opens the input yaml file. """
+    try:
+        ymlfile = open(str(yml_file_name))
+        yml = yaml.safe_load(ymlfile)
+        return yml
+    except IOError:
+        print ("Error: file does not exist.")
+
+
+def _open_mappings():
+    """ Opens the file with name mappings. """
+    try:
+        mapping_file = open("name_mapping/mapping.yml")
+        mappings = yaml.safe_load(mapping_file)
+        return mappings
+    except IOError:
+        print ("Error: cannot find mappings.")
+
+
+def _open_flavors():
+    """ Opens the file with flavor definitions. """
+    try:
+        flavors_file = open("name_mapping/flavors.yml")
+        flavors = yaml.safe_load(flavors_file)
+        return flavors
+    except IOError:
+        print ("Error: cannot find the list of flavors.")
+
+
+def _create_hosts(yml, mappings, flavors):
+    """ Creates a dictionary with formatted definition of each host. """
+    host_definitions = {}
+
+    for host in yml['hosts']:
+        host_definitions[host['name']] = []
+        
+        add_simple_commands(host, mappings, host_definitions[host['name']])
+        add_networks(host["name"], yml, host_definitions)
+        add_prov_attributes(host, flavors
+                , mappings['need_provider'], host_definitions)
+
+    return host_definitions
+
+
+def _create_routers(yml, mappings):
+    """ Creates a dictionary with formatted definition of each router. """
+    router_definitions = {}
+
+    for router in yml['routers']:
+        router_definitions[router['name']] = []
+        add_router_ip(router["name"], yml, router_definitions)
+        add_router_specification(router, router_definitions)
+
+    return router_definitions
+
+
+def create_devices(yml_file_name):
+    """ Returns a marged dictionary of host and router definitions. """
+
+    yml = _open_yml(yml_file_name)
+    mappings = _open_mappings()
+    flavors = _open_flavors()
+
+    return dict(**_create_hosts(yml, mappings, flavors)
+            , **_create_routers(yml, mappings))
+
diff --git a/modules/network_parser.py b/modules/network_parser.py
index 365fa57a9f271cae85b33d1bb2fd76663c798448..edd93ca57ae8d3dc5dfd24c288fb69512898adaa 100644
--- a/modules/network_parser.py
+++ b/modules/network_parser.py
@@ -1,4 +1,6 @@
 def _find_ip(hostname, mappings, device_type):
+    """ Finds the ip address of a device. """
+
     for mapping in mappings:
         if ((device_type == 'host'
                 and mapping['host'] and mapping['host'] == hostname)
@@ -6,41 +8,46 @@ def _find_ip(hostname, mappings, device_type):
                 and mapping['router'] and mapping['router'] == hostname)):
             return mapping['ip']
 
-def _add_ip(hostname, mappings, device_type, devices):
-    devices[hostname].append(
-            'device.vm.network :private_network, ip: \"'
+
+def _add_ip(hostname, mappings, device_type, definitions):
+    """ Adds a formatted ip address to a device definition. """
+
+    definitions[hostname].append(
+            "device.vm.network :private_network, ip: \""
             + str(_find_ip(hostname, mappings, device_type)) + '\"')
 
-def _add_netmask(hostname, my_network, networks, devices):
+
+def _add_netmask(hostname, my_network, networks, definitions):
+    """ Adds netmask to the end of a formatted ip definition. """
+
     for network in networks:
         if (network['name'] == my_network):
             address, mask = network['cidr'].split('/')
-            devices[hostname][-1] += (', netmask: ' + mask)
+            definitions[hostname][-1] += (', netmask: ' + mask)
+
 
-def add_networks(hostname, yml, devices):
+def add_networks(hostname, yml, definitions):
+    """ Adds ip address and natmask to a host. """
 
     if (not yml['net_mappings']):
         return
 
     for mapping in yml['net_mappings']:
         if (mapping['host'] == hostname):
-            _add_ip(hostname, yml['net_mappings'], 'host', devices)
+            _add_ip(hostname, yml['net_mappings'], 'host', definitions)
             if (yml['networks']):
                 _add_netmask(
                         hostname, mapping['network']
-                        , yml['networks'], devices)
+                        , yml['networks'], definitions)
 
-def _add_router_os(routername, devices):
-    router_os = 'generic/debian10'
-    devices[routername].append('device.vm.box = \"' + router_os + '\"')
 
-def add_routers(routername, yml, devices):
+def add_router_ip(routername, yml, definitions):
+    """ Adds ip address to a router. """
 
     if (not yml['router_mappings']):
         return
 
     for mapping in yml['router_mappings']:
         if (mapping['router'] == routername):
-            _add_router_os(routername, devices)
-            _add_ip(routername, yml['router_mappings'], 'router', devices)
+            _add_ip(routername, yml['router_mappings'], 'router', definitions)
 
diff --git a/modules/provider.py b/modules/provider.py
index 76318572dc4b21464d1898691f662778d7c88661..daf5ff6c4f6607f90f2bc8f203c22a6618869af4 100644
--- a/modules/provider.py
+++ b/modules/provider.py
@@ -1,35 +1,59 @@
-def _print_flavor(host, flavors, provider_attributes, devices):
+def _print_flavor(host, flavors, provider_attributes, definitions):
+    """ Formats and add a flavor for a device. """
+
     if ('memory' not in host):
-        devices[host['name']].append('  vb.'
+        definitions[host['name']].append('  vb.'
                 + provider_attributes['memory'] + ' = '
                 + str(flavors[host['flavor']]['memory']))
     if ('cpus' not in host):
-        devices[host['name']].append('  vb.'
+        definitions[host['name']].append('  vb.'
                 + provider_attributes['cpus'] + ' = '
                 + str(flavors[host['flavor']]['cores']))
 
-def _add_params(host, flavors, provider_attributes, devices):
+
+def _add_params(host, flavors, provider_attributes, definitions):
+    """ Formats and adds simple provision attributes. """
+
     if ('memory' in host):
-        devices[host['name']].append('  vb.'
+        definitions[host['name']].append('  vb.'
                 + provider_attributes['memory'] + ' = '
                 + str(host['memory']))
     if ('cpus' in host):
-        devices[host['name']].append('  vb.'
+        definitions[host['name']].append('  vb.'
                 + provider_attributes['cpus'] + ' = '
                 + str(host['cpus']))
     if ('flavor' in host and host['flavor'] in flavors):
-        _print_flavor(host, flavors, provider_attributes, devices)
+        _print_flavor(host, flavors, provider_attributes, definitions)
+
 
 def _need_provider(host, provider_attributes):
+    """ Checks if provision attributes are present. """
+
     for attribute in provider_attributes:
         if (attribute in host):
             return True
     return False
 
-def print_prov_attributes(host, flavors, provider_attributes, devices):
+
+def add_prov_attributes(host, flavors, provider_attributes, definitions):
+    """ Adds provider attributes. """
+
     if (_need_provider(host, provider_attributes)):
-        devices[host['name']].append(
+        definitions[host['name']].append(
                 "device.vm.provider \"virtualbox\" do |vb|")
-        _add_params(host, flavors, provider_attributes, devices)     
-        devices[host['name']].append("end")
+        _add_params(host, flavors, provider_attributes, definitions)     
+        definitions[host['name']].append("end")
+
+
+def add_router_specification(router, definitions):
+    """ Adds the default specification for a router. """
     
+    ROUTER_BOX = "generic/debian10"
+    ROUTER_MEMORY = 128
+
+    definitions[router['name']].append("device.vm.box = \"" + ROUTER_BOX + "\"")
+    definitions[router['name']].append(
+                "device.vm.provider \"virtualbox\" do |vb|")
+    definitions[router['name']].append("  vb.memory = " + str(ROUTER_MEMORY))
+    definitions[router['name']].append("end")
+