diff --git a/files/gitlab-cookbooks/gitlab-ee/libraries/gitlab_geo.rb b/files/gitlab-cookbooks/gitlab-ee/libraries/gitlab_geo.rb
deleted file mode 100644
index 7c4c0949350934df709fbbe4f1ddc0152e87c375_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItZWUvbGlicmFyaWVzL2dpdGxhYl9nZW8ucmI=..0000000000000000000000000000000000000000
--- a/files/gitlab-cookbooks/gitlab-ee/libraries/gitlab_geo.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Copyright:: Copyright (c) 2016 GitLab Inc.
-# License:: Apache License, Version 2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-module GitlabGeo
-  class << self
-    def parse_variables
-      parse_data_dir if geo_postgresql_enabled?
-    end
-
-    private
-
-    def parse_data_dir
-      postgresql_data_dir = Gitlab['geo_postgresql']['data_dir'] || node['gitlab']['geo-postgresql']['data_dir']
-      Gitlab['geo_postgresql']['bootstrap'] = !File.exist?(File.join(postgresql_data_dir, 'PG_VERSION'))
-    end
-
-    def geo_primary_role?
-      Gitlab['geo_primary_role']['enable']
-    end
-
-    def geo_secondary_role?
-      Gitlab['geo_secondary_role']['enable']
-    end
-
-    def geo_postgresql_enabled?
-      Services.enabled?('geo_postgresql')
-    end
-
-    def node
-      Gitlab[:node]
-    end
-  end
-end
diff --git a/files/gitlab-cookbooks/gitlab-ee/recipes/geo-postgresql.rb b/files/gitlab-cookbooks/gitlab-ee/recipes/geo-postgresql.rb
index 7c4c0949350934df709fbbe4f1ddc0152e87c375_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItZWUvcmVjaXBlcy9nZW8tcG9zdGdyZXNxbC5yYg==..fdce020927bd62b081ac2e5c8df16b669e262dda_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWItZWUvcmVjaXBlcy9nZW8tcG9zdGdyZXNxbC5yYg== 100644
--- a/files/gitlab-cookbooks/gitlab-ee/recipes/geo-postgresql.rb
+++ b/files/gitlab-cookbooks/gitlab-ee/recipes/geo-postgresql.rb
@@ -60,7 +60,7 @@
 
 postgresql_config = File.join(postgresql_data_dir, 'postgresql.conf')
 postgresql_runtime_config = File.join(postgresql_data_dir, 'runtime.conf')
-bootstrapping = node['gitlab']['geo-postgresql']['bootstrap']
+bootstrapping = !geo_pg_helper.bootstrapped?
 should_notify = omnibus_helper.should_notify?('geo-postgresql') && !bootstrapping
 
 template postgresql_config do
@@ -80,7 +80,7 @@
   helper(:pg_helper) { geo_pg_helper }
   variables(node['gitlab']['geo-postgresql'].to_hash)
   cookbook 'gitlab'
-  notifies :run, 'execute[reload postgresql]', :immediately if should_notify
+  notifies :run, 'execute[reload geo-postgresql]', :immediately if should_notify
 end
 
 pg_hba_config = File.join(postgresql_data_dir, 'pg_hba.conf')
diff --git a/files/gitlab-cookbooks/package/libraries/config/gitlab.rb b/files/gitlab-cookbooks/package/libraries/config/gitlab.rb
index 7c4c0949350934df709fbbe4f1ddc0152e87c375_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9jb25maWcvZ2l0bGFiLnJi..fdce020927bd62b081ac2e5c8df16b669e262dda_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9wYWNrYWdlL2xpYnJhcmllcy9jb25maWcvZ2l0bGFiLnJi 100644
--- a/files/gitlab-cookbooks/package/libraries/config/gitlab.rb
+++ b/files/gitlab-cookbooks/package/libraries/config/gitlab.rb
@@ -50,7 +50,7 @@
   attribute_block 'gitlab' do
     # EE attributes
     ee_attribute('sidekiq_cluster', priority: 20).use { SidekiqCluster }
-    ee_attribute('geo_postgresql',  priority: 20).use { GitlabGeo }
+    ee_attribute('geo_postgresql',  priority: 20)
     ee_attribute('geo_secondary')
     ee_attribute('geo_logcursor')
 
diff --git a/spec/chef/gitlab-ee/libraries/gitlab_geo_spec.rb b/spec/chef/gitlab-ee/libraries/gitlab_geo_spec.rb
deleted file mode 100644
index 7c4c0949350934df709fbbe4f1ddc0152e87c375_c3BlYy9jaGVmL2dpdGxhYi1lZS9saWJyYXJpZXMvZ2l0bGFiX2dlb19zcGVjLnJi..0000000000000000000000000000000000000000
--- a/spec/chef/gitlab-ee/libraries/gitlab_geo_spec.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-require_relative '../../../../files/gitlab-cookbooks/gitlab-ee/libraries/gitlab_geo.rb'
-require 'chef_helper'
-
-describe GitlabGeo do
-  let(:node) { chef_run.node }
-
-  before do
-    allow(Gitlab).to receive(:[]).and_call_original
-  end
-
-  shared_examples 'default services' do
-    it 'remain enabled' do
-      chef_run
-      default_services = Services.find_by_group(Services::DEFAULT_GROUP).keys
-      expect(default_services.count).to be > 0
-      default_services.each { |service| expect(Services.enabled?(service)).to be(true) }
-    end
-  end
-
-  context 'when geo_primary_role enabled' do
-    cached(:chef_run) do
-      RSpec::Mocks.with_temporary_scope do
-        stub_gitlab_rb(geo_primary_role: { enable: true })
-      end
-      ChefSpec::SoloRunner.converge('gitlab-ee::default')
-    end
-
-    it_behaves_like 'default services'
-
-    context 'in geo_logcursor settings' do
-      it 'is not enabled' do
-        expect(node['gitlab']['geo-logcursor']['enable']).to eq(nil)
-      end
-    end
-
-    context 'in postgres settings' do
-      let(:config_attrs) { node['gitlab']['postgresql'] }
-
-      it 'defines sql_replication_user' do
-        expect(config_attrs['sql_replication_user']).to eq('gitlab_replicator')
-      end
-
-      it 'defines wal_level' do
-        expect(config_attrs['wal_level']).to eq('hot_standby')
-      end
-
-      it 'defines max_wal_senders' do
-        expect(config_attrs['max_wal_senders']).to eq(10)
-      end
-
-      it 'defines wal_keep_segments' do
-        expect(config_attrs['wal_keep_segments']).to eq(50)
-      end
-
-      it 'defines max_replication_slots' do
-        expect(config_attrs['max_replication_slots']).to eq(1)
-      end
-
-      it 'defines hot_standby' do
-        expect(config_attrs['hot_standby']).to eq('on')
-      end
-    end
-  end
-
-  context 'geo_secondary_role enabled' do
-    cached(:chef_run) do
-      RSpec::Mocks.with_temporary_scope do
-        stub_gitlab_rb(geo_secondary_role: { enable: true })
-      end
-      ChefSpec::SoloRunner.converge('gitlab-ee::default')
-    end
-
-    it_behaves_like 'default services'
-
-    context 'in geo_postgres settings' do
-      it 'is enabled' do
-        expect(node['gitlab']['geo-postgresql']['enable']).to eq(true)
-      end
-    end
-
-    context 'in geo_logcursor settings' do
-      it 'is enabled' do
-        expect(node['gitlab']['geo-logcursor']['enable']).to eq(true)
-      end
-    end
-
-    context 'in postgres settings' do
-      let(:config_attrs) { node['gitlab']['postgresql'] }
-
-      it 'defines wal_level' do
-        expect(config_attrs['wal_level']).to eq('hot_standby')
-      end
-
-      it 'defines max_wal_senders' do
-        expect(config_attrs['max_wal_senders']).to eq(10)
-      end
-
-      it 'defines wal_keep_segments' do
-        expect(config_attrs['wal_keep_segments']).to eq(10)
-      end
-
-      it 'defines max_replication_slots' do
-        expect(config_attrs['max_replication_slots']).to eq(0)
-      end
-
-      it 'defines hot_standby' do
-        expect(config_attrs['hot_standby']).to eq('on')
-      end
-    end
-
-    context 'in gitlab-rails' do
-      it 'disables auto_migrate' do
-        expect(node['gitlab']['gitlab-rails']['auto_migrate']).to eq(false)
-      end
-    end
-  end
-end
diff --git a/spec/chef/gitlab-ee/recipes/geo-postgresql_spec.rb b/spec/chef/gitlab-ee/recipes/geo-postgresql_spec.rb
index 7c4c0949350934df709fbbe4f1ddc0152e87c375_c3BlYy9jaGVmL2dpdGxhYi1lZS9yZWNpcGVzL2dlby1wb3N0Z3Jlc3FsX3NwZWMucmI=..fdce020927bd62b081ac2e5c8df16b669e262dda_c3BlYy9jaGVmL2dpdGxhYi1lZS9yZWNpcGVzL2dlby1wb3N0Z3Jlc3FsX3NwZWMucmI= 100644
--- a/spec/chef/gitlab-ee/recipes/geo-postgresql_spec.rb
+++ b/spec/chef/gitlab-ee/recipes/geo-postgresql_spec.rb
@@ -8,6 +8,11 @@
     allow(Gitlab).to receive(:[]).and_call_original
     allow_any_instance_of(GeoPgHelper).to receive(:version).and_return('9.2.18')
     allow_any_instance_of(GeoPgHelper).to receive(:database_version).and_return('9.2')
+
+    # Workaround for Chef reloading instances across different examples
+    allow_any_instance_of(GeoPgHelper).to receive(:bootstrapped?).and_return(true)
+    allow_any_instance_of(OmnibusHelper).to receive(:should_notify?).and_call_original
+    allow_any_instance_of(OmnibusHelper).to receive(:should_notify?).with('geo-postgresql').and_return(true)
   end
 
   context 'when geo postgres is disabled' do
@@ -177,6 +182,11 @@
         runtime_conf
       ).with_content(/archive_timeout = 120/)
     end
+
+    it 'notifies geo-postgresql reload' do
+      runtime_resource = chef_run.template(runtime_conf)
+      expect(runtime_resource).to notify('execute[reload geo-postgresql]').to(:run).immediately
+    end
   end
 end
 
diff --git a/spec/chef/gitlab-ee/recipes/geo_spec.rb b/spec/chef/gitlab-ee/recipes/geo_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fdce020927bd62b081ac2e5c8df16b669e262dda_c3BlYy9jaGVmL2dpdGxhYi1lZS9yZWNpcGVzL2dlb19zcGVjLnJi
--- /dev/null
+++ b/spec/chef/gitlab-ee/recipes/geo_spec.rb
@@ -0,0 +1,116 @@
+require 'chef_helper'
+
+describe 'gitlab-ee::geo' do
+  let(:node) { chef_run.node }
+
+  before do
+    allow(Gitlab).to receive(:[]).and_call_original
+  end
+
+  shared_examples 'default services' do
+    it 'remain enabled' do
+      chef_run
+      default_services = Services.find_by_group(Services::DEFAULT_GROUP).keys
+      expect(default_services.count).to be > 0
+      default_services.each { |service| expect(Services.enabled?(service)).to be(true) }
+    end
+  end
+
+  context 'when geo_primary_role enabled' do
+    cached(:chef_run) do
+      RSpec::Mocks.with_temporary_scope do
+        stub_gitlab_rb(geo_primary_role: { enable: true })
+      end
+      ChefSpec::SoloRunner.converge('gitlab-ee::default')
+    end
+
+    it_behaves_like 'default services'
+
+    context 'in geo_logcursor settings' do
+      it 'is not enabled' do
+        expect(node['gitlab']['geo-logcursor']['enable']).to eq(nil)
+      end
+    end
+
+    context 'in postgres settings' do
+      let(:config_attrs) { node['gitlab']['postgresql'] }
+
+      it 'defines sql_replication_user' do
+        expect(config_attrs['sql_replication_user']).to eq('gitlab_replicator')
+      end
+
+      it 'defines wal_level' do
+        expect(config_attrs['wal_level']).to eq('hot_standby')
+      end
+
+      it 'defines max_wal_senders' do
+        expect(config_attrs['max_wal_senders']).to eq(10)
+      end
+
+      it 'defines wal_keep_segments' do
+        expect(config_attrs['wal_keep_segments']).to eq(50)
+      end
+
+      it 'defines max_replication_slots' do
+        expect(config_attrs['max_replication_slots']).to eq(1)
+      end
+
+      it 'defines hot_standby' do
+        expect(config_attrs['hot_standby']).to eq('on')
+      end
+    end
+  end
+
+  context 'geo_secondary_role enabled' do
+    cached(:chef_run) do
+      RSpec::Mocks.with_temporary_scope do
+        stub_gitlab_rb(geo_secondary_role: { enable: true })
+      end
+      ChefSpec::SoloRunner.converge('gitlab-ee::default')
+    end
+
+    it_behaves_like 'default services'
+
+    context 'in geo_postgres settings' do
+      it 'is enabled' do
+        expect(node['gitlab']['geo-postgresql']['enable']).to eq(true)
+      end
+    end
+
+    context 'in geo_logcursor settings' do
+      it 'is enabled' do
+        expect(node['gitlab']['geo-logcursor']['enable']).to eq(true)
+      end
+    end
+
+    context 'in postgres settings' do
+      let(:config_attrs) { node['gitlab']['postgresql'] }
+
+      it 'defines wal_level' do
+        expect(config_attrs['wal_level']).to eq('hot_standby')
+      end
+
+      it 'defines max_wal_senders' do
+        expect(config_attrs['max_wal_senders']).to eq(10)
+      end
+
+      it 'defines wal_keep_segments' do
+        expect(config_attrs['wal_keep_segments']).to eq(10)
+      end
+
+      it 'defines max_replication_slots' do
+        expect(config_attrs['max_replication_slots']).to eq(0)
+      end
+
+      it 'defines hot_standby' do
+        expect(config_attrs['hot_standby']).to eq('on')
+      end
+    end
+
+    context 'in gitlab-rails' do
+      it 'disables auto_migrate' do
+        expect(node['gitlab']['gitlab-rails']['auto_migrate']).to eq(false)
+      end
+    end
+  end
+end