diff --git a/diskimage_builder/block_device/level0/localloop.py b/diskimage_builder/block_device/level0/localloop.py
index de18e972e..f54fa95c7 100644
--- a/diskimage_builder/block_device/level0/localloop.py
+++ b/diskimage_builder/block_device/level0/localloop.py
@@ -15,6 +15,7 @@
 from diskimage_builder.block_device.blockdevicesetupexception \
     import BlockDeviceSetupException
 from diskimage_builder.block_device.plugin_base import NodePluginBase
+from diskimage_builder.block_device.tree_config import TreeConfig
 from diskimage_builder.block_device.utils import parse_abs_size_spec
 from diskimage_builder.graph.digraph import Digraph
 import logging
@@ -31,6 +32,7 @@ class LocalLoop(NodePluginBase):
     This class handles local loop devices that can be used
     for VM image installation.
     """
+    tree_config = TreeConfig("local_loop")
 
     def __init__(self, config, default_config):
         logger.debug("Creating LocalLoop object; config [%s] "
diff --git a/diskimage_builder/block_device/level1/__init__.py b/diskimage_builder/block_device/level1/__init__.py
index 6c3b57a88..145b0b45b 100644
--- a/diskimage_builder/block_device/level1/__init__.py
+++ b/diskimage_builder/block_device/level1/__init__.py
@@ -1,4 +1,5 @@
-# Copyright 2016 Andreas Florath (andreas@florath.net)
+# Copyright
+# 2016-2017 Andreas Florath (andreas@florath.net)
 #
 # Licensed under the Apache License, Version 2.0 (the "License"); you may
 # not use this file except in compliance with the License. You may obtain
@@ -13,5 +14,7 @@
 # under the License.
 
 from diskimage_builder.block_device.level1.partitioning import Partitioning
+from diskimage_builder.block_device.level1.partitioning \
+    import PartitioningTreeConfig
 
-__all__ = [Partitioning]
+__all__ = [Partitioning, PartitioningTreeConfig]
diff --git a/diskimage_builder/block_device/level1/partitioning.py b/diskimage_builder/block_device/level1/partitioning.py
index c3c30317a..a1a66e7b6 100644
--- a/diskimage_builder/block_device/level1/partitioning.py
+++ b/diskimage_builder/block_device/level1/partitioning.py
@@ -12,11 +12,11 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-import collections
 from diskimage_builder.block_device.blockdevicesetupexception \
     import BlockDeviceSetupException
 from diskimage_builder.block_device.level1.mbr import MBR
 from diskimage_builder.block_device.plugin_base import PluginBase
+from diskimage_builder.block_device.tree_config import TreeConfig
 from diskimage_builder.block_device.utils import parse_abs_size_spec
 from diskimage_builder.block_device.utils import parse_rel_size_spec
 from diskimage_builder.graph.digraph import Digraph
@@ -28,15 +28,50 @@ import subprocess
 logger = logging.getLogger(__name__)
 
 
+class PartitionTreeConfig(object):
+
+    @staticmethod
+    def config_tree_to_digraph(config_key, config_value, pconfig, dconfig,
+                               base_name, plugin_manager):
+        logger.debug("called [%s] [%s] [%s]"
+                     % (config_key, config_value, base_name))
+        assert config_key == Partition.type_string
+
+        for partition in config_value:
+            name = partition['name']
+            nconfig = {'name': name}
+            for k, v in partition.items():
+                if k not in plugin_manager:
+                    nconfig[k] = v
+                else:
+                    plugin_manager[k].plugin \
+                                     .tree_config.config_tree_to_digraph(
+                                         k, v, dconfig, name, plugin_manager)
+            pconfig.append(nconfig)
+
+        logger.debug("finished [%s] [%s]" % (nconfig, dconfig))
+
+
 class Partition(Digraph.Node):
 
-    def __init__(self, name, flags, size, ptype, base, partitioning):
+    type_string = "partitions"
+    tree_config = TreeConfig("partitions")
+
+    def __init__(self, name, flags, size, ptype, base, partitioning,
+                 prev_partition):
         Digraph.Node.__init__(self, name)
+        self.name = name
         self.flags = flags
         self.size = size
         self.ptype = ptype
         self.base = base
         self.partitioning = partitioning
+        self.prev_partition = prev_partition
+
+    def __repr__(self):
+        return "<Partition [%s] on [%s] size [%s] prev [%s]>" \
+            % (self.name, self.base, self.size,
+               self.prev_partition.name if self.prev_partition else "UNSET")
 
     def get_flags(self):
         return self.flags
@@ -51,6 +86,9 @@ class Partition(Digraph.Node):
         bnode = dg.find(self.base)
         assert bnode is not None
         dg.create_edge(bnode, self)
+        if self.prev_partition is not None:
+            logger.debug("Insert edge [%s]" % self)
+            dg.create_edge(self.prev_partition, self)
 
     def create(self, result, rollback):
         self.partitioning.create(result, rollback)
@@ -68,8 +106,34 @@ class Partition(Digraph.Node):
         pass
 
 
+class PartitioningTreeConfig(object):
+
+    @staticmethod
+    def config_tree_to_digraph(config_key, config_value, dconfig,
+                               default_base_name, plugin_manager):
+        logger.debug("called [%s] [%s] [%s]"
+                     % (config_key, config_value, default_base_name))
+        assert config_key == "partitioning"
+        base_name = config_value['base'] if 'base' in config_value \
+                    else default_base_name
+        nconfig = {'base': base_name}
+        for k, v in config_value.items():
+            if k != 'partitions':
+                nconfig[k] = v
+            else:
+                pconfig = []
+                PartitionTreeConfig.config_tree_to_digraph(
+                    k, v, pconfig, dconfig, base_name, plugin_manager)
+                nconfig['partitions'] = pconfig
+
+        dconfig.append({config_key: nconfig})
+        logger.debug("finished new [%s] complete [%s]" % (nconfig, dconfig))
+
+
 class Partitioning(PluginBase):
 
+    tree_config = PartitioningTreeConfig()
+
     flag_boot = 1
     flag_primary = 2
 
@@ -109,7 +173,9 @@ class Partitioning(PluginBase):
         if 'partitions' not in config:
             self._config_error("Partitioning config needs 'partitions'")
 
-        self.partitions = collections.OrderedDict()
+        self.partitions = []
+        prev_partition = None
+
         for part_cfg in config['partitions']:
             if 'name' not in part_cfg:
                 self.config_error("Missing 'name' in partition config")
@@ -133,8 +199,10 @@ class Partitioning(PluginBase):
 
             ptype = int(part_cfg['type'], 16) if 'type' in part_cfg else 0x83
 
-            self.partitions[part_name] \
-                = Partition(part_name, flags, size, ptype, self.base, self)
+            np = Partition(part_name, flags, size, ptype, self.base, self,
+                           prev_partition)
+            self.partitions.append(np)
+            prev_partition = np
             logger.debug(part_cfg)
 
     def _config_error(self, msg):
@@ -147,7 +215,8 @@ class Partitioning(PluginBase):
             return fd.tell()
 
     def insert_nodes(self, dg):
-        for _, part in self.partitions.items():
+        for part in self.partitions:
+            logger.debug("Insert node [%s]" % part)
             dg.add_node(part)
 
     def _exec_sudo(self, cmd):
@@ -212,7 +281,8 @@ class Partitioning(PluginBase):
         partition_devices = set()
         disk_size = self._size_of_block_dev(image_path)
         with MBR(image_path, disk_size, self.align) as part_impl:
-            for part_name, part_cfg in self.partitions.items():
+            for part_cfg in self.partitions:
+                part_name = part_cfg.get_name()
                 part_bootflag = Partitioning.flag_boot \
                                 in part_cfg.get_flags()
                 part_primary = Partitioning.flag_primary \
diff --git a/diskimage_builder/block_device/tree_config.py b/diskimage_builder/block_device/tree_config.py
new file mode 100644
index 000000000..d7c5531be
--- /dev/null
+++ b/diskimage_builder/block_device/tree_config.py
@@ -0,0 +1,60 @@
+# Copyright 2016-2017 Andreas Florath (andreas@florath.net)
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class TreeConfig(object):
+    """Supports simple tree-like configuration
+
+    When using the new (complete) configuration there is a need to
+    specify the complete digraph of block level configurations.  This
+    provides great flexibility for the cost of complex configurations:
+    each and every single element must be completely specified.  In
+    many simple use cases the configuration flexibility is not
+    needed.
+
+    With the help of this object the simple to use and short tree-like
+    configuration is converted automatically into the complete digraph
+    configuration which can be used to create the block device
+    elements.
+    """
+
+    def __init__(self, type_string):
+        self.type_string = type_string
+
+    def config_tree_to_digraph(self, config_key, config_value, dconfig,
+                               default_base_name, plugin_manager):
+        logger.debug("called [%s] [%s] [%s]"
+                     % (config_key, config_value, default_base_name))
+        base_name = config_value['base'] if 'base' in config_value \
+                    else default_base_name
+        name = config_value['name'] \
+               if 'name' in config_value \
+                  else "%s_%s" % (config_key, base_name)
+        assert config_key == self.type_string
+
+        nconfig = {'base': base_name, 'name': name}
+        for k, v in config_value.items():
+            if k not in plugin_manager:
+                nconfig[k] = v
+            else:
+                plugin_manager[k].plugin \
+                    .tree_config.config_tree_to_digraph(
+                        k, v, dconfig, name, plugin_manager)
+
+        dconfig.append({self.type_string: nconfig})
+        logger.debug("finished new [%s] complete [%s]" % (nconfig, dconfig))