diff --git a/software/slaprunner/buildout.hash.cfg b/software/slaprunner/buildout.hash.cfg
index 43cd6f970565a77905ef60263ea77ebf028afb53..ef038ee6228e8aab31ae028a23b65b95fafea20e 100644
--- a/software/slaprunner/buildout.hash.cfg
+++ b/software/slaprunner/buildout.hash.cfg
@@ -14,11 +14,11 @@
 # not need these here).
 [template]
 filename = instance.cfg
-md5sum = 317c49bf451e80bf0f9d44baa603861e
+md5sum = 8b78e32b877d591400746ec7fd68ed4c
 
 [template-runner]
 filename = instance-runner.cfg
-md5sum = bacb2d1a38d3a512025e861debdc75b2
+md5sum = 85ea0b78fd18428c242438ebe95f980b
 
 [template-runner-import-script]
 filename = template/runner-import.sh.jinja2
@@ -26,7 +26,7 @@ md5sum = fc22e2d2f03ce58631f157a5b4943e15
 
 [instance-runner-import]
 filename = instance-runner-import.cfg.in
-md5sum = 1f1c62f2bc09a6ab3a2f96eacdf99492
+md5sum = b450c474464a326f3d0b98728460ac97
 
 [instance-runner-export]
 filename = instance-runner-export.cfg.in
@@ -34,7 +34,7 @@ md5sum = b992bb3391de9d6d422bfa8011d8ffc4
 
 [template-resilient]
 filename = instance-resilient.cfg.jinja2
-md5sum = 0f3d75ca834839c5ae04e9c26cca289a
+md5sum = 2271c829b94542b7b2d9c589376ae538
 
 [template_nginx_conf]
 filename = nginx_conf.in
diff --git a/software/slaprunner/instance-resilient.cfg.jinja2 b/software/slaprunner/instance-resilient.cfg.jinja2
index 5d23a95baaea0a26a72fb7621257640011397462..d9eaae96449cfb87bdd8484137f5f9cbec1c2741 100644
--- a/software/slaprunner/instance-resilient.cfg.jinja2
+++ b/software/slaprunner/instance-resilient.cfg.jinja2
@@ -26,6 +26,9 @@ eggs-directory = {{ eggs_directory }}
 develop-eggs-directory = {{ develop_eggs_directory }}
 offline = true
 
+extends =
+  {{ monitor_template }}
+
 # += because we need to take up parts (like instance-custom, slapmonitor etc) from the profile we extended
 parts +=
   publish-early
diff --git a/software/slaprunner/instance-runner-import.cfg.in b/software/slaprunner/instance-runner-import.cfg.in
index 93dda4869098e437dd72aeddd001621f7021f88a..7af0e2dc6937342a0d9cf84876687bfa6e5d6d25 100644
--- a/software/slaprunner/instance-runner-import.cfg.in
+++ b/software/slaprunner/instance-runner-import.cfg.in
@@ -112,7 +112,7 @@ context =
   raw  restore_exit_code_file ${:restore-exit-code-file}
   raw  restore_error_message_file ${:restore-error-message-file}
 
-[importer-consistency-promise]
+[importer-consistency-promise-bin]
 # Test that the importer script and "after-import" subscripts
 # are not older than 2 days (1 day + some slack), and have succeeded
 recipe = collective.recipe.template
@@ -135,10 +135,16 @@ input = inline: #!/bin/sh
     fi
   fi
   exit 1; # Something else went wrong
-output = ${directory:promises}/importer-consistency-promise
+output = ${directory:bin}/importer-consistency-promise
 mode = 755
 
-[software-release-deployment-promise]
+[importer-consistency-promise]
+<= monitor-promise-base
+module = check_command_execute
+name = importer-consistency-promise.py
+config-command = ${importer-consistency-promise-bin:output}
+
+[software-release-deployment-bin]
 recipe = collective.recipe.template
 input = inline: #!/bin/sh
   PROJECT_FILE=$(find "${directory:etc}" -maxdepth 1 -name .project)
@@ -153,9 +159,15 @@ input = inline: #!/bin/sh
     fi
   fi
   exit 1
-output = ${directory:promises}/software-release-deployment-promise
+output = ${directory:bin}/software-release-deployment-promise
 mode = 755
 
+[software-release-deployment-promise]
+<= monitor-promise-base
+module = check_command_execute
+name = software-release-deployment-promise.py
+config-command =${software-release-deployment-bin:output}
+
 [resilient-software-release-information]
 recipe = slapos.recipe.template
 url = {{ software_release_information_template }}
diff --git a/software/slaprunner/instance-runner.cfg b/software/slaprunner/instance-runner.cfg
index 8a31174542de0214e77c40333febad5ab9c8e500..380c9fbd6c9097753e52a0d056f28ad5a8ce0cc9 100644
--- a/software/slaprunner/instance-runner.cfg
+++ b/software/slaprunner/instance-runner.cfg
@@ -85,20 +85,18 @@ config-url = {{ slapparameter_dict.get('custom-frontend-backend-url') }}
 return = site_url domain
 
 [custom-frontend-promise]
-recipe = slapos.cookbook:check_url_available
-path = $${directory:promises}/custom_frontend_promise
-url = https://$${request-custom-frontend:connection-domain}
+<= monitor-promise-base
+module = check_url_available
+name = custom_frontend_promise.py
+config-url = https://$${request-custom-frontend:connection-domain}
 {% if slapparameter_dict.get('custom-frontend-basic-auth') -%}
-check-secure = 1
+config-check-secure = 1
 {% endif -%}
-dash_path = {{ dash_executable_location }}
-curl_path = {{ curl_executable_location }}
 
-[custom-frontend-url-ready-promise]
+[custom-frontend-url-ready-promise-bin]
 recipe = slapos.recipe.template:jinja2
-path = $${directory:promises}/custom_frontend_ready_promise
 url = https://$${request-custom-frontend:connection-domain}
-rendered = $${directory:promises}/custom_frontend_ready_promise
+rendered = $${directory:bin}/custom_frontend_ready_promise
 template = inline:
   #!{{ dash_executable_location }}
 
@@ -110,6 +108,12 @@ template = inline:
     exit 1
   fi
 
+[custom-frontend-url-ready-promise]
+<= monitor-promise-base
+module = check_command_execute
+name = custom_frontend_ready_promise.py
+config-command = $${custom-frontend-url-ready-promise-bin:rendered}
+
 [publish-connection-information]
 custom-frontend-url = $${custom-frontend-url-ready-promise:url}
 {% endif %}
@@ -135,7 +139,6 @@ ssh = $${:etc}/ssh/
 log = $${:var}/log/
 run = $${:var}/run/
 backup = $${:srv}/backup/
-promises = $${:etc}/promise/
 test = $${:etc}/test/
 nginx-data = $${:srv}/nginx
 ca-dir = $${:srv}/ssl
@@ -476,13 +479,12 @@ output = $${directory:scripts}/slaprunner-httpd-graceful
 mode = 700
 
 [apache-httpd-promise]
-recipe = slapos.cookbook:check_url_available
-path = $${directory:promises}/$${:filename}
+<= monitor-promise-base
+module = check_url_available
+name = $${:filename}.py
 filename = apache-httpd-listening-on-tcp
-url = $${apache-httpd:access-url}
-check-secure = 1
-dash_path = {{ dash_executable_location }}
-curl_path = {{ curl_executable_location }}
+config-url = $${apache-httpd:access-url}
+config-check-secure = 1
 
 [slaprunner-httpd-cors]
 recipe = plone.recipe.command
@@ -579,12 +581,11 @@ config-domain = $${slap-parameter:frontend-domain}
 return = site_url domain
 
 [slaprunner-frontend-promise]
-recipe = slapos.cookbook:check_url_available
-path = $${directory:promises}/slaprunner_frontend
-url = https://$${request-frontend:connection-domain}/login
-dash_path = ${dash:location}/bin/dash
-curl_path = ${curl:location}/bin/curl
-check-secure = 1
+<= monitor-promise-base
+module = check_url_available
+name = slaprunner_frontend.py
+config-url = https://$${request-frontend:connection-domain}/login
+config-check-secure = 1
 
 [request-httpd-frontend]
 <= slap-connection
@@ -600,12 +601,11 @@ config-domain =
 return = secure_access domain
 
 [httpd-frontend-promise]
-recipe = slapos.cookbook:check_url_available
-path = $${directory:promises}/slaprunner-apache-http-frontend
-url = $${request-httpd-frontend:connection-secure_access}
-dash_path = {{ dash_executable_location }}
-curl_path = {{ curl_executable_location }}
-check-secure = 1
+<= monitor-promise-base
+module = check_url_available
+name = slaprunner-apache-http-frontend.py
+config-url = $${request-httpd-frontend:connection-secure_access}
+config-check-secure = 1
 
 {% endif %}
 
@@ -667,16 +667,18 @@ monitor-password = $${monitor-publish-parameters:monitor-password}
 #-- Deploy promises scripts
 
 [slaprunner-promise]
-recipe = slapos.cookbook:check_port_listening
-path = $${directory:promises}/slaprunner
-hostname = $${slaprunner:ipv6}
-port = $${slaprunner:runner_port}
+<= monitor-promise-base
+module = check_port_listening
+name = slaprunner.py
+config-hostname = $${slaprunner:ipv6}
+config-port = $${slaprunner:runner_port}
 
 [runner-sshd-promise]
-recipe = slapos.cookbook:check_port_listening
-path = $${directory:promises}/runner-sshd
-hostname = $${slap-network-information:global-ipv6}
-port = $${runner-sshd-port:port}
+<= monitor-promise-base
+module = check_port_listening
+name = runner-sshd.py
+config-hostname = $${slap-network-information:global-ipv6}
+config-port = $${runner-sshd-port:port}
 
 [symlinks]
 recipe = cns.recipe.symlink
@@ -891,10 +893,11 @@ name = slapgrid
 log = $${runnerdirectory:home}/instance/*/.slapgrid/log/instance.log $${runnerdirectory:home}/instance/*/.slapgrid/promise/log/*.log
 
 [supervisord-promise]
-recipe = slapos.cookbook:check_port_listening
-path = $${directory:promises}/supervisord
-hostname = $${slaprunner:ipv4}
-port = $${supervisord:port}
+<= monitor-promise-base
+module = check_port_listening
+name = supervisord.py
+config-hostname = $${slaprunner:ipv4}
+config-port = $${supervisord:port}
 
 # XXX Monitor
 [monitor-instance-parameter]
diff --git a/software/slaprunner/instance.cfg b/software/slaprunner/instance.cfg
index 537ab2756dd4a4befb2242bf1d7fd258747736cf..de1389256b2e7bbf2ee804d390052c12c9934e66 100644
--- a/software/slaprunner/instance.cfg
+++ b/software/slaprunner/instance.cfg
@@ -42,6 +42,7 @@ context = key buildout buildout:bin-directory
           key develop_eggs_directory buildout:develop-eggs-directory
           key eggs_directory buildout:eggs-directory
           key slapparameter_dict slap-configuration:configuration
+          raw monitor_template ${monitor-template:rendered}
 template-parts-destination = ${template-parts:target}
 template-replicated-destination = ${template-replicated:target}
 import-list = file parts :template-parts-destination