diff --git a/tools/notaryhealthcheck/build.gradle b/tools/notaryhealthcheck/build.gradle
index 3d0ac39e2b..6c1eed4657 100644
--- a/tools/notaryhealthcheck/build.gradle
+++ b/tools/notaryhealthcheck/build.gradle
@@ -45,17 +45,17 @@ publishing {
 
 task runTest(type: JavaExec) {
     classpath = sourceSets.main.runtimeClasspath
-    main = 'net.corda.notarytest.MainKt'
+    main = 'net.corda.notaryhealthcheck.MainKt'
 }
 
-task deployHealthCheck(type: Cordform, dependsOn: 'jar') {
-    definitionClass = 'net.corda.notarytest.HealthCheckCordform'
+task deployNodes(type: Cordform, dependsOn: 'jar') {
+    definitionClass = 'net.corda.notaryhealthcheck.HealthCheckCordform'
 }
 
 jar {
     manifest {
         attributes(
-                'Automatic-Module-Name': 'net.corda.notarytest'
+                'Automatic-Module-Name': 'net.corda.notaryhealthcheck'
         )
     }
 }
diff --git a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/HealthCheckCordform.kt b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/HealthCheckCordform.kt
new file mode 100644
index 0000000000..8f7bb5a4ef
--- /dev/null
+++ b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/HealthCheckCordform.kt
@@ -0,0 +1,58 @@
+package net.corda.notaryhealthcheck
+
+import net.corda.cordform.CordformContext
+import net.corda.cordform.CordformDefinition
+import net.corda.cordform.CordformNode
+import net.corda.core.identity.CordaX500Name
+import net.corda.core.utilities.NetworkHostAndPort
+import net.corda.node.services.Permissions.Companion.all
+import net.corda.node.services.config.NotaryConfig
+import net.corda.node.services.config.RaftConfig
+import net.corda.nodeapi.internal.DevIdentityGenerator
+import net.corda.testing.node.User
+import net.corda.testing.node.internal.demorun.*
+import java.nio.file.Paths
+
+fun main(args: Array<String>) = HealthCheckCordform().deployNodes()
+
+class HealthCheckCordform : CordformDefinition() {
+    private fun createNotaryNames(clusterSize: Int) = (0 until clusterSize).map { CordaX500Name("Notary Service $it", "Zurich", "CH") }
+    private val notaryDemoUser = User("demou", "demop", setOf(all()))
+    private val notaryNames = createNotaryNames(3)
+    private val clusterName = CordaX500Name("Raft", "Zurich", "CH")
+
+    init {
+        nodesDirectory = Paths.get("build", "nodes")
+        fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node {
+            name(notaryNames[index])
+            val clusterAddresses = if (clusterPort != null) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList()
+            notary(NotaryConfig(validating = true, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses)))
+            configure()
+        }
+        notaryNode(0, 10008) {
+            p2pPort(10009)
+            rpcPort(10010)
+        }
+        notaryNode(1, 10012, 10008) {
+            p2pPort(10013)
+            rpcPort(10014)
+        }
+        notaryNode(2, 10016, 10008) {
+            p2pPort(10017)
+            rpcPort(10018)
+        }
+        node {
+            name(CordaX500Name("R3 Notary Health Check", "London", "GB"))
+            p2pPort(10002)
+            rpcPort(10003)
+            rpcUsers(notaryDemoUser)
+        }
+    }
+
+    override fun setup(context: CordformContext) {
+        DevIdentityGenerator.generateDistributedNotarySingularIdentity(
+                notaryNames.map { context.baseDirectory(it.toString()) },
+                clusterName
+        )
+    }
+}
\ No newline at end of file
diff --git a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/Main.kt b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/Main.kt
similarity index 70%
rename from tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/Main.kt
rename to tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/Main.kt
index 8a6de73657..fc6dc8348b 100644
--- a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/Main.kt
+++ b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/Main.kt
@@ -1,4 +1,4 @@
-package net.corda.notarytest
+package net.corda.notaryhealthcheck
 
 import net.corda.client.rpc.CordaRPCClient
 import net.corda.core.messaging.CordaRPCOps
@@ -6,21 +6,22 @@ import net.corda.core.messaging.startFlow
 import net.corda.core.utilities.NetworkHostAndPort
 import net.corda.nodeapi.internal.config.User
 import net.corda.node.services.Permissions
-import net.corda.notarytest.flows.HealthCheckFlow
+import net.corda.notaryhealthcheck.flows.HealthCheckFlow
 
 fun main(args: Array<String>) {
     val addresses = listOf(NetworkHostAndPort("localhost", 10003))
-
     val notaryDemoUser = User("demou", "demop", setOf(Permissions.all()))
 
     addresses.parallelStream().forEach {
        val c = CordaRPCClient(it).start(notaryDemoUser.username, notaryDemoUser.password)
        healthCheck(c.proxy)
     }
-    println("ok")
+    println("Health check complete.")
 }
 
 fun healthCheck(rpc: CordaRPCOps) {
     val notary = rpc.notaryIdentities().first()
-    rpc.startFlow(::HealthCheckFlow, notary).returnValue.get()
+    print("Running health check for notary cluster ${notary.name}... ")
+    rpc.startFlow(::HealthCheckFlow, notary, true).returnValue.get()
+    println("Done.")
 }
diff --git a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/flows/HealthCheckFlow.kt b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/flows/HealthCheckFlow.kt
similarity index 58%
rename from tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/flows/HealthCheckFlow.kt
rename to tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/flows/HealthCheckFlow.kt
index f87b00f216..536b6f90f1 100644
--- a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/flows/HealthCheckFlow.kt
+++ b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/flows/HealthCheckFlow.kt
@@ -1,11 +1,10 @@
-package net.corda.notarytest.flows
+package net.corda.notaryhealthcheck.flows
 
 import co.paralleluniverse.fibers.Suspendable
 import net.corda.core.contracts.CommandData
 import net.corda.core.contracts.Contract
 import net.corda.core.contracts.ContractState
 import net.corda.core.flows.FlowLogic
-import net.corda.core.flows.NotaryFlow
 import net.corda.core.flows.StartableByRPC
 import net.corda.core.identity.AbstractParty
 import net.corda.core.identity.Party
@@ -13,26 +12,21 @@ import net.corda.core.transactions.LedgerTransaction
 import net.corda.core.transactions.TransactionBuilder
 
 @StartableByRPC
-open class HealthCheckFlow(val notaryParty: Party) : FlowLogic<Unit>() {
-
+open class HealthCheckFlow(val notaryParty: Party, val checkEntireCluster: Boolean = false) : FlowLogic<Unit>() {
     class DoNothingContract : Contract {
         override fun verify(tx: LedgerTransaction) {}
     }
 
     data class DummyCommand(val dummy: Int = 0) : CommandData
+    data class State(override val participants: List<AbstractParty>) : ContractState
 
     @Suspendable
-    override fun call(): Unit {
-
-        data class State(override val participants: List<AbstractParty>) : ContractState
-
+    override fun call() {
         val state = State(listOf(ourIdentity))
-
-         val stx = serviceHub.signInitialTransaction(TransactionBuilder(notaryParty).apply {
-            addOutputState(state, "net.corda.notarytest.flows.HealthCheckFlow\$DoNothingContract")
+        val stx = serviceHub.signInitialTransaction(TransactionBuilder(notaryParty).apply {
+            addOutputState(state, "net.corda.notaryhealthcheck.flows.HealthCheckFlow\$DoNothingContract")
             addCommand(DummyCommand(), listOf(ourIdentity.owningKey))
         })
-
-        subFlow(NotaryFlow.Client(stx))
+        subFlow(HealthCheckNotaryClientFlow(stx, checkEntireCluster = checkEntireCluster))
     }
 }
\ No newline at end of file
diff --git a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/flows/HealthCheckNotaryClientFlow.kt b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/flows/HealthCheckNotaryClientFlow.kt
new file mode 100644
index 0000000000..e36f24995a
--- /dev/null
+++ b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notaryhealthcheck/flows/HealthCheckNotaryClientFlow.kt
@@ -0,0 +1,56 @@
+package net.corda.notaryhealthcheck.flows
+
+import co.paralleluniverse.fibers.Suspendable
+import net.corda.core.crypto.TransactionSignature
+import net.corda.core.flows.NotaryError
+import net.corda.core.flows.NotaryException
+import net.corda.core.flows.NotaryFlow
+import net.corda.core.transactions.SignedTransaction
+
+/**
+ * Notarises the provided transaction. If [checkEntireCluster] is set to *true*, will repeat the notarisation request
+ * to each member of the notary cluster.
+ */
+class HealthCheckNotaryClientFlow(
+        stx: SignedTransaction,
+        /**
+         * If set to *true*, will issue a notarisation request to each replica in the notary cluster,
+         * rather than sending the request to one replica only.
+         */
+        private val checkEntireCluster: Boolean = false
+) : NotaryFlow.Client(stx) {
+    @Suspendable
+    @Throws(NotaryException::class)
+    override fun call(): List<TransactionSignature> {
+        progressTracker.currentStep = REQUESTING
+        val notaryParty = checkTransaction()
+
+        val parties = if (checkEntireCluster) {
+            serviceHub.networkMapCache
+                    .getNodesByLegalIdentityKey(notaryParty.owningKey)
+                    .map { it.legalIdentities.first() }
+        } else {
+            listOf(notaryParty)
+        }
+        var signatures: List<TransactionSignature> = emptyList()
+        parties.forEach { nodeLegalIdentity ->
+            logger.info("Sending notarisation request to: $nodeLegalIdentity")
+            val response = try {
+                val session = initiateFlow(nodeLegalIdentity)
+                if (serviceHub.networkMapCache.isValidatingNotary(notaryParty)) {
+                    sendAndReceiveValidating(session)
+                } else {
+                    sendAndReceiveNonValidating(nodeLegalIdentity, session)
+                }
+            } catch (e: NotaryException) {
+                if (e.error is NotaryError.Conflict) {
+                    (e.error as NotaryError.Conflict).conflict.verified()
+                }
+                throw e
+            }
+            signatures = validateResponse(response, notaryParty)
+            logger.info("Received a valid signature from $nodeLegalIdentity, signed by $notaryParty")
+        }
+        return signatures
+    }
+}
\ No newline at end of file
diff --git a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/HealthCheckCordform.kt b/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/HealthCheckCordform.kt
deleted file mode 100644
index ee26a4f9ea..0000000000
--- a/tools/notaryhealthcheck/src/main/kotlin/net/corda/notarytest/HealthCheckCordform.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.corda.notarytest
-
-import net.corda.cordform.CordformContext
-import net.corda.cordform.CordformDefinition
-import net.corda.core.identity.CordaX500Name
-import net.corda.node.services.Permissions.Companion.all
-import net.corda.node.services.config.NotaryConfig
-import net.corda.testing.node.User
-import net.corda.testing.node.internal.demorun.*
-import java.nio.file.Paths
-
-fun main(args: Array<String>) = HealthCheckCordform().deployNodes()
-
-val notaryDemoUser = User("demou", "demop", setOf(all()))
-
-// This is not the intended final design for how to use CordformDefinition, please treat this as experimental and DO
-// NOT use this as a design to copy.
-class HealthCheckCordform : CordformDefinition() {
-    init {
-        nodesDirectory = Paths.get("build", "nodes")
-        node {
-            name(CordaX500Name("R3 Notary Health Check", "London", "GB"))
-            p2pPort(10002)
-            rpcPort(10003)
-            rpcUsers(notaryDemoUser)
-        }
-        node {
-            name(CordaX500Name("Notary Service 0", "London", "GB"))
-            p2pPort(10009)
-            rpcPort(10010)
-            notary(NotaryConfig(validating = false))
-            extraConfig = mapOf(
-                    "mysql" to mapOf(
-                            "jdbcUrl" to "jdbc:mysql://notary-10.northeurope.cloudapp.azure.com:3306/corda?rewriteBatchedStatements=true&useSSL=false",
-                            "username" to "",
-                            "password" to "",
-                            "autoCommit" to "false"
-                    )
-            )
-        }
-    }
-
-    override fun setup(context: CordformContext) {}
-}