diff --git a/lib/client/gnt_cluster.py b/lib/client/gnt_cluster.py
index 1fc0cf8e8a23713170f79f38bed67b0055ef37aa..cbaea0d444e795e2c66ddef2799f8d1b84899025 100644
--- a/lib/client/gnt_cluster.py
+++ b/lib/client/gnt_cluster.py
@@ -468,6 +468,8 @@ def ShowClusterConfig(opts, args):
     _PrintGroupedParams(result["ipolicy"][key], roman=opts.roman_integers)
   ToStdout("  - enabled disk templates: %s",
            utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS]))
+  for key in constants.IPOLICY_PARAMETERS:
+    ToStdout("  - %s: %s", key, result["ipolicy"][key])
 
   return 0
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 46bf7eeca6ab24acbb9d0aa942f16c64246c4643..7e00bf880ea2344e7e874a17ef2ad1786b1840f7 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -740,8 +740,6 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
                                        use_none=use_none,
                                        use_default=use_default)
     else:
-      # FIXME: we assume all others are lists; this should be redone
-      # in a nicer way
       if not value or value == [constants.VALUE_DEFAULT]:
         if group_policy:
           del ipolicy[key]
@@ -750,7 +748,18 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
                                      " on the cluster'" % key,
                                      errors.ECODE_INVAL)
       else:
-        ipolicy[key] = list(value)
+        if key in constants.IPOLICY_PARAMETERS:
+          # FIXME: we assume all such values are float
+          try:
+            ipolicy[key] = float(value)
+          except (TypeError, ValueError), err:
+            raise errors.OpPrereqError("Invalid value for attribute"
+                                       " '%s': '%s', error: %s" %
+                                       (key, value, err), errors.ECODE_INVAL)
+        else:
+          # FIXME: we assume all others are lists; this should be redone
+          # in a nicer way
+          ipolicy[key] = list(value)
   try:
     objects.InstancePolicy.CheckParameterSyntax(ipolicy)
   except errors.ConfigurationError, err:
diff --git a/lib/config.py b/lib/config.py
index a4f864d82dc15f4b9611b09854eb86b0fdad1844..abf379d4f225c5593a9be9f700906627e3358caa 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -439,10 +439,14 @@ class ConfigWriter:
           _helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES)
         else:
           # FIXME: assuming list type
-          if not isinstance(value, list):
+          if key in constants.IPOLICY_PARAMETERS:
+            exp_type = float
+          else:
+            exp_type = list
+          if not isinstance(value, exp_type):
             result.append("%s has invalid instance policy: for %s,"
-                          " expecting list, got %s" %
-                          (owner, key, type(value)))
+                          " expecting %s, got %s" %
+                          (owner, key, exp_type.__name__, type(value)))
 
     # check cluster parameters
     _helper("cluster", "beparams", cluster.SimpleFillBE({}),
diff --git a/lib/constants.py b/lib/constants.py
index b2cdfec35a0089ac9eb91f2139741aea0437399b..dcece0b4593ae150a205164f40c36f1167e1e434 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -950,13 +950,21 @@ ISPECS_MIN = "min"
 ISPECS_MAX = "max"
 ISPECS_STD = "std"
 IPOLICY_DTS = "disk_templates"
+IPOLICY_VCPU_RATIO = "vcpu_ratio"
 
 IPOLICY_ISPECS = frozenset([
   ISPECS_MIN,
   ISPECS_MAX,
   ISPECS_STD,
   ])
-IPOLICY_ALL_KEYS = IPOLICY_ISPECS.union([IPOLICY_DTS])
+
+IPOLICY_PARAMETERS = frozenset([
+  IPOLICY_VCPU_RATIO,
+  ])
+
+IPOLICY_ALL_KEYS = (IPOLICY_ISPECS |
+                    IPOLICY_PARAMETERS |
+                    frozenset([IPOLICY_DTS]))
 
 # Node parameter names
 ND_OOB_PROGRAM = "oob_program"
@@ -1907,6 +1915,7 @@ IPOLICY_DEFAULTS = {
     ISPEC_NIC_COUNT: 1,
     },
   IPOLICY_DTS: DISK_TEMPLATES,
+  IPOLICY_VCPU_RATIO: 4.0,
   }
 
 MASTER_POOL_SIZE_DEFAULT = 10
diff --git a/lib/objects.py b/lib/objects.py
index ff921d619e3aa71302a804d29f2f47032fd6be99..cfd723b818512f5b40c90bc83c5428af3673f11a 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -105,6 +105,9 @@ def FillIPolicy(default_ipolicy, custom_ipolicy, skip_keys=None):
   # list items
   for key in [constants.IPOLICY_DTS]:
     ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key]))
+  # other items which we know we can directly copy (immutables)
+  for key in constants.IPOLICY_PARAMETERS:
+    ret_dict[key] = custom_ipolicy.get(key, default_ipolicy[key])
 
   return ret_dict
 
@@ -908,6 +911,9 @@ class InstancePolicy(ConfigObject):
       InstancePolicy.CheckISpecSyntax(ipolicy, param)
     if constants.IPOLICY_DTS in ipolicy:
       InstancePolicy.CheckDiskTemplates(ipolicy[constants.IPOLICY_DTS])
+    for key in constants.IPOLICY_PARAMETERS:
+      if key in ipolicy:
+        InstancePolicy.CheckParameter(key, ipolicy[key])
     wrong_keys = frozenset(ipolicy.keys()) - constants.IPOLICY_ALL_KEYS
     if wrong_keys:
       raise errors.ConfigurationError("Invalid keys in ipolicy: %s" %
@@ -948,6 +954,19 @@ class InstancePolicy(ConfigObject):
       raise errors.ConfigurationError("Invalid disk template(s) %s" %
                                       utils.CommaJoin(wrong))
 
+  @classmethod
+  def CheckParameter(cls, key, value):
+    """Checks a parameter.
+
+    Currently we expect all parameters to be float values.
+
+    """
+    try:
+      float(value)
+    except (TypeError, ValueError), err:
+      raise errors.ConfigurationError("Invalid value for key" " '%s':"
+                                      " '%s', error: %s" % (key, value, err))
+
 
 class Instance(TaggableObject):
   """Config object representing an instance."""