diff --git a/changelogs/unreleased/43802-ensure-foreign-keys-on-clusters-applications.yml b/changelogs/unreleased/43802-ensure-foreign-keys-on-clusters-applications.yml
new file mode 100644
index 0000000000000000000000000000000000000000..860a8becd65fc35b243808ac8d695c9a42336100
--- /dev/null
+++ b/changelogs/unreleased/43802-ensure-foreign-keys-on-clusters-applications.yml
@@ -0,0 +1,5 @@
+---
+title: Ensure foreign keys on clusters applications
+merge_request: 17488
+author:
+type: other
diff --git a/db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb b/db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8298979e96abca26c7e16a4487b27a17c1746422
--- /dev/null
+++ b/db/migrate/20180302152117_ensure_foreign_keys_on_clusters_applications.rb
@@ -0,0 +1,50 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class EnsureForeignKeysOnClustersApplications < ActiveRecord::Migration
+  include Gitlab::Database::MigrationHelpers
+
+  DOWNTIME = false
+
+  disable_ddl_transaction!
+
+  def up
+    existing = Clusters::Cluster
+      .joins(:application_ingress)
+      .where('clusters.id = clusters_applications_ingress.cluster_id')
+
+    Clusters::Applications::Ingress.where('NOT EXISTS (?)', existing).in_batches do |batch|
+      batch.delete_all
+    end
+
+    unless foreign_keys_for(:clusters_applications_ingress, :cluster_id).any?
+      add_concurrent_foreign_key :clusters_applications_ingress, :clusters,
+        column: :cluster_id,
+        on_delete: :cascade
+    end
+
+    existing = Clusters::Cluster
+      .joins(:application_prometheus)
+      .where('clusters.id = clusters_applications_prometheus.cluster_id')
+
+    Clusters::Applications::Ingress.where('NOT EXISTS (?)', existing).in_batches do |batch|
+      batch.delete_all
+    end
+
+    unless foreign_keys_for(:clusters_applications_prometheus, :cluster_id).any?
+      add_concurrent_foreign_key :clusters_applications_prometheus, :clusters,
+        column: :cluster_id,
+        on_delete: :cascade
+    end
+  end
+
+  def down
+    if foreign_keys_for(:clusters_applications_ingress, :cluster_id).any?
+      remove_foreign_key :clusters_applications_ingress, column: :cluster_id
+    end
+
+    if foreign_keys_for(:clusters_applications_prometheus, :cluster_id).any?
+      remove_foreign_key :clusters_applications_prometheus, column: :cluster_id
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index bfd4d2ef38fbcb9eac366042b2f0f211e1c27b82..75a094bbbb69034d97753b8701a0c10a16fa7dff 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -2032,6 +2032,8 @@ ActiveRecord::Schema.define(version: 20180308052825) do
   add_foreign_key "cluster_providers_gcp", "clusters", on_delete: :cascade
   add_foreign_key "clusters", "users", on_delete: :nullify
   add_foreign_key "clusters_applications_helm", "clusters", on_delete: :cascade
+  add_foreign_key "clusters_applications_ingress", "clusters", name: "fk_753a7b41c1", on_delete: :cascade
+  add_foreign_key "clusters_applications_prometheus", "clusters", name: "fk_557e773639", on_delete: :cascade
   add_foreign_key "clusters_applications_runners", "ci_runners", column: "runner_id", name: "fk_02de2ded36", on_delete: :nullify
   add_foreign_key "clusters_applications_runners", "clusters", on_delete: :cascade
   add_foreign_key "container_repositories", "projects"