diff --git a/files/gitlab-cookbooks/monitoring/attributes/default.rb b/files/gitlab-cookbooks/monitoring/attributes/default.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL2F0dHJpYnV0ZXMvZGVmYXVsdC5yYg==..b936676d711b66cc19630e9a22173d22c04d00fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL2F0dHJpYnV0ZXMvZGVmYXVsdC5yYg== 100644
--- a/files/gitlab-cookbooks/monitoring/attributes/default.rb
+++ b/files/gitlab-cookbooks/monitoring/attributes/default.rb
@@ -49,10 +49,10 @@
 ####
 # Prometheus Node Exporter
 ####
-default['monitoring']['node-exporter']['enable'] = false
-default['monitoring']['node-exporter']['home'] = '/var/opt/gitlab/node-exporter'
-default['monitoring']['node-exporter']['log_directory'] = '/var/log/gitlab/node-exporter'
-default['monitoring']['node-exporter']['env_directory'] = '/opt/gitlab/etc/node-exporter/env'
-default['monitoring']['node-exporter']['env'] = {
+default['monitoring']['node_exporter']['enable'] = false
+default['monitoring']['node_exporter']['home'] = '/var/opt/gitlab/node-exporter'
+default['monitoring']['node_exporter']['log_directory'] = '/var/log/gitlab/node-exporter'
+default['monitoring']['node_exporter']['env_directory'] = '/opt/gitlab/etc/node-exporter/env'
+default['monitoring']['node_exporter']['env'] = {
   'SSL_CERT_DIR' => "#{node['package']['install-dir']}/embedded/ssl/certs/"
 }
@@ -57,8 +57,8 @@
   'SSL_CERT_DIR' => "#{node['package']['install-dir']}/embedded/ssl/certs/"
 }
-default['monitoring']['node-exporter']['listen_address'] = 'localhost:9100'
-default['monitoring']['node-exporter']['consul_service_name'] = 'node-exporter'
-default['monitoring']['node-exporter']['consul_service_meta'] = nil
+default['monitoring']['node_exporter']['listen_address'] = 'localhost:9100'
+default['monitoring']['node_exporter']['consul_service_name'] = 'node-exporter'
+default['monitoring']['node_exporter']['consul_service_meta'] = nil
 
 ####
 # Redis exporter
@@ -187,3 +187,8 @@
   'startTLS_policy' => nil
 }
 default['monitoring']['grafana']['register_as_oauth_app'] = true
+
+# Temporarily retain support for `node['monitoring']['node-exporter'][*]` usage in
+# `/etc/gitlab/gitlab.rb`
+# TODO: Remove support in 16.0
+default['monitoring']['node-exporter'] = Gitlab::Deprecations::NodeAttribute.new(proc { node['monitoring']['node_exporter'].to_h }, "node['monitoring']['node-exporter']", "node['monitoring']['node_exporter']")
diff --git a/files/gitlab-cookbooks/monitoring/libraries/prometheus.rb b/files/gitlab-cookbooks/monitoring/libraries/prometheus.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL2xpYnJhcmllcy9wcm9tZXRoZXVzLnJi..b936676d711b66cc19630e9a22173d22c04d00fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL2xpYnJhcmllcy9wcm9tZXRoZXVzLnJi 100644
--- a/files/gitlab-cookbooks/monitoring/libraries/prometheus.rb
+++ b/files/gitlab-cookbooks/monitoring/libraries/prometheus.rb
@@ -94,7 +94,7 @@
     end
 
     def parse_node_exporter_flags
-      default_config = Gitlab['node']['monitoring']['node-exporter'].to_hash
+      default_config = Gitlab['node']['monitoring']['node_exporter'].to_hash
       user_config = Gitlab['node_exporter']
       runit_config = Gitlab['node']['runit'].to_hash
 
@@ -469,7 +469,8 @@
           'consul_sd_configs' => [{ 'services' => ["#{exporter}-exporter"] }]
         }
       else
-        default_config = Gitlab['node']['monitoring']["#{exporter}-exporter"].to_hash
+        node_attribute_key = SettingsDSL::Utils.sanitized_key("#{exporter}-exporter")
+        default_config = Gitlab['node']['monitoring'][node_attribute_key].to_hash
         user_config = Gitlab["#{exporter}_exporter"]
 
         listen_address = user_config['listen_address'] || default_config['listen_address']
diff --git a/files/gitlab-cookbooks/monitoring/recipes/default.rb b/files/gitlab-cookbooks/monitoring/recipes/default.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL3JlY2lwZXMvZGVmYXVsdC5yYg==..b936676d711b66cc19630e9a22173d22c04d00fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL3JlY2lwZXMvZGVmYXVsdC5yYg== 100644
--- a/files/gitlab-cookbooks/monitoring/recipes/default.rb
+++ b/files/gitlab-cookbooks/monitoring/recipes/default.rb
@@ -17,4 +17,5 @@
 
 # Configure Prometheus Services
 Prometheus.services.each do |service|
+  cookbook_name = SettingsDSL::Utils.hyphenated_form(service)
   if node['monitoring'][service]['enable']
@@ -20,3 +21,3 @@
   if node['monitoring'][service]['enable']
-    include_recipe "monitoring::#{service}"
+    include_recipe "monitoring::#{cookbook_name}"
   else
@@ -22,4 +23,4 @@
   else
-    include_recipe "monitoring::#{service}_disable"
+    include_recipe "monitoring::#{cookbook_name}_disable"
   end
 end
diff --git a/files/gitlab-cookbooks/monitoring/recipes/node-exporter.rb b/files/gitlab-cookbooks/monitoring/recipes/node-exporter.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL3JlY2lwZXMvbm9kZS1leHBvcnRlci5yYg==..b936676d711b66cc19630e9a22173d22c04d00fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL3JlY2lwZXMvbm9kZS1leHBvcnRlci5yYg== 100644
--- a/files/gitlab-cookbooks/monitoring/recipes/node-exporter.rb
+++ b/files/gitlab-cookbooks/monitoring/recipes/node-exporter.rb
@@ -17,9 +17,9 @@
 #
 account_helper = AccountHelper.new(node)
 prometheus_user = account_helper.prometheus_user
-node_exporter_log_dir = node['monitoring']['node-exporter']['log_directory']
-textfile_dir = File.join(node['monitoring']['node-exporter']['home'], 'textfile_collector')
-node_exporter_static_etc_dir = node['monitoring']['node-exporter']['env_directory']
+node_exporter_log_dir = node['monitoring']['node_exporter']['log_directory']
+textfile_dir = File.join(node['monitoring']['node_exporter']['home'], 'textfile_collector')
+node_exporter_static_etc_dir = node['monitoring']['node_exporter']['env_directory']
 
 # node-exporter runs under the prometheus user account. If prometheus is
 # disabled, it's up to this recipe to create the account
@@ -38,7 +38,7 @@
 end
 
 env_dir node_exporter_static_etc_dir do
-  variables node['monitoring']['node-exporter']['env']
+  variables node['monitoring']['node_exporter']['env']
   notifies :restart, "runit_service[node-exporter]"
 end
 
@@ -48,7 +48,7 @@
   recursive true
 end
 
-runtime_flags = PrometheusHelper.new(node).kingpin_flags('node-exporter')
+runtime_flags = PrometheusHelper.new(node).kingpin_flags('node_exporter')
 runit_service 'node-exporter' do
   options({
     log_directory: node_exporter_log_dir,
@@ -56,7 +56,7 @@
     env_dir: node_exporter_static_etc_dir
   }.merge(params))
   log_options node['gitlab']['logging'].to_hash.merge(
-    node['monitoring']['node-exporter'].to_hash
+    node['monitoring']['node_exporter'].to_hash
   )
 end
 
@@ -66,5 +66,5 @@
   end
 end
 
-consul_service node['monitoring']['node-exporter']['consul_service_name'] do
+consul_service node['monitoring']['node_exporter']['consul_service_name'] do
   id 'node-exporter'
@@ -70,3 +70,3 @@
   id 'node-exporter'
-  meta node['monitoring']['node-exporter']['consul_service_meta']
+  meta node['monitoring']['node_exporter']['consul_service_meta']
   action Prometheus.service_discovery_action
@@ -72,4 +72,4 @@
   action Prometheus.service_discovery_action
-  socket_address node['monitoring']['node-exporter']['listen_address']
+  socket_address node['monitoring']['node_exporter']['listen_address']
   reload_service false unless Services.enabled?('consul')
 end
diff --git a/files/gitlab-cookbooks/monitoring/recipes/node-exporter_disable.rb b/files/gitlab-cookbooks/monitoring/recipes/node-exporter_disable.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL3JlY2lwZXMvbm9kZS1leHBvcnRlcl9kaXNhYmxlLnJi..b936676d711b66cc19630e9a22173d22c04d00fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9tb25pdG9yaW5nL3JlY2lwZXMvbm9kZS1leHBvcnRlcl9kaXNhYmxlLnJi 100644
--- a/files/gitlab-cookbooks/monitoring/recipes/node-exporter_disable.rb
+++ b/files/gitlab-cookbooks/monitoring/recipes/node-exporter_disable.rb
@@ -20,7 +20,7 @@
   action :disable
 end
 
-consul_service node['monitoring']['node-exporter']['consul_service_name'] do
+consul_service node['monitoring']['node_exporter']['consul_service_name'] do
   id 'node-exporter'
   action :delete
   reload_service false unless Services.enabled?('consul')
diff --git a/files/gitlab-cookbooks/package/libraries/settings_dsl.rb b/files/gitlab-cookbooks/package/libraries/settings_dsl.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9zZXR0aW5nc19kc2wucmI=..b936676d711b66cc19630e9a22173d22c04d00fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9zZXR0aW5nc19kc2wucmI= 100644
--- a/files/gitlab-cookbooks/package/libraries/settings_dsl.rb
+++ b/files/gitlab-cookbooks/package/libraries/settings_dsl.rb
@@ -251,7 +251,11 @@
       def sanitized_key(key)
         # Services that have been migrated to use underscored form in Chef code
         # and no longer needs to be hyphenated.
-        skip_hyphenation = %w[gitlab_pages gitlab_sshd]
+        skip_hyphenation = %w[
+          gitlab_pages
+          gitlab_sshd
+          node_exporter
+        ]
 
         return underscored_form(key) if skip_hyphenation.include?(underscored_form(key))
 
diff --git a/spec/chef/cookbooks/gitlab/recipes/config_spec.rb b/spec/chef/cookbooks/gitlab/recipes/config_spec.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9jb25maWdfc3BlYy5yYg==..b936676d711b66cc19630e9a22173d22c04d00fd_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9jb25maWdfc3BlYy5yYg== 100644
--- a/spec/chef/cookbooks/gitlab/recipes/config_spec.rb
+++ b/spec/chef/cookbooks/gitlab/recipes/config_spec.rb
@@ -70,7 +70,7 @@
       expect(node['redis']['enable']).to eq true
       expect(node['monitoring']['prometheus']['enable']).to eq true
       expect(node['monitoring']['alertmanager']['enable']).to eq true
-      expect(node['monitoring']['node-exporter']['enable']).to eq true
+      expect(node['monitoring']['node_exporter']['enable']).to eq true
       expect(node['monitoring']['redis-exporter']['enable']).to eq true
       expect(node['logrotate']['enable']).to eq true
       expect(node['monitoring']['postgres-exporter']['enable']).to eq true
@@ -98,7 +98,7 @@
         expect(node['gitlab']['sentinel']['enable']).to eq true
         expect(node['redis']['enable']).to eq false
         expect(node['monitoring']['redis-exporter']['enable']).to eq false
-        expect(node['monitoring']['node-exporter']['enable']).to eq true
+        expect(node['monitoring']['node_exporter']['enable']).to eq true
         expect(node['logrotate']['enable']).to eq true
       end
 
@@ -121,7 +121,7 @@
           expect(node['gitlab']['sentinel']['enable']).to eq true
           expect(node['redis']['enable']).to eq true
           expect(node['monitoring']['redis-exporter']['enable']).to eq true
-          expect(node['monitoring']['node-exporter']['enable']).to eq true
+          expect(node['monitoring']['node_exporter']['enable']).to eq true
           expect(node['logrotate']['enable']).to eq true
         end
       end
@@ -150,7 +150,7 @@
           expect(node['gitlab']['sentinel']['enable']).to eq true
           expect(node['redis']['enable']).to eq true
           expect(node['monitoring']['redis-exporter']['enable']).to eq true
-          expect(node['monitoring']['node-exporter']['enable']).to eq true
+          expect(node['monitoring']['node_exporter']['enable']).to eq true
           expect(node['logrotate']['enable']).to eq true
         end
       end
@@ -172,7 +172,7 @@
         expect(node['redis']['enable']).to eq true
         expect(node['gitlab']['sentinel']['enable']).to eq false
         expect(node['monitoring']['redis-exporter']['enable']).to eq true
-        expect(node['monitoring']['node-exporter']['enable']).to eq true
+        expect(node['monitoring']['node_exporter']['enable']).to eq true
         expect(node['logrotate']['enable']).to eq true
       end
     end
diff --git a/spec/chef/cookbooks/monitoring/libraries/prometheus_spec.rb b/spec/chef/cookbooks/monitoring/libraries/prometheus_spec.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_c3BlYy9jaGVmL2Nvb2tib29rcy9tb25pdG9yaW5nL2xpYnJhcmllcy9wcm9tZXRoZXVzX3NwZWMucmI=..b936676d711b66cc19630e9a22173d22c04d00fd_c3BlYy9jaGVmL2Nvb2tib29rcy9tb25pdG9yaW5nL2xpYnJhcmllcy9wcm9tZXRoZXVzX3NwZWMucmI= 100644
--- a/spec/chef/cookbooks/monitoring/libraries/prometheus_spec.rb
+++ b/spec/chef/cookbooks/monitoring/libraries/prometheus_spec.rb
@@ -8,7 +8,7 @@
                                                  prometheus
                                                  alertmanager
                                                  grafana
-                                                 node-exporter
+                                                 node_exporter
                                                  redis-exporter
                                                  postgres-exporter
                                                  gitlab-exporter
diff --git a/spec/chef/cookbooks/package/libraries/config/services_spec.rb b/spec/chef/cookbooks/package/libraries/config/services_spec.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_c3BlYy9jaGVmL2Nvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9jb25maWcvc2VydmljZXNfc3BlYy5yYg==..b936676d711b66cc19630e9a22173d22c04d00fd_c3BlYy9jaGVmL2Nvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9jb25maWcvc2VydmljZXNfc3BlYy5yYg== 100644
--- a/spec/chef/cookbooks/package/libraries/config/services_spec.rb
+++ b/spec/chef/cookbooks/package/libraries/config/services_spec.rb
@@ -115,8 +115,8 @@
 
       it 'ignores disable on system services' do
         Services.disable('node_exporter')
-        expect(node['monitoring']['node-exporter']['enable']).to be true
+        expect(node['monitoring']['node_exporter']['enable']).to be true
       end
 
       it 'allows forced disable on system services' do
         Services.disable('node_exporter', include_system: true)
@@ -119,8 +119,8 @@
       end
 
       it 'allows forced disable on system services' do
         Services.disable('node_exporter', include_system: true)
-        expect(node['monitoring']['node-exporter']['enable']).to be false
+        expect(node['monitoring']['node_exporter']['enable']).to be false
       end
     end
 
@@ -251,7 +251,7 @@
         Services.disable_group('redis', Services::SYSTEM_GROUP, include_system: true)
         Services.enable_group('rails', 'monitoring', except: ['redis', Services::SYSTEM_GROUP])
         expect(node['monitoring']['redis-exporter']['enable']).to be false
-        expect(node['monitoring']['node-exporter']['enable']).to be false
+        expect(node['monitoring']['node_exporter']['enable']).to be false
         expect(node['gitlab']['puma']['enable']).to be true
 
         Services.enable_group('sidekiq', 'monitoring')
@@ -300,7 +300,7 @@
         Services.disable_group('redis', 'rails')
         Services.enable_group(Services::ALL_GROUPS, except: %w(redis rails))
         expect(node['gitlab']['puma']['enable']).to be false
-        expect(node['monitoring']['node-exporter']['enable']).to be true
+        expect(node['monitoring']['node_exporter']['enable']).to be true
         expect(node['monitoring']['redis-exporter']['enable']).to be false
       end
 
diff --git a/spec/chef/cookbooks/package/libraries/settings_dsl_spec.rb b/spec/chef/cookbooks/package/libraries/settings_dsl_spec.rb
index 313dbfc14e4e76a93914f07a9df47c7ecf7e3092_c3BlYy9jaGVmL2Nvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9zZXR0aW5nc19kc2xfc3BlYy5yYg==..b936676d711b66cc19630e9a22173d22c04d00fd_c3BlYy9jaGVmL2Nvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9zZXR0aW5nc19kc2xfc3BlYy5yYg== 100644
--- a/spec/chef/cookbooks/package/libraries/settings_dsl_spec.rb
+++ b/spec/chef/cookbooks/package/libraries/settings_dsl_spec.rb
@@ -26,7 +26,9 @@
   describe '.sanitized_key' do
     it 'returns underscored form for services specified to skip hyphenation' do
       [
-        %w[gitlab-pages gitlab_pages]
+        %w[gitlab-pages gitlab_pages],
+        %w[gitlab-sshd gitlab_sshd],
+        %w[node-exporter node_exporter]
       ].each do |input, output|
         expect(subject.sanitized_key(input)).to eq(output)
       end