diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index 62d59ce4b10b52223db0925f662d8c618ba6d4c1..f154694b53b6b7070983f70c2f1d493cc8e979d9 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -282,14 +282,14 @@ def _InitFileStorage(file_storage_dir):
   return file_storage_dir
 
 
-def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
+def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913, R0914
                 master_netmask, master_netdev, file_storage_dir,
                 shared_file_storage_dir, candidate_pool_size, secondary_ip=None,
                 vg_name=None, beparams=None, nicparams=None, ndparams=None,
                 hvparams=None, diskparams=None, enabled_hypervisors=None,
                 modify_etc_hosts=True, modify_ssh_setup=True,
                 maintain_node_health=False, drbd_helper=None, uid_pool=None,
-                default_iallocator=None, primary_ip_version=None,
+                default_iallocator=None, primary_ip_version=None, ipolicy=None,
                 prealloc_wipe_disks=False, use_external_mip_script=False):
   """Initialise the cluster.
 
@@ -413,7 +413,16 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
   objects.UpgradeBeParams(beparams)
   utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES)
   utils.ForceDictType(nicparams, constants.NICS_PARAMETER_TYPES)
+  for key, val in ipolicy.items():
+    if key not in constants.IPOLICY_PARAMETERS:
+      raise errors.OpPrereqError("'%s' is not a valid key for instance policy"
+                                 " description", key)
+    utils.ForceDictType(val, constants.ISPECS_PARAMETER_TYPES)
+
   objects.NIC.CheckParameterSyntax(nicparams)
+  full_ipolicy = objects.FillDictOfDicts(constants.IPOLICY_DEFAULTS,
+                                         ipolicy)
+  objects.InstancePolicy.CheckParameterSyntax(full_ipolicy)
 
   if ndparams is not None:
     utils.ForceDictType(ndparams, constants.NDS_PARAMETER_TYPES)
@@ -497,6 +506,7 @@ def InitCluster(cluster_name, mac_prefix, # pylint: disable=R0913
     primary_ip_family=ipcls.family,
     prealloc_wipe_disks=prealloc_wipe_disks,
     use_external_mip_script=use_external_mip_script,
+    ipolicy=ipolicy
     )
   master_node_config = objects.Node(name=hostname.name,
                                     primary_ip=hostname.ip,
diff --git a/lib/client/gnt_cluster.py b/lib/client/gnt_cluster.py
index 5c952072793d936f8d586da675965c89655da9fa..06fa258c0997007eac9af86dfcd22843f7b35e4f 100644
--- a/lib/client/gnt_cluster.py
+++ b/lib/client/gnt_cluster.py
@@ -138,6 +138,17 @@ def InitCluster(opts, args):
                                          diskparams[templ])
     utils.ForceDictType(diskparams[templ], constants.DISK_DT_TYPES)
 
+  # prepare ipolicy dict
+  ipolicy_raw = \
+    objects.CreateIPolicyFromOpts(ispecs_mem_size=opts.ispecs_mem_count,
+                                  ispecs_cpu_count=opts.ispecs_cpu_count,
+                                  ispecs_disk_count=opts.ispecs_disk_count,
+                                  ispecs_disk_size=opts.ispecs_disk_size,
+                                  ispecs_nic_count=opts.ispecs_nic_count)
+  ipolicy = objects.FillDictOfDicts(constants.IPOLICY_DEFAULTS, ipolicy_raw)
+  for value in ipolicy.values():
+    utils.ForceDictType(value, constants.ISPECS_PARAMETER_TYPES)
+
   if opts.candidate_pool_size is None:
     opts.candidate_pool_size = constants.MASTER_POOL_SIZE_DEFAULT
 
@@ -183,6 +194,7 @@ def InitCluster(opts, args):
                         nicparams=nicparams,
                         ndparams=ndparams,
                         diskparams=diskparams,
+                        ipolicy=ipolicy,
                         candidate_pool_size=opts.candidate_pool_size,
                         modify_etc_hosts=opts.modify_etc_hosts,
                         modify_ssh_setup=opts.modify_ssh_setup,