diff --git a/charms/gnocchi-k8s/lib/charms/gnocchi_k8s/v0/gnocchi_service.py b/charms/gnocchi-k8s/lib/charms/gnocchi_k8s/v0/gnocchi_service.py
new file mode 100644
index 00000000..f830ec2c
--- /dev/null
+++ b/charms/gnocchi-k8s/lib/charms/gnocchi_k8s/v0/gnocchi_service.py
@@ -0,0 +1,205 @@
+"""GnocchiService Provides and Requires module.
+
+This library contains the Requires and Provides classes for handling
+the Gnocchi service interface.
+
+Import `GnocchiServiceRequires` in your charm, with the charm object and the
+relation name:
+    - self
+    - "gnocchi-db"
+
+Two events are also available to respond to:
+    - readiness_changed
+    - goneaway
+
+A basic example showing the usage of this relation follows:
+
+```
+from charms.gnocchi_k8s.v0.gnocchi_service import (
+    GnocchiServiceRequires
+)
+
+class GnocchiServiceClientCharm(CharmBase):
+    def __init__(self, *args):
+        super().__init__(*args)
+        #  GnocchiService Requires
+        self.gnocchi_svc = GnocchiServiceRequires(
+            self, "gnocchi-db",
+        )
+        self.framework.observe(
+            self.gnocchi_svc.on.readiness_changed,
+            self._on_gnocchi_service_readiness_changed
+        )
+        self.framework.observe(
+            self.gnocchi_svc.on.goneaway,
+            self._on_gnocchi_service_goneaway
+        )
+
+    def _on_gnocchi_service_readiness_changed(self, event):
+        '''React to the Gnocchi service readiness changed event.
+
+        This event happens when Gnocchi service relation is added to the
+        model and relation data is changed.
+        '''
+        # Do something with the configuration provided by relation.
+        pass
+
+    def _on_gnocchi_service_goneaway(self, event):
+        '''React to the Gnocchi Service goneaway event.
+
+        This event happens when Gnocchi service relation is removed.
+        '''
+        # HeatSharedConfig Relation has goneaway.
+        pass
+```
+"""
+
+
+import json
+import logging
+from typing import (
+    Optional,
+)
+
+from ops.charm import (
+    CharmBase,
+    RelationBrokenEvent,
+    RelationChangedEvent,
+    RelationEvent,
+)
+from ops.framework import (
+    EventSource,
+    Object,
+    ObjectEvents,
+)
+from ops.model import (
+    Relation,
+)
+
+logger = logging.getLogger(__name__)
+
+# The unique Charmhub library identifier, never change it
+LIBID = "97b7682b415040f3b32d77fff8d93e7e"
+
+# Increment this major API version when introducing breaking changes
+LIBAPI = 0
+
+# Increment this PATCH version before using `charmcraft publish-lib` or reset
+# to 0 if you are raising the major API version
+LIBPATCH = 1
+
+
+class GnocchiServiceReadinessRequestEvent(RelationEvent):
+    """GnocchiServiceReadinessRequest Event."""
+
+    pass
+
+
+class GnocchiServiceProviderEvents(ObjectEvents):
+    """Events class for `on`."""
+
+    service_readiness = EventSource(GnocchiServiceReadinessRequestEvent)
+
+
+class GnocchiServiceProvides(Object):
+    """GnocchiServiceProvides class."""
+
+    on = GnocchiServiceProviderEvents()
+
+    def __init__(self, charm: CharmBase, relation_name: str):
+        super().__init__(charm, relation_name)
+        self.charm = charm
+        self.relation_name = relation_name
+        self.framework.observe(
+            self.charm.on[relation_name].relation_changed,
+            self._on_relation_changed,
+        )
+
+    def _on_relation_changed(self, event: RelationChangedEvent):
+        """Handle Gnocchi service relation changed."""
+        logging.debug("Gnocchi Service relation changed")
+        self.on.service_readiness.emit(event.relation)
+
+    def set_service_status(self, relation: Relation, is_ready: bool) -> None:
+        """Set gnocchi service readiness status on the relation."""
+        if not self.charm.unit.is_leader():
+            logging.debug("Not a leader unit, skipping setting ready status")
+            return
+
+        logging.debug(
+            f"Setting ready status on relation {relation.app.name} "
+            f"{relation.name}/{relation.id}"
+        )
+        relation.data[self.charm.app]["ready"] = json.dumps(is_ready)
+
+
+class GnocchiServiceReadinessChangedEvent(RelationEvent):
+    """GnocchiServiceReadinessChanged Event."""
+
+    pass
+
+
+class GnocchiServiceGoneAwayEvent(RelationEvent):
+    """GnocchiServiceGoneAway Event."""
+
+    pass
+
+
+class GnocchiServiceRequirerEvents(ObjectEvents):
+    """Events class for `on`."""
+
+    readiness_changed = EventSource(GnocchiServiceReadinessChangedEvent)
+    goneaway = EventSource(GnocchiServiceGoneAwayEvent)
+
+
+class GnocchiServiceRequires(Object):
+    """GnocchiServiceRequires class."""
+
+    on = GnocchiServiceRequirerEvents()
+
+    def __init__(self, charm: CharmBase, relation_name: str):
+        super().__init__(charm, relation_name)
+        self.charm = charm
+        self.relation_name = relation_name
+        self.framework.observe(
+            self.charm.on[relation_name].relation_changed,
+            self._on_relation_changed,
+        )
+        self.framework.observe(
+            self.charm.on[relation_name].relation_broken,
+            self._on_relation_broken,
+        )
+
+    def _on_relation_changed(self, event: RelationChangedEvent):
+        """Handle Gnocchi Service relation changed."""
+        logging.debug("Gnocchi service readiness data changed")
+        self.on.readiness_changed.emit(event.relation)
+
+    def _on_relation_broken(self, event: RelationBrokenEvent):
+        """Handle Gnocchi Service relation broken."""
+        logging.debug("Gnocchi service on_broken")
+        self.on.goneaway.emit(event.relation)
+
+    @property
+    def _gnocchi_service_rel(self) -> Optional[Relation]:
+        """The gnocchi service relation."""
+        return self.framework.model.get_relation(self.relation_name)
+
+    def get_remote_app_data(self, key: str) -> Optional[str]:
+        """Return the value for the given key from remote app data."""
+        if self._gnocchi_service_rel:
+            data = self._gnocchi_service_rel.data[
+                self._gnocchi_service_rel.app
+            ]
+            return data.get(key)
+
+        return None
+
+    @property
+    def service_ready(self) -> bool:
+        """Return the auth_encryption_key."""
+        is_ready = self.get_remote_app_data("ready")
+        if is_ready:
+            return json.loads(is_ready)
+
+        return False
diff --git a/charms/gnocchi-k8s/metadata.yaml b/charms/gnocchi-k8s/metadata.yaml
index 65a8e30d..d55f0315 100644
--- a/charms/gnocchi-k8s/metadata.yaml
+++ b/charms/gnocchi-k8s/metadata.yaml
@@ -52,6 +52,10 @@ requires:
   ceph:
     interface: ceph-client
 
+provides:
+  gnocchi-service:
+    interface: gnocchi
+
 peers:
   peers:
     interface: gnocchi-peer
diff --git a/charms/gnocchi-k8s/src/charm.py b/charms/gnocchi-k8s/src/charm.py
index 6204ec3f..e5909458 100755
--- a/charms/gnocchi-k8s/src/charm.py
+++ b/charms/gnocchi-k8s/src/charm.py
@@ -20,6 +20,7 @@ This charm provide Gnocchi services as part of an OpenStack deployment
 
 import logging
 from typing import (
+    Callable,
     List,
 )
 
@@ -30,7 +31,16 @@ import ops_sunbeam.container_handlers as sunbeam_chandlers
 import ops_sunbeam.core as sunbeam_core
 import ops_sunbeam.guard as sunbeam_guard
 import ops_sunbeam.relation_handlers as sunbeam_rhandlers
+from charms.gnocchi_k8s.v0.gnocchi_service import (
+    GnocchiServiceProvides,
+    GnocchiServiceReadinessRequestEvent,
+)
+from ops.charm import (
+    CharmBase,
+    RelationEvent,
+)
 from ops.framework import (
+    EventBase,
     StoredState,
 )
 from ops.main import (
@@ -43,6 +53,54 @@ GNOCHHI_WSGI_CONTAINER = "gnocchi-api"
 GNOCCHI_METRICD_CONTAINER = "gnocchi-metricd"
 
 
+class GnocchiServiceProvidesHandler(sunbeam_rhandlers.RelationHandler):
+    """Handler for Gnocchi service relation on provider side."""
+
+    def __init__(
+        self,
+        charm: CharmBase,
+        relation_name: str,
+        callback_f: Callable,
+    ):
+        """Create a new gnocchi service handler.
+
+        Create a new GnocchiServiceProvidesHandler that updates service
+        readiness on the related units.
+
+        :param charm: the Charm class the handler is for
+        :type charm: ops.charm.CharmBase
+        :param relation_name: the relation the handler is bound to
+        :type relation_name: str
+        :param callback_f: the function to call when the nodes are connected
+        :type callback_f: Callable
+        """
+        super().__init__(charm, relation_name, callback_f)
+
+    def setup_event_handler(self):
+        """Configure event handlers for Gnocchi service relation."""
+        logger.debug("Setting up Gnocchi service event handler")
+        svc = GnocchiServiceProvides(
+            self.charm,
+            self.relation_name,
+        )
+        self.framework.observe(
+            svc.on.service_readiness,
+            self._on_service_readiness,
+        )
+        return svc
+
+    def _on_service_readiness(
+        self, event: GnocchiServiceReadinessRequestEvent
+    ) -> None:
+        """Handle service readiness request event."""
+        self.callback_f(event)
+
+    @property
+    def ready(self) -> bool:
+        """Report if relation is ready."""
+        return True
+
+
 class GnocchiWSGIPebbleHandler(sunbeam_chandlers.WSGIPebbleHandler):
     """Pebble handler for Gnocchi WSGI services."""
 
@@ -173,6 +231,18 @@ class GnocchiOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
             f"http://localhost:{self.default_public_ingress_port}/healthcheck"
         )
 
+    def get_relation_handlers(self) -> List[sunbeam_rhandlers.RelationHandler]:
+        """Relation handlers for the service."""
+        handlers = super().get_relation_handlers()
+        self.svc_ready_handler = GnocchiServiceProvidesHandler(
+            self,
+            "gnocchi-service",
+            self.handle_readiness_request_from_event,
+        )
+        handlers.append(self.svc_ready_handler)
+
+        return handlers
+
     def get_pebble_handlers(
         self,
     ) -> List[sunbeam_chandlers.ServicePebbleHandler]:
@@ -212,6 +282,31 @@ class GnocchiOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
             ),
         ]
 
+    def configure_app_leader(self, event: EventBase):
+        """Run global app setup.
+
+        These are tasks that should only be run once per application and only
+        the leader runs them.
+        """
+        super().configure_app_leader(event)
+        self.set_readiness_on_related_units()
+
+    def handle_readiness_request_from_event(
+        self, event: RelationEvent
+    ) -> None:
+        """Set service readiness in relation data."""
+        self.svc_ready_handler.interface.set_service_status(
+            event.relation, self.bootstrapped()
+        )
+
+    def set_readiness_on_related_units(self) -> None:
+        """Set service readiness on gnocchi-service related units."""
+        logger.debug(
+            "Set service readiness on all connected gnocchi-service relations"
+        )
+        for relation in self.framework.model.relations["gnocchi-service"]:
+            self.svc_ready_handler.interface.set_service_status(relation, True)
+
 
 class GnocchiCephOperatorCharm(GnocchiOperatorCharm):
     """Charm the Gnocchi service with Ceph backend."""
diff --git a/charms/gnocchi-k8s/tests/unit/test_charm.py b/charms/gnocchi-k8s/tests/unit/test_charm.py
index 942e28b1..a52ccfaf 100644
--- a/charms/gnocchi-k8s/tests/unit/test_charm.py
+++ b/charms/gnocchi-k8s/tests/unit/test_charm.py
@@ -85,6 +85,7 @@ class TestGnocchiCephOperatorCharm(test_utils.CharmTestCase):
         self.harness.update_relation_data(
             ceph_rel_id, "ceph-mon/0", {"ingress-address": "10.0.0.33"}
         )
+        self.harness.add_relation("gnocchi-service", "ceilometer", app_data={})
         test_utils.add_ceph_relation_credentials(self.harness, ceph_rel_id)
         test_utils.add_db_relation_credentials(
             self.harness, test_utils.add_base_db_relation(self.harness)
diff --git a/charms/gnocchi-k8s/tox.ini b/charms/gnocchi-k8s/tox.ini
index 4a7848e9..0bc536c1 100644
--- a/charms/gnocchi-k8s/tox.ini
+++ b/charms/gnocchi-k8s/tox.ini
@@ -104,7 +104,7 @@ deps =
     isort
     codespell
 commands =
-    codespell {[vars]all_path} 
+    codespell {[vars]all_path}
     # pflake8 wrapper supports config from pyproject.toml
     pflake8 --exclude {[vars]lib_path} --config {toxinidir}/pyproject.toml {[vars]all_path}
     isort --check-only --diff {[vars]all_path} --skip-glob {[vars]lib_path}