diff --git a/.gitignore b/.gitignore
index 857cb4a..f002c30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,8 +20,7 @@
 # Go workspace file
 go.work
 
-cloudflare-tunnel-ingress-controller
-!image/cloudflare-tunnel-ingress-controller
+/cloudflare-tunnel-ingress-controller
 hack/dev/cloudflare-api.yaml
 
 # go test coverage report
diff --git a/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-connector-headless-service.yaml b/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-connector-headless-service.yaml
index d189249..c6cadc1 100644
--- a/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-connector-headless-service.yaml
+++ b/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-connector-headless-service.yaml
@@ -3,15 +3,20 @@ apiVersion: v1
 kind: Service
 metadata:
   name: controlled-cloudflared-connector-headless
+  labels:
+    app.kubernetes.io/component: controlled-cloudflared
+    {{- include "cloudflare-tunnel-ingress-controller.labels" . | nindent 4 }}
   annotations:
+    {{- if not .Values.cloudflaredServiceMonitor.create }}
     prometheus.io/scrape: "true"
     prometheus.io/port: "44483"
+    {{- end }}
 spec:
-    ports:
+  ports:
     - name: metrics
       port: 44483
       protocol: TCP
-    clusterIP: None
-    selector:
-        "app": "controlled-cloudflared-connector"
-        "strrl.dev/cloudflare-tunnel-ingress-controller": "controlled-cloudflared-connector"
+  clusterIP: None
+  selector:
+    app: controlled-cloudflared-connector
+    strrl.dev/cloudflare-tunnel-ingress-controller: controlled-cloudflared-connector
diff --git a/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-servicemonitor.yaml b/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-servicemonitor.yaml
new file mode 100644
index 0000000..c34ff00
--- /dev/null
+++ b/helm/cloudflare-tunnel-ingress-controller/templates/controlled-cloudflared-servicemonitor.yaml
@@ -0,0 +1,38 @@
+{{- if .Values.cloudflaredServiceMonitor.create }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: {{ include "cloudflare-tunnel-ingress-controller.fullname" . }}-controlled-cloudflared
+  labels:
+    {{- include "cloudflare-tunnel-ingress-controller.labels" . | nindent 4 }}
+spec:
+  {{- if .Values.cloudflaredServiceMonitor.jobLabel }}
+  jobLabel: {{ .Values.cloudflaredServiceMonitor.jobLabel }}
+  {{- end }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/component: controlled-cloudflared
+      {{- include "cloudflare-tunnel-ingress-controller.selectorLabels" . | nindent 6 }}
+  endpoints:
+    - port: metrics
+      path: /metrics
+      scheme: {{ .Values.cloudflaredServiceMonitor.scheme }}
+      {{- if .Values.cloudflaredServiceMonitor.interval }}
+      interval: {{ .Values.cloudflaredServiceMonitor.interval }}
+      {{- end }}
+      {{- if .Values.cloudflaredServiceMonitor.scrapeTimeout }}
+      scrapeTimeout: {{ .Values.cloudflaredServiceMonitor.scrapeTimeout }}
+      {{- end }}
+      {{- if .Values.cloudflaredServiceMonitor.honorLabels }}
+      honorLabels: {{ .Values.cloudflaredServiceMonitor.honorLabels }}
+      {{- end }}
+      {{- if .Values.cloudflaredServiceMonitor.metricRelabelings }}
+      metricRelabelings: {{ .Values.cloudflaredServiceMonitor.metricRelabelings }}
+      {{- end }}
+      {{- if .Values.cloudflaredServiceMonitor.relabelings }}
+      relabelings: {{ .Values.cloudflaredServiceMonitor.relabelings }}
+      {{- end }}
+  namespaceSelector:
+    matchNames:
+      - {{ .Release.Namespace }}
+{{- end }}
diff --git a/helm/cloudflare-tunnel-ingress-controller/values.yaml b/helm/cloudflare-tunnel-ingress-controller/values.yaml
index 934ce6d..6ec6527 100644
--- a/helm/cloudflare-tunnel-ingress-controller/values.yaml
+++ b/helm/cloudflare-tunnel-ingress-controller/values.yaml
@@ -80,3 +80,14 @@ cloudflared:
     tag: latest
   replicaCount: 1
   protocol: quic
+
+cloudflaredServiceMonitor:
+  create: false
+  jobLabel: ""
+  interval: ""
+  scrapeTimeout: ""
+  honorLabels: false
+  metricRelabelings: []
+  relabelings: []
+  labels: {}
+  scheme: http