diff --git a/ops-sunbeam/ops_sunbeam/charm.py b/ops-sunbeam/ops_sunbeam/charm.py
index 9bc1ea2e..f375de08 100644
--- a/ops-sunbeam/ops_sunbeam/charm.py
+++ b/ops-sunbeam/ops_sunbeam/charm.py
@@ -236,6 +236,14 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
                 "Not all relations are ready"
             )
 
+    def update_relations(self):
+        """Update relation data."""
+        for handler in self.relation_handlers:
+            try:
+                handler.update_relation_data()
+            except NotImplementedError:
+                logging.debug(f"send_requests not implemented for {handler}")
+
     def configure_unit(self, event: ops.framework.EventBase) -> None:
         """Run configuration on this unit."""
         self.check_leader_ready()
@@ -270,6 +278,11 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
     def configure_charm(self, event: ops.framework.EventBase) -> None:
         """Catchall handler to configure charm services."""
         with sunbeam_guard.guard(self, "Bootstrapping"):
+            # Publishing relation data may be dependent on something else (like
+            # receiving a piece of data from the leader). To cover that
+            # republish relation if the relation adapter has implemented an
+            # update method.
+            self.update_relations()
             self.configure_unit(event)
             self.configure_app(event)
             self.bootstrap_status.set(ActiveStatus())
diff --git a/ops-sunbeam/ops_sunbeam/relation_handlers.py b/ops-sunbeam/ops_sunbeam/relation_handlers.py
index de33ee29..6e49c751 100644
--- a/ops-sunbeam/ops_sunbeam/relation_handlers.py
+++ b/ops-sunbeam/ops_sunbeam/relation_handlers.py
@@ -138,6 +138,10 @@ class RelationHandler(ops.charm.Object):
         """Pull together context for rendering templates."""
         return self.interface_properties()
 
+    def update_relation_data(self):
+        """Update relation outside of relation context."""
+        raise NotImplementedError
+
 
 class IngressHandler(RelationHandler):
     """Base class to handle Ingress relations."""
@@ -826,6 +830,7 @@ class TlsCertificatesHandler(RelationHandler):
     ) -> None:
         """Run constructor."""
         self.sans = sans
+        self._private_key = None
         super().__init__(charm, relation_name, callback_f, mandatory)
         try:
             self.store = self.PeerKeyStore(
@@ -833,6 +838,7 @@ class TlsCertificatesHandler(RelationHandler):
             )
         except KeyError:
             self.store = self.LocalDBKeyStore(charm._state)
+        self.setup_private_key()
 
     def setup_event_handler(self) -> None:
         """Configure event handlers for tls relation."""
@@ -846,7 +852,6 @@ class TlsCertificatesHandler(RelationHandler):
         self.certificates = TLSCertificatesRequiresV1(
             self.charm, "certificates"
         )
-        self.framework.observe(self.charm.on.install, self._on_install)
         self.framework.observe(
             self.charm.on.certificates_relation_joined,
             self._on_certificates_relation_joined,
@@ -869,7 +874,8 @@ class TlsCertificatesHandler(RelationHandler):
         )
         return self.certificates
 
-    def _on_install(self, event: ops.framework.EventBase) -> None:
+    def setup_private_key(self) -> None:
+        """Create and store private key if needed."""
         # Lazy import to ensure this lib is only required if the charm
         # has this relation.
         from charms.tls_certificates_interface.v1.tls_certificates import (
@@ -877,45 +883,65 @@ class TlsCertificatesHandler(RelationHandler):
         )
 
         if not self.store.store_ready():
-            event.defer()
+            logger.debug("Store not ready, cannot generate key")
             return
 
         if self.store.get_private_key():
-            # Secret already saved
+            logger.debug("Private key already present")
+            self._private_key = self.store.get_private_key()
+            private_key_secret_id = self.store.get_private_key()
+            private_key_secret = self.model.get_secret(
+                id=private_key_secret_id
+            )
+            self._private_key = private_key_secret.get_content().get(
+                "private-key"
+            )
             return
 
-        private_key = generate_private_key()
+        self._private_key = generate_private_key()
         private_key_secret = self.model.unit.add_secret(
-            {"private-key": private_key.decode()},
+            {"private-key": self._private_key.decode()},
             label=f"{self.charm.model.unit}-private-key",
         )
 
         self.store.set_private_key(private_key_secret.id)
 
+    @property
+    def private_key(self):
+        """Private key for certificates."""
+        logger.debug("Returning private key: {}".format(self._private_key))
+        return self._private_key
+
+    def update_relation_data(self):
+        """Request certificates outside of relation context."""
+        self._request_certificates()
+
     def _on_certificates_relation_joined(
         self, event: ops.framework.EventBase
     ) -> None:
+        """Request certificates in response to relation join event."""
+        self._request_certificates()
+
+    def _request_certificates(self):
+        """Request certificates from remote provider."""
         # Lazy import to ensure this lib is only required if the charm
         # has this relation.
         from charms.tls_certificates_interface.v1.tls_certificates import (
             generate_csr,
         )
 
-        if not self.store.store_ready():
-            event.defer()
+        if self.ready:
+            logger.debug("Certificate request already complete.")
             return
 
-        private_key = None
-        private_key_secret_id = self.store.get_private_key()
-
-        if private_key_secret_id:
-            private_key_secret = self.model.get_secret(
-                id=private_key_secret_id
-            )
-            private_key = private_key_secret.get_content().get("private-key")
+        if self.private_key:
+            logger.debug("Private key found, requesting certificates")
+        else:
+            logger.debug("Cannot request certificates, private key not found")
+            return
 
         csr = generate_csr(
-            private_key=private_key.encode(),
+            private_key=self.private_key.encode(),
             subject=self.charm.model.unit.name.replace("/", "-"),
             sans=self.sans,
         )
@@ -998,16 +1024,8 @@ class TlsCertificatesHandler(RelationHandler):
         cert = certs["cert"]
         ca_cert = certs["ca"] + "\n" + "\n".join(certs["chain"])
 
-        key = None
-        private_key_secret_id = self.store.get_private_key()
-        if private_key_secret_id:
-            private_key_secret = self.model.get_secret(
-                id=private_key_secret_id
-            )
-            key = private_key_secret.get_content().get("private-key")
-
         ctxt = {
-            "key": key,
+            "key": self.private_key,
             "cert": cert,
             "ca_cert": ca_cert,
         }