diff --git a/jsonnet/kube-prometheus/lib/image.libsonnet b/jsonnet/kube-prometheus/lib/image.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..0561e33c820c207d8a7dd1da2b31bdd9350afd14
--- /dev/null
+++ b/jsonnet/kube-prometheus/lib/image.libsonnet
@@ -0,0 +1,21 @@
+// imageName extracts the image name from a fully qualified image string. eg.
+// quay.io/coreos/addon-resizer -> addon-resizer
+// grafana/grafana -> grafana
+local imageName(image) =
+  local parts = std.split(image, '/');
+  local len = std.length(parts);
+  if len == 3 then
+    # registry.com/org/image
+    parts[2]
+  else if len == 2 then
+    # org/image
+    parts[1]
+  else if len == 1 then
+    # image, ie. busybox
+    parts[0]
+  else
+      error 'unknown image format: ' + image;
+
+{
+  imageName:: imageName,
+}
diff --git a/jsonnet/kube-prometheus/lib/lib.libsonnet b/jsonnet/kube-prometheus/lib/lib.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..c30f976f15a4367a4361c72306aa579e5580f6fe
--- /dev/null
+++ b/jsonnet/kube-prometheus/lib/lib.libsonnet
@@ -0,0 +1 @@
+(import 'image.libsonnet')
diff --git a/sync-to-internal-registry.jsonnet b/sync-to-internal-registry.jsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..f0cf35ae3f2a4e7ac7d38ae927324fb3fa926771
--- /dev/null
+++ b/sync-to-internal-registry.jsonnet
@@ -0,0 +1,30 @@
+local kp = import 'kube-prometheus/kube-prometheus.libsonnet';
+local l = import 'kube-prometheus/lib/lib.libsonnet';
+local config = kp._config;
+
+local makeImages(config) = [
+    {
+        name: config.imageRepos[image],
+        tag: config.versions[image],
+    }
+    for image in std.objectFields(config.imageRepos)
+];
+
+local upstreamImage(image) = '%s:%s' % [image.name, image.tag];
+local downstreamImage(registry, image) = '%s/%s:%s' % [registry, l.imageName(image.name), image.tag];
+
+local pullPush(image, newRegistry) = [
+    'docker pull %s' % upstreamImage(image),
+    'docker tag %s %s' % [upstreamImage(image), downstreamImage(newRegistry, image)],
+    'docker push %s' % downstreamImage(newRegistry, image),
+];
+
+local images = makeImages(config);
+
+local output(repository) = std.flattenArrays([
+  pullPush(image, repository)
+  for image in images
+]);
+
+function(repository="my-registry.com/repository")
+    std.join('\n', output(repository))