diff --git a/app/controllers/projects/google_cloud_controller.rb b/app/controllers/projects/google_cloud_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d185457aeb386a61a6e6d172965de1ab0214d316
--- /dev/null
+++ b/app/controllers/projects/google_cloud_controller.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class Projects::GoogleCloudController < Projects::ApplicationController
+  before_action :authorize_can_manage_google_cloud_deployments!
+
+  feature_category :release_orchestration
+
+  def index
+  end
+
+  private
+
+  def authorize_can_manage_google_cloud_deployments!
+    access_denied! unless can?(current_user, :manage_project_google_cloud, project)
+  end
+end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index c9f71e247ae5ca0b1e684a46fc158ac4f0d82500..59aa47beff9c4916d28c8bcd5507ecd4766dacee 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -438,6 +438,7 @@ class ProjectPolicy < BasePolicy
     enable :destroy_freeze_period
     enable :admin_feature_flags_client
     enable :update_runners_registration_token
+    enable :manage_project_google_cloud
   end
 
   rule { public_project & metrics_dashboard_allowed }.policy do
diff --git a/app/views/projects/google_cloud/index.html.haml b/app/views/projects/google_cloud/index.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..4fc66e17810a0235c492ad499129f01aa6f5ad76
--- /dev/null
+++ b/app/views/projects/google_cloud/index.html.haml
@@ -0,0 +1,83 @@
+- breadcrumb_title _('Google Cloud')
+- page_title _('Google Cloud')
+
+- @content_class = "limit-container-width" unless fluid_layout
+
+#js-google-cloud
+
+  %h1.gl-font-size-h1 Google Cloud
+
+  %section#js-section-google-cloud-service-accounts
+
+    %h2.gl-font-size-h2 Service Accounts
+
+    %p= _('Service Accounts keys are required to authorize GitLab to deploy your Google Cloud project.')
+
+    %table.table.b-table.gl-table
+
+      %thead
+        %tr
+          %th Environment
+          %th GCP Project ID
+          %th Service Account Key
+
+      %tbody
+
+        %tr
+          %td *
+          %td serving-salutes-453
+          %td .....
+
+        %tr
+          %td production
+          %td crimson-corey-234
+          %td .....
+
+        %tr
+          %td review/*
+          %td roving-river-379
+          %td .....
+
+    %a.gl-button.btn.btn-primary= _('Add new service account')
+
+  %br
+
+  %section#js-section-google-cloud-deployments
+
+    .row.row-fluid
+
+      .col-lg-4
+        %h2.gl-font-size-h2 Deployments
+        %p= _('Google Cloud offers several deployment targets. Select the one most suitable for your project.')
+        %p
+          = _('Deployments to Google Kubernetes Engine can be ')
+          %a{ href: '#' }= _('managed')
+          = _('in Infrastructure :: Kubernetes clusters')
+
+      .col-lg-8
+
+        %br
+
+        .gl-card.gl-mb-6
+          .gl-card-body
+            .gl-display-flex.gl-align-items-baseline
+              %strong.gl-font-lg App Engine
+              .gl-ml-auto.gl-text-gray-500 Disabled
+            %p= _('App Engine description and apps that are suitable for this deployment target')
+            %button.gl-button.btn.btn-default= _('Configure via Merge Request')
+
+        .gl-card.gl-mb-6
+          .gl-card-body
+            .gl-display-flex.gl-align-items-baseline
+              %strong.gl-font-lg Cloud Functions
+              .gl-ml-auto.gl-text-gray-500 Disabled
+            %p= _('Cloud Functions description and apps that are suitable for this deployment target')
+            %button.gl-button.btn.btn-default= _('Configure via Merge Request')
+
+        .gl-card.gl-mb-6
+          .gl-card-body
+            .gl-display-flex.gl-align-items-baseline
+              %strong.gl-font-lg Cloud Run
+              .gl-ml-auto.gl-text-gray-500 Disabled
+            %p= _('Cloud Run description and apps that are suitable for this deployment target')
+            %button.gl-button.btn.btn-default= _('Configure via Merge Request')
diff --git a/config/feature_flags/development/incubation_5mp_google_cloud.yml b/config/feature_flags/development/incubation_5mp_google_cloud.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b687a656b40632e6fb9217fe6c3740a383e51e30
--- /dev/null
+++ b/config/feature_flags/development/incubation_5mp_google_cloud.yml
@@ -0,0 +1,8 @@
+---
+name: incubation_5mp_google_cloud
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70715
+rollout_issue_url:
+milestone: '14.3'
+type: development
+group: group::incubation
+default_enabled: false
diff --git a/config/routes/project.rb b/config/routes/project.rb
index bfb7802b3de0051d0a2745b08d6f8fffc56fee85..b1be9ad2ada9e4d51eb40953eadba0a843aa069d 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -313,6 +313,8 @@
 
         resources :terraform, only: [:index]
 
+        resources :google_cloud, only: [:index]
+
         resources :environments, except: [:destroy] do
           member do
             post :stop
diff --git a/ee/spec/features/projects/navbar_spec.rb b/ee/spec/features/projects/navbar_spec.rb
index 3b2119a7f40178fbe52b68fb550562b73352f2f3..ad37f8be60bf379e660d0f624e48b90e6dea0880 100644
--- a/ee/spec/features/projects/navbar_spec.rb
+++ b/ee/spec/features/projects/navbar_spec.rb
@@ -16,6 +16,7 @@
 
     insert_package_nav(_('Infrastructure'))
     insert_infrastructure_registry_nav
+    insert_infrastructure_google_cloud_nav
   end
 
   context 'when issue analytics is available' do
diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb
index e26bb2237e6fa121e1942fb51ba51ecaed29c2d9..92e9cbb70406958d17da8f5c3a0c700e5ab10a40 100644
--- a/lib/sidebars/projects/menus/infrastructure_menu.rb
+++ b/lib/sidebars/projects/menus/infrastructure_menu.rb
@@ -11,6 +11,7 @@ def configure_menu_items
           add_item(kubernetes_menu_item)
           add_item(serverless_menu_item)
           add_item(terraform_menu_item)
+          add_item(google_cloud_menu_item)
 
           true
         end
@@ -87,6 +88,22 @@ def terraform_menu_item
             item_id: :terraform
           )
         end
+
+        def google_cloud_menu_item
+          feature_is_enabled = Feature.enabled?(:incubation_5mp_google_cloud)
+          user_has_permissions = can?(context.current_user, :manage_project_google_cloud, context.project)
+
+          unless feature_is_enabled && user_has_permissions
+            return ::Sidebars::NilMenuItem.new(item_id: :incubation_5mp_google_cloud)
+          end
+
+          ::Sidebars::MenuItem.new(
+            title: _('Google Cloud'),
+            link: project_google_cloud_index_path(context.project),
+            active_routes: {},
+            item_id: :google_cloud
+          )
+        end
       end
     end
   end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 6d757abbad94daf75466a63f1a3232cb384ab6e3..61406b0c5c7600c46b53e086881b82cd2e0b2c41 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2045,6 +2045,9 @@ msgstr ""
 msgid "Add new directory"
 msgstr ""
 
+msgid "Add new service account"
+msgstr ""
+
 msgid "Add or remove previously merged commits"
 msgstr ""
 
@@ -3959,6 +3962,9 @@ msgstr ""
 msgid "Any namespace"
 msgstr ""
 
+msgid "App Engine description and apps that are suitable for this deployment target"
+msgstr ""
+
 msgid "App ID"
 msgstr ""
 
@@ -7174,6 +7180,12 @@ msgstr ""
 msgid "Closes this %{quick_action_target}."
 msgstr ""
 
+msgid "Cloud Functions description and apps that are suitable for this deployment target"
+msgstr ""
+
+msgid "Cloud Run description and apps that are suitable for this deployment target"
+msgstr ""
+
 msgid "Cloud licenses can not be removed."
 msgstr ""
 
@@ -8613,6 +8625,9 @@ msgstr ""
 msgid "Configure the way a user creates a new account."
 msgstr ""
 
+msgid "Configure via Merge Request"
+msgstr ""
+
 msgid "Configure which lists are shown for anyone who visits this board"
 msgstr ""
 
@@ -11385,6 +11400,9 @@ msgstr ""
 msgid "Deployments"
 msgstr ""
 
+msgid "Deployments to Google Kubernetes Engine can be "
+msgstr ""
+
 msgid "Deployments|%{deployments} environment impacted."
 msgid_plural "Deployments|%{deployments} environments impacted."
 msgstr[0] ""
@@ -15832,6 +15850,12 @@ msgstr ""
 msgid "Goal of the changes and what reviewers should be aware of"
 msgstr ""
 
+msgid "Google Cloud"
+msgstr ""
+
+msgid "Google Cloud offers several deployment targets. Select the one most suitable for your project."
+msgstr ""
+
 msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
 msgstr ""
 
@@ -30832,6 +30856,9 @@ msgstr ""
 msgid "Service"
 msgstr ""
 
+msgid "Service Accounts keys are required to authorize GitLab to deploy your Google Cloud project."
+msgstr ""
+
 msgid "Service Desk"
 msgstr ""
 
@@ -40159,6 +40186,9 @@ msgstr ""
 msgid "in"
 msgstr ""
 
+msgid "in Infrastructure :: Kubernetes clusters"
+msgstr ""
+
 msgid "in all GitLab"
 msgstr ""
 
@@ -40314,6 +40344,9 @@ msgstr ""
 msgid "log in"
 msgstr ""
 
+msgid "managed"
+msgstr ""
+
 msgid "manual"
 msgstr ""
 
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 876bc82d16c7238db3240f718c6f850136682ee8..f61eaccf5b96bf0736ffa822a45ca26834263271 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -18,6 +18,7 @@
     stub_config(registry: { enabled: false })
     insert_package_nav(_('Infrastructure'))
     insert_infrastructure_registry_nav
+    insert_infrastructure_google_cloud_nav
   end
 
   it_behaves_like 'verified navigation bar' do
diff --git a/spec/requests/projects/google_cloud_controller_spec.rb b/spec/requests/projects/google_cloud_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3b43f0d1dfbd3a395e1cd47145e10073f741d333
--- /dev/null
+++ b/spec/requests/projects/google_cloud_controller_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::GoogleCloudController do
+  let_it_be(:project) { create(:project, :public) }
+
+  describe 'GET index' do
+    let_it_be(:url) { "#{project_google_cloud_index_path(project)}" }
+
+    let(:subject) { get url }
+
+    context 'when user is authorized' do
+      let(:user) { project.creator }
+
+      before do
+        sign_in(user)
+        subject
+      end
+
+      it 'renders content' do
+        expect(response).to be_successful
+      end
+    end
+
+    context 'when user is unauthorized' do
+      let(:user) { create(:user) }
+
+      before do
+        project.add_guest(user)
+        sign_in(user)
+        subject
+      end
+
+      it 'shows 404' do
+        expect(response).to have_gitlab_http_status(:not_found)
+      end
+    end
+
+    context 'when no user is present' do
+      before do
+        subject
+      end
+
+      it 'shows 404' do
+        expect(response).to have_gitlab_http_status(:not_found)
+      end
+    end
+  end
+end
diff --git a/spec/support/helpers/navbar_structure_helper.rb b/spec/support/helpers/navbar_structure_helper.rb
index 826108a63a5377bb99b1ea3e9c7120f7add3eb50..96e7942727887ab0038fbf1b1df8447dc639e6f3 100644
--- a/spec/support/helpers/navbar_structure_helper.rb
+++ b/spec/support/helpers/navbar_structure_helper.rb
@@ -52,4 +52,12 @@ def insert_infrastructure_registry_nav
       new_sub_nav_item_name: _('Infrastructure Registry')
     )
   end
+
+  def insert_infrastructure_google_cloud_nav
+    insert_after_sub_nav_item(
+      _('Terraform'),
+      within: _('Infrastructure'),
+      new_sub_nav_item_name: _('Google Cloud')
+    )
+  end
 end
diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
index adfe1cee6d6ad29d98830beb77ee4af2cbb41e04..20c5d9992be49f7233d2234f2c243c05440d8b1a 100644
--- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb
@@ -580,6 +580,23 @@
         end
       end
     end
+
+    describe 'Google Cloud' do
+      it 'has a link to the google cloud page' do
+        render
+        expect(rendered).to have_link('Google Cloud', href: project_google_cloud_index_path(project))
+      end
+
+      describe 'when the user does not have access' do
+        let(:user) { nil }
+
+        it 'does not have a link to the google cloud page' do
+          render
+
+          expect(rendered).not_to have_link('Google Cloud')
+        end
+      end
+    end
   end
 
   describe 'Packages and Registries' do