ExtraConfig:
     default: {}
     description: |
-      Additional configuration to inject into the cluster. The JSON should have
-      the following structure:
-        {"FILEKEY":
-          {"config":
-            [{"section": "SECTIONNAME",
-              "values":
-                [{"option": "OPTIONNAME",
-                  "value": "VALUENAME"
-                 }
-                ]
-             }
-            ]
-          }
-        }
-      For instance:
-        {"nova":
-          {"config":
-            [{"section": "default",
-              "values":
-                [{"option": "force_config_drive",
-                  "value": "always"
-                 }
-                ]
-             },
-             {"section": "cells",
-              "values":
-                [{"option": "driver",
-                  "value": "nova.cells.rpc_driver.CellsRPCDriver"
-                 }
-                ]
-             }
-            ]
-          }
-        }
+      Additional configuration to inject into the cluster. The format required
+      may be implementation specific, e.g puppet hieradata.  Any role specific
+      ExtraConfig, e.g controllerExtraConfig takes precedence over ExtraConfig.
     type: json
   FencingConfig:
     default: {}
 
   ControllerExtraConfig:
     default: {}
     description: |
-      Controller specific configuration to inject into the cluster. Same
-      structure as ExtraConfig.
+      Controller specific hiera configuration data to inject into the cluster.
     type: json
   ControlVirtualInterface:
     default: 'br-ex'
   ExtraConfig:
     default: {}
     description: |
-      Additional configuration to inject into the cluster. The JSON should have
-      the following structure:
-        {"FILEKEY":
-          {"config":
-            [{"section": "SECTIONNAME",
-              "values":
-                [{"option": "OPTIONNAME",
-                  "value": "VALUENAME"
-                 }
-                ]
-             }
-            ]
-          }
-        }
-      For instance:
-        {"nova":
-          {"config":
-            [{"section": "default",
-              "values":
-                [{"option": "compute_manager",
-                  "value": "ironic.nova.compute.manager.ClusterComputeManager"
-                 }
-                ]
-             },
-             {"section": "cells",
-              "values":
-                [{"option": "driver",
-                  "value": "nova.cells.rpc_driver.CellsRPCDriver"
-                 }
-                ]
-             }
-            ]
-          }
-        }
+      Additional hieradata to inject into the cluster, note that
+      ControllerExtraConfig takes precedence over ExtraConfig.
     type: json
   FencingConfig:
     default: {}
         hiera:
           hierarchy:
             - heat_config_%{::deploy_config_name}
+            - controller_extraconfig
+            - extraconfig
             - controller
             - object
             - swift_devices_and_proxy # provided by SwiftDevicesAndProxyConfig
             - common
             - cinder_netapp_data # Optionally provided by ControllerExtraConfigPre
           datafiles:
+            controller_extraconfig:
+              mapped_data: {get_param: ControllerExtraConfig}
+            extraconfig:
+              mapped_data: {get_param: ExtraConfig}
             common:
               raw_data: {get_file: hieradata/common.yaml}
             ceph: