diff --git a/cfg/config.yaml b/cfg/config.yaml
index 766ece37e1e7ac20bf16bb4bd69b3bdf43dc1817..6836fd55685d1529b8105e0f33765d584a787b80 100644
--- a/cfg/config.yaml
+++ b/cfg/config.yaml
@@ -8,69 +8,106 @@
 # federatedControls: ./cfg/federated.yaml
 
 master:
-  bins: 
-    apiserver:
+  components:
+    - apiserver
+    - scheduler
+    - controllermanager
+    - etcd 
+    - flanneld
+    # kubernetes is a component to cover the config file /etc/kubernetes/config that is referred to in the 
+    # benchmark but is believed to now be obselete
+    - kubernetes
+
+  kubernetes:
+    defaultconf: /etc/kubernetes/config
+
+  apiserver:
+    bins:
       - "kube-apiserver"
       - "hyperkube apiserver"
       - "apiserver"
-    scheduler:
+    confs:
+      - /etc/kubernetes/manifests/kube-apiserver.yaml
+      - /etc/kubernetes/apiserver.conf
+      - /etc/kubernetes/apiserver
+    defaultconf: /etc/kubernetes/apiserver
+
+  scheduler:
+    bins:
       - "kube-scheduler"
       - "hyperkube scheduler"
       - "scheduler"
-    controllermanager:
+    confs: 
+      - /etc/kubernetes/manifests/kube-scheduler.yaml
+      - /etc/kubernetes/scheduler.conf
+      - /etc/kubernetes/scheduler
+    defaultconf: /etc/kubernetes/scheduler
+
+  controllermanager:
+    bins:
       - "kube-controller-manager"
       - "hyperkube controller-manager"
       - "controller-manager"
-  confs:
-    apiserver: 
-      - /etc/kubernetes/admin.conf
-      - /etc/kubernetes/apiserver
-      - /etc/kubernetes/manifests/kube-apiserver.yaml
-    scheduler: 
-      - /etc/kubernetes/scheduler.conf
-      - /etc/kubernetes/scheduler
-      - /etc/kubernetes/manifests/kube-scheduler.yaml
-    controller-manager: 
+    confs:
+      - /etc/kubernetes/manifests/kube-controller-manager.yaml
       - /etc/kubernetes/controller-manager.conf
       - /etc/kubernetes/controller-manager
-      - /etc/kubernetes/manifests/kube-controller-manager.yaml
-    etcd:
+    defaultconf: /etc/kubernetes/controller-manager
+
+  etcd:
+    optional: true
+    bins:
+      - "etcd"
+    confs:
+      - /etc/kubernetes/manifests/etcd.yaml
       - /etc/etcd/etcd.conf
-    flanneld:
-      - /etc/sysconfig/flanneld
+    defaultconf: /etc/etcd/etcd.conf
+
+  flanneld:
+    optional: true
+    bins:
+      - flanneld
+    defaultconf: /etc/sysconfig/flanneld
+
 
 node:
-  bins:
-    kubelet:
+  components:
+    - kubelet
+    - proxy
+
+  kubelet:
+    bins:
       - "hyperkube kubelet"
       - "kubelet"
-    proxy:
+    confs:
+      - /etc/kubernetes/kubelet.conf
+      - /etc/kubernetes/kubelet
+  
+  proxy:
+    bins:
       - "kube-proxy"
       - "hyperkube proxy"
       - "proxy"
-  confs:
-    kubelet: 
-      - /etc/kubernetes/kubelet.conf
-      - /etc/kubernetes/kubelet
-    proxy: 
+    confs:
       - /etc/kubernetes/proxy.conf
       - /etc/kubernetes/proxy
       - /etc/kubernetes/addons/kube-proxy-daemonset.yaml
 
 federated:
-  bins:
-    fedapiserver:
+  components:
+    - fedapiserver
+    - fedcontrollermanager
+
+  fedapiserver:
+    bins:
       - "hyperkube federation-apiserver"
       - "kube-federation-apiserver"
       - "federation-apiserver"
-    fedcontrollermanager:
+
+  fedcontrollermanager:
+    bins:
       - "hyperkube federation-controller-manager"
       - "kube-federation-controller-manager"
       - "federation-controller-manager"
 
-optional:
-  bins:
-    etcd:
-      - "etcd"
-    flanneld:
-      - "flanneld"
+
diff --git a/cmd/common.go b/cmd/common.go
index 33c0a035601189ba2bd077fdede75822ffdc7e04..14f2998d67f2c7acad16dbc553443e54f0a33538 100644
--- a/cmd/common.go
+++ b/cmd/common.go
@@ -17,7 +17,6 @@ package cmd
 import (
 	"fmt"
 	"io/ioutil"
-	"os"
 
 	"github.com/aquasecurity/kube-bench/check"
 	"github.com/spf13/viper"
@@ -67,10 +66,10 @@ func runChecks(t check.NodeType) {
 		typeConf = viper.Sub("federated")
 	}
 
-	// Get the set of exectuables we care about on this type of node
-	binmap := getBinaries(typeConf.Sub("bins"), false)
-	extrasmap := getBinaries(viper.Sub("optional"), true)
-	confmap := getConfigFiles(typeConf.Sub("confs"))
+	// Get the set of exectuables and config files we care about on this type of node. This also
+	// checks that the executables we need for the node type are running.
+	binmap := getBinaries(typeConf)
+	confmap := getConfigFiles(typeConf)
 
 	// Run kubernetes installation validation checks.
 	verifyKubeVersion(kubeMajorVersion, kubeMinorVersion)
@@ -92,7 +91,6 @@ func runChecks(t check.NodeType) {
 	// Variable substitutions. Replace all occurrences of variables in controls files.
 	s := string(in)
 	s = makeSubstitutions(s, "bin", binmap)
-	s = makeSubstitutions(s, "bin", extrasmap)
 	s = makeSubstitutions(s, "conf", confmap)
 
 	controls, err := check.NewControls(t, []byte(s))
diff --git a/cmd/util.go b/cmd/util.go
index a89a1f08bde0158fca7ce14763db1d245380b6e4..52010f43023177b2614007c77179baef1d64def0 100644
--- a/cmd/util.go
+++ b/cmd/util.go
@@ -85,17 +85,34 @@ func ps(proc string) string {
 }
 
 // getBinaries finds which of the set of candidate executables are running
-func getBinaries(v *viper.Viper, optional bool) map[string]string {
+func getBinaries(v *viper.Viper) map[string]string {
 	binmap := make(map[string]string)
 
-	for _, exeType := range v.AllKeys() {
-		bin, err := findExecutable(v.GetStringSlice(exeType))
-		if err != nil && !optional {
-			exitWithError(fmt.Errorf("looking for %s executable but none of the candidates are running", exeType))
+	for _, component := range v.GetStringSlice("components") {
+		s := v.Sub(component)
+		if s == nil {
+			continue
 		}
 
-		binmap[exeType] = bin
+		optional := s.GetBool("optional")
+		bins := s.GetStringSlice("bins")
+		if len(bins) > 0 {
+			bin, err := findExecutable(bins)
+			if err != nil && !optional {
+				exitWithError(fmt.Errorf("need %s executable but none of the candidates are running", component))
+			}
+
+			// Default the executable name that we'll substitute to the name of the component
+			if bin == "" {
+				bin = component
+				glog.V(2).Info(fmt.Sprintf("Component %s not running", component))
+			} else {
+				glog.V(2).Info(fmt.Sprintf("Component %s uses running binary %s", component, bin))
+			}
+			binmap[component] = bin
+		}
 	}
+
 	return binmap
 }
 
@@ -103,13 +120,28 @@ func getBinaries(v *viper.Viper, optional bool) map[string]string {
 func getConfigFiles(v *viper.Viper) map[string]string {
 	confmap := make(map[string]string)
 
-	for _, confType := range v.AllKeys() {
-		conf := findConfigFile(v.GetStringSlice(confType))
+	for _, component := range v.GetStringSlice("components") {
+		s := v.Sub(component)
+		if s == nil {
+			continue
+		}
+
+		// See if any of the candidate config files exist
+		conf := findConfigFile(s.GetStringSlice("confs"))
 		if conf == "" {
-			printlnWarn(fmt.Sprintf("Missing kubernetes config file for %s", confType))
+			if s.IsSet("defaultconf") {
+				conf = s.GetString("defaultconf")
+				glog.V(2).Info(fmt.Sprintf("Using default config file name '%s' for component %s", conf, component))
+			} else {
+				// Default the config file name that we'll substitute to the name of the component
+				printlnWarn(fmt.Sprintf("Missing config file for %s", component))
+				conf = component
+			}
 		} else {
-			confmap[confType] = conf
+			glog.V(2).Info(fmt.Sprintf("Component %s uses config file '%s'", component, conf))
 		}
+
+		confmap[component] = conf
 	}
 
 	return confmap