From e4db99f3e8edf682d2c1df30e76a4a38747ea9ae Mon Sep 17 00:00:00 2001
From: Emily Ring <ering@gitlab.com>
Date: Thu, 22 Oct 2020 22:01:26 +0000
Subject: [PATCH] Remove default EKS Region Dropdown in cluster form

Replace dropdown with input field for EKS Regions
Update authorize_role_service to authenticate with customer region
---
 .../eks_cluster_configuration_form.vue        |  61 +++-------
 .../components/service_credentials_form.vue   |  40 ++++++-
 .../create_cluster/eks_cluster/constants.js   |   2 +
 .../services/aws_services_facade.js           |  21 +---
 .../eks_cluster/store/actions.js              |  16 ++-
 .../create_cluster/eks_cluster/store/index.js |   5 -
 .../clusters/clusters_controller.rb           |   2 +-
 .../clusters/aws/authorize_role_service.rb    |   9 +-
 .../clusters/aws/fetch_credentials_service.rb |   9 +-
 .../216974-optional-input-field.yml           |   5 +
 locale/gitlab.pot                             |  30 ++---
 .../eks_cluster_configuration_form_spec.js    | 112 ++++++------------
 .../services/aws_services_facade_spec.js      |  26 +---
 .../eks_cluster/store/actions_spec.js         |  61 +++++++++-
 .../aws/authorize_role_service_spec.rb        |   8 +-
 .../aws/fetch_credentials_service_spec.rb     |   4 +-
 16 files changed, 195 insertions(+), 216 deletions(-)
 create mode 100644 changelogs/unreleased/216974-optional-input-field.yml

diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue
index d403f370f9d57..2858561e03334 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue
+++ b/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue
@@ -1,15 +1,12 @@
 <script>
 import { createNamespacedHelpers, mapState, mapActions, mapGetters } from 'vuex';
-import { GlFormInput, GlFormCheckbox, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
+import { GlFormGroup, GlFormInput, GlFormCheckbox, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
 import { s__ } from '~/locale';
 import ClusterFormDropdown from '~/create_cluster/components/cluster_form_dropdown.vue';
 import { KUBERNETES_VERSIONS } from '../constants';
 import LoadingButton from '~/vue_shared/components/loading_button.vue';
 
 const { mapState: mapRolesState, mapActions: mapRolesActions } = createNamespacedHelpers('roles');
-const { mapState: mapRegionsState, mapActions: mapRegionsActions } = createNamespacedHelpers(
-  'regions',
-);
 const { mapState: mapKeyPairsState, mapActions: mapKeyPairsActions } = createNamespacedHelpers(
   'keyPairs',
 );
@@ -27,6 +24,7 @@ export default {
   components: {
     ClusterFormDropdown,
     GlFormCheckbox,
+    GlFormGroup,
     GlFormInput,
     GlIcon,
     GlLink,
@@ -60,11 +58,10 @@ export default {
     ),
     roleDropdownHelpPath:
       'https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html#create-service-role',
-    regionsDropdownHelpText: s__(
-      'ClusterIntegration|Learn more about %{linkStart}Regions%{linkEnd}.',
+    regionInputLabel: s__('ClusterIntegration|Cluster Region'),
+    regionHelpText: s__(
+      'ClusterIntegration|The region the new cluster will be created in. You must reauthenticate to change regions.',
     ),
-    regionsDropdownHelpPath:
-      'https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/',
     keyPairDropdownHelpText: s__(
       'ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{linkStart}Amazon Web Services%{linkEnd}.',
     ),
@@ -117,11 +114,6 @@ export default {
       isLoadingRoles: 'isLoadingItems',
       loadingRolesError: 'loadingItemsError',
     }),
-    ...mapRegionsState({
-      regions: 'items',
-      isLoadingRegions: 'isLoadingItems',
-      loadingRegionsError: 'loadingItemsError',
-    }),
     ...mapKeyPairsState({
       keyPairs: 'items',
       isLoadingKeyPairs: 'isLoadingItems',
@@ -195,8 +187,8 @@ export default {
     },
   },
   mounted() {
-    this.fetchRegions();
     this.fetchRoles();
+    this.setRegionAndFetchVpcsAndKeyPairs();
   },
   methods: {
     ...mapActions([
@@ -215,20 +207,18 @@ export default {
       'setGitlabManagedCluster',
       'setNamespacePerEnvironment',
     ]),
-    ...mapRegionsActions({ fetchRegions: 'fetchItems' }),
     ...mapVpcActions({ fetchVpcs: 'fetchItems' }),
     ...mapSubnetActions({ fetchSubnets: 'fetchItems' }),
     ...mapRolesActions({ fetchRoles: 'fetchItems' }),
     ...mapKeyPairsActions({ fetchKeyPairs: 'fetchItems' }),
     ...mapSecurityGroupsActions({ fetchSecurityGroups: 'fetchItems' }),
-    setRegionAndFetchVpcsAndKeyPairs(region) {
-      this.setRegion({ region });
+    setRegionAndFetchVpcsAndKeyPairs() {
       this.setVpc({ vpc: null });
       this.setKeyPair({ keyPair: null });
       this.setSubnet({ subnet: [] });
       this.setSecurityGroup({ securityGroup: null });
-      this.fetchVpcs({ region });
-      this.fetchKeyPairs({ region });
+      this.fetchVpcs({ region: this.selectedRegion });
+      this.fetchKeyPairs({ region: this.selectedRegion });
     },
     setVpcAndFetchSubnets(vpc) {
       this.setVpc({ vpc });
@@ -314,33 +304,12 @@ export default {
         </gl-sprintf>
       </p>
     </div>
-    <div class="form-group">
-      <label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Region') }}</label>
-      <cluster-form-dropdown
-        field-id="eks-region"
-        field-name="eks-region"
-        :value="selectedRegion"
-        :items="regions"
-        :loading="isLoadingRegions"
-        :loading-text="s__('ClusterIntegration|Loading Regions')"
-        :placeholder="s__('ClusterIntergation|Select a region')"
-        :search-field-placeholder="s__('ClusterIntegration|Search regions')"
-        :empty-text="s__('ClusterIntegration|No region found')"
-        :has-errors="Boolean(loadingRegionsError)"
-        :error-message="s__('ClusterIntegration|Could not load regions from your AWS account')"
-        @input="setRegionAndFetchVpcsAndKeyPairs($event)"
-      />
-      <p class="form-text text-muted">
-        <gl-sprintf :message="$options.i18n.regionsDropdownHelpText">
-          <template #link="{ content }">
-            <gl-link :href="$options.i18n.regionsDropdownHelpPath" target="_blank">
-              {{ content }}
-              <gl-icon name="external-link" class="gl-vertical-align-middle" />
-            </gl-link>
-          </template>
-        </gl-sprintf>
-      </p>
-    </div>
+    <gl-form-group
+      :label="$options.i18n.regionInputLabel"
+      :description="$options.i18n.regionHelpText"
+    >
+      <gl-form-input id="eks-region" :value="selectedRegion" type="text" readonly />
+    </gl-form-group>
     <div class="form-group">
       <label class="label-bold" for="eks-key-pair">{{
         s__('ClusterIntegration|Key pair name')
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue
index 5c13cbb27759b..a3f76241bf2bf 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue
+++ b/app/assets/javascripts/create_cluster/eks_cluster/components/service_credentials_form.vue
@@ -1,15 +1,20 @@
 <script>
 /* eslint-disable vue/no-v-html */
-import { GlFormInput, GlButton } from '@gitlab/ui';
+import { GlButton, GlFormGroup, GlFormInput, GlIcon, GlLink, GlSprintf } from '@gitlab/ui';
 import { escape } from 'lodash';
 import { mapState, mapActions } from 'vuex';
+import { DEFAULT_REGION } from '../constants';
 import { sprintf, s__, __ } from '~/locale';
 import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
 
 export default {
   components: {
-    GlFormInput,
     GlButton,
+    GlFormGroup,
+    GlFormInput,
+    GlIcon,
+    GlLink,
+    GlSprintf,
     ClipboardButton,
   },
   props: {
@@ -26,9 +31,18 @@ export default {
       required: true,
     },
   },
+  i18n: {
+    regionInputLabel: s__('ClusterIntegration|Cluster Region'),
+    regionHelpPath: 'https://aws.amazon.com/about-aws/global-infrastructure/regions_az/',
+    regionHelpText: s__(
+      'ClusterIntegration|Select the region you want to create the new cluster in. Make sure you have access to this region for your role to be able to authenticate. If no region is selected, we will use %{codeStart}DEFAULT_REGION%{codeEnd}. Learn more about %{linkStart}Regions%{linkEnd}.',
+    ),
+    regionHelpTextDefaultRegion: DEFAULT_REGION,
+  },
   data() {
     return {
       roleArn: this.$store.state.roleArn,
+      selectedRegion: this.$store.state.selectedRegion,
     };
   },
   computed: {
@@ -130,13 +144,33 @@ export default {
       <gl-form-input id="eks-provision-role-arn" v-model="roleArn" />
       <p class="form-text text-muted" v-html="provisionRoleArnHelpText"></p>
     </div>
+
+    <gl-form-group :label="$options.i18n.regionInputLabel">
+      <gl-form-input id="eks-region" v-model="selectedRegion" type="text" />
+
+      <template #description>
+        <gl-sprintf :message="$options.i18n.regionHelpText">
+          <template #code>
+            <code>{{ $options.i18n.regionHelpTextDefaultRegion }}</code>
+          </template>
+
+          <template #link="{ content }">
+            <gl-link :href="$options.i18n.regionHelpPath" target="_blank">
+              {{ content }}
+              <gl-icon name="external-link" />
+            </gl-link>
+          </template>
+        </gl-sprintf>
+      </template>
+    </gl-form-group>
+
     <gl-button
       variant="success"
       category="primary"
       type="submit"
       :disabled="submitButtonDisabled"
       :loading="isCreatingRole"
-      @click.prevent="createRole({ roleArn, externalId })"
+      @click.prevent="createRole({ roleArn, selectedRegion, externalId })"
     >
       {{ submitButtonLabel }}
     </gl-button>
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/constants.js b/app/assets/javascripts/create_cluster/eks_cluster/constants.js
index 471d6e1f0aa6a..0f0db2090c102 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/constants.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/constants.js
@@ -1,3 +1,5 @@
+export const DEFAULT_REGION = 'us-east-2';
+
 export const KUBERNETES_VERSIONS = [
   { name: '1.14', value: '1.14' },
   { name: '1.15', value: '1.15' },
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js b/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js
index 601ff6f9adca7..58568b5dedbcd 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/services/aws_services_facade.js
@@ -8,13 +8,8 @@ const lookupVpcName = ({ Tags: tags, VpcId: id }) => {
   return nameTag ? nameTag.Value : id;
 };
 
-export const DEFAULT_REGION = 'us-east-2';
-
 export const setAWSConfig = ({ awsCredentials }) => {
-  AWS.config = {
-    ...awsCredentials,
-    region: DEFAULT_REGION,
-  };
+  AWS.config = awsCredentials;
 };
 
 export const fetchRoles = () => {
@@ -26,20 +21,6 @@ export const fetchRoles = () => {
     .then(({ Roles: roles }) => roles.map(({ RoleName: name, Arn: value }) => ({ name, value })));
 };
 
-export const fetchRegions = () => {
-  const ec2 = new EC2();
-
-  return ec2
-    .describeRegions()
-    .promise()
-    .then(({ Regions: regions }) =>
-      regions.map(({ RegionName: name }) => ({
-        name,
-        value: name,
-      })),
-    );
-};
-
 export const fetchKeyPairs = ({ region }) => {
   const ec2 = new EC2({ region });
 
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js b/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js
index 48c85ff627ff1..f3950a3343a8a 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js
@@ -1,4 +1,5 @@
 import * as types from './mutation_types';
+import { DEFAULT_REGION } from '../constants';
 import { setAWSConfig } from '../services/aws_services_facade';
 import axios from '~/lib/utils/axios_utils';
 import { deprecatedCreateFlash as createFlash } from '~/flash';
@@ -25,12 +26,22 @@ export const setKubernetesVersion = ({ commit }, payload) => {
 export const createRole = ({ dispatch, state: { createRolePath } }, payload) => {
   dispatch('requestCreateRole');
 
+  const region = payload.selectedRegion || DEFAULT_REGION;
+
   return axios
     .post(createRolePath, {
       role_arn: payload.roleArn,
       role_external_id: payload.externalId,
+      region,
+    })
+    .then(({ data }) => {
+      const awsData = {
+        ...convertObjectPropsToCamelCase(data),
+        region,
+      };
+
+      dispatch('createRoleSuccess', awsData);
     })
-    .then(({ data }) => dispatch('createRoleSuccess', convertObjectPropsToCamelCase(data)))
     .catch(error => dispatch('createRoleError', { error }));
 };
 
@@ -38,7 +49,8 @@ export const requestCreateRole = ({ commit }) => {
   commit(types.REQUEST_CREATE_ROLE);
 };
 
-export const createRoleSuccess = ({ commit }, awsCredentials) => {
+export const createRoleSuccess = ({ dispatch, commit }, awsCredentials) => {
+  dispatch('setRegion', { region: awsCredentials.region });
   setAWSConfig({ awsCredentials });
   commit(types.CREATE_ROLE_SUCCESS);
 };
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/index.js b/app/assets/javascripts/create_cluster/eks_cluster/store/index.js
index 8dc55506dc285..262bbb3167a5a 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/store/index.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/store/index.js
@@ -8,7 +8,6 @@ import clusterDropdownStore from '~/create_cluster/store/cluster_dropdown';
 
 import {
   fetchRoles,
-  fetchRegions,
   fetchKeyPairs,
   fetchVpcs,
   fetchSubnets,
@@ -26,10 +25,6 @@ const createStore = ({ initialState }) =>
         namespaced: true,
         ...clusterDropdownStore({ fetchFn: fetchRoles }),
       },
-      regions: {
-        namespaced: true,
-        ...clusterDropdownStore({ fetchFn: fetchRegions }),
-      },
       keyPairs: {
         namespaced: true,
         ...clusterDropdownStore({ fetchFn: fetchKeyPairs }),
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index 52719e90e04f3..9800d94964d57 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -272,7 +272,7 @@ def create_user_cluster_params
   end
 
   def aws_role_params
-    params.require(:cluster).permit(:role_arn)
+    params.require(:cluster).permit(:role_arn, :region)
   end
 
   def generate_gcp_authorize_url
diff --git a/app/services/clusters/aws/authorize_role_service.rb b/app/services/clusters/aws/authorize_role_service.rb
index 2712a4b05bbb3..1f6f350bcc89b 100644
--- a/app/services/clusters/aws/authorize_role_service.rb
+++ b/app/services/clusters/aws/authorize_role_service.rb
@@ -17,7 +17,8 @@ class AuthorizeRoleService
 
       def initialize(user, params:)
         @user = user
-        @params = params
+        @role_arn = params[:role_arn]
+        @region = params[:region]
       end
 
       def execute
@@ -33,18 +34,18 @@ def execute
 
       private
 
-      attr_reader :role, :params
+      attr_reader :role, :role_arn, :region
 
       def ensure_role_exists!
         @role = ::Aws::Role.find_by_user_id!(user.id)
       end
 
       def update_role_arn!
-        role.update!(params)
+        role.update!(role_arn: role_arn)
       end
 
       def credentials
-        Clusters::Aws::FetchCredentialsService.new(role).execute
+        Clusters::Aws::FetchCredentialsService.new(role, region: region).execute
       end
     end
   end
diff --git a/app/services/clusters/aws/fetch_credentials_service.rb b/app/services/clusters/aws/fetch_credentials_service.rb
index 33efc4cc12077..f94d8d8c66d15 100644
--- a/app/services/clusters/aws/fetch_credentials_service.rb
+++ b/app/services/clusters/aws/fetch_credentials_service.rb
@@ -7,9 +7,10 @@ class FetchCredentialsService
 
       MissingRoleError = Class.new(StandardError)
 
-      def initialize(provision_role, provider: nil)
+      def initialize(provision_role, provider: nil, region: nil)
         @provision_role = provision_role
         @provider = provider
+        @region = provider&.region || region
       end
 
       def execute
@@ -26,7 +27,7 @@ def execute
 
       private
 
-      attr_reader :provider
+      attr_reader :provider, :region
 
       def client
         ::Aws::STS::Client.new(credentials: gitlab_credentials, region: region)
@@ -44,10 +45,6 @@ def secret_access_key
         Gitlab::CurrentSettings.eks_secret_access_key
       end
 
-      def region
-        provider&.region || Clusters::Providers::Aws::DEFAULT_REGION
-      end
-
       ##
       # If we haven't created a provider record yet,
       # we restrict ourselves to read only access so
diff --git a/changelogs/unreleased/216974-optional-input-field.yml b/changelogs/unreleased/216974-optional-input-field.yml
new file mode 100644
index 0000000000000..1816b6202bf4b
--- /dev/null
+++ b/changelogs/unreleased/216974-optional-input-field.yml
@@ -0,0 +1,5 @@
+---
+title: Remove default EKS Region dropdown in cluster create form
+merge_request: 43017
+author:
+type: fixed
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index fd2ca67c3d89f..447fb5b508630 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5687,6 +5687,9 @@ msgstr ""
 msgid "ClusterIntegration|Clear the local cache of namespace and service accounts."
 msgstr ""
 
+msgid "ClusterIntegration|Cluster Region"
+msgstr ""
+
 msgid "ClusterIntegration|Cluster management project (alpha)"
 msgstr ""
 
@@ -5744,9 +5747,6 @@ msgstr ""
 msgid "ClusterIntegration|Could not load networks"
 msgstr ""
 
-msgid "ClusterIntegration|Could not load regions from your AWS account"
-msgstr ""
-
 msgid "ClusterIntegration|Could not load security groups for the selected VPC"
 msgstr ""
 
@@ -6002,9 +6002,6 @@ msgstr ""
 msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}."
 msgstr ""
 
-msgid "ClusterIntegration|Learn more about %{linkStart}Regions%{linkEnd}."
-msgstr ""
-
 msgid "ClusterIntegration|Learn more about Kubernetes"
 msgstr ""
 
@@ -6020,9 +6017,6 @@ msgstr ""
 msgid "ClusterIntegration|Loading Key Pairs"
 msgstr ""
 
-msgid "ClusterIntegration|Loading Regions"
-msgstr ""
-
 msgid "ClusterIntegration|Loading VPCs"
 msgstr ""
 
@@ -6089,9 +6083,6 @@ msgstr ""
 msgid "ClusterIntegration|No projects matched your search"
 msgstr ""
 
-msgid "ClusterIntegration|No region found"
-msgstr ""
-
 msgid "ClusterIntegration|No security group found"
 msgstr ""
 
@@ -6158,9 +6149,6 @@ msgstr ""
 msgid "ClusterIntegration|Real-time web application monitoring, logging and access control. %{linkStart}More information%{linkEnd}"
 msgstr ""
 
-msgid "ClusterIntegration|Region"
-msgstr ""
-
 msgid "ClusterIntegration|Remove Kubernetes cluster integration"
 msgstr ""
 
@@ -6227,9 +6215,6 @@ msgstr ""
 msgid "ClusterIntegration|Search projects"
 msgstr ""
 
-msgid "ClusterIntegration|Search regions"
-msgstr ""
-
 msgid "ClusterIntegration|Search security groups"
 msgstr ""
 
@@ -6290,6 +6275,9 @@ msgstr ""
 msgid "ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{linkStart}Amazon Web Services%{linkEnd}."
 msgstr ""
 
+msgid "ClusterIntegration|Select the region you want to create the new cluster in. Make sure you have access to this region for your role to be able to authenticate. If no region is selected, we will use %{codeStart}DEFAULT_REGION%{codeEnd}. Learn more about %{linkStart}Regions%{linkEnd}."
+msgstr ""
+
 msgid "ClusterIntegration|Select zone"
 msgstr ""
 
@@ -6374,6 +6362,9 @@ msgstr ""
 msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals."
 msgstr ""
 
+msgid "ClusterIntegration|The region the new cluster will be created in. You must reauthenticate to change regions."
+msgstr ""
+
 msgid "ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid."
 msgstr ""
 
@@ -6515,9 +6506,6 @@ msgstr ""
 msgid "ClusterIntergation|Select a network"
 msgstr ""
 
-msgid "ClusterIntergation|Select a region"
-msgstr ""
-
 msgid "ClusterIntergation|Select a security group"
 msgstr ""
 
diff --git a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
index 2600415fc9fd5..f9984091df0d7 100644
--- a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
@@ -16,7 +16,6 @@ describe('EksClusterConfigurationForm', () => {
   let getters;
   let state;
   let rolesState;
-  let regionsState;
   let vpcsState;
   let subnetsState;
   let keyPairsState;
@@ -24,7 +23,6 @@ describe('EksClusterConfigurationForm', () => {
   let instanceTypesState;
   let vpcsActions;
   let rolesActions;
-  let regionsActions;
   let subnetsActions;
   let keyPairsActions;
   let securityGroupsActions;
@@ -46,9 +44,6 @@ describe('EksClusterConfigurationForm', () => {
       setNodeCount: jest.fn(),
       setGitlabManagedCluster: jest.fn(),
     };
-    regionsActions = {
-      fetchItems: jest.fn(),
-    };
     keyPairsActions = {
       fetchItems: jest.fn(),
     };
@@ -72,10 +67,6 @@ describe('EksClusterConfigurationForm', () => {
       ...clusterDropdownStoreState(),
       ...config.rolesState,
     };
-    regionsState = {
-      ...clusterDropdownStoreState(),
-      ...config.regionsState,
-    };
     vpcsState = {
       ...clusterDropdownStoreState(),
       ...config.vpcsState,
@@ -109,11 +100,6 @@ describe('EksClusterConfigurationForm', () => {
           state: vpcsState,
           actions: vpcsActions,
         },
-        regions: {
-          namespaced: true,
-          state: regionsState,
-          actions: regionsActions,
-        },
         subnets: {
           namespaced: true,
           state: subnetsState,
@@ -189,7 +175,6 @@ describe('EksClusterConfigurationForm', () => {
   const findClusterNameInput = () => vm.find('[id=eks-cluster-name]');
   const findEnvironmentScopeInput = () => vm.find('[id=eks-environment-scope]');
   const findKubernetesVersionDropdown = () => vm.find('[field-id="eks-kubernetes-version"]');
-  const findRegionDropdown = () => vm.find('[field-id="eks-region"]');
   const findKeyPairDropdown = () => vm.find('[field-id="eks-key-pair"]');
   const findVpcDropdown = () => vm.find('[field-id="eks-vpc"]');
   const findSubnetDropdown = () => vm.find('[field-id="eks-subnet"]');
@@ -200,13 +185,44 @@ describe('EksClusterConfigurationForm', () => {
   const findGitlabManagedClusterCheckbox = () => vm.find(GlFormCheckbox);
 
   describe('when mounted', () => {
-    it('fetches available regions', () => {
-      expect(regionsActions.fetchItems).toHaveBeenCalled();
-    });
-
     it('fetches available roles', () => {
       expect(rolesActions.fetchItems).toHaveBeenCalled();
     });
+
+    describe('when fetching vpcs and key pairs', () => {
+      const region = 'us-west-2';
+
+      beforeEach(() => {
+        createValidStateStore({ selectedRegion: region });
+        buildWrapper();
+      });
+
+      it('fetches available vpcs', () => {
+        expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region });
+      });
+
+      it('fetches available key pairs', () => {
+        expect(keyPairsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region });
+      });
+
+      it('cleans selected vpc', () => {
+        expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc: null });
+      });
+
+      it('cleans selected key pair', () => {
+        expect(actions.setKeyPair).toHaveBeenCalledWith(expect.anything(), { keyPair: null });
+      });
+
+      it('cleans selected subnet', () => {
+        expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet: [] });
+      });
+
+      it('cleans selected security group', () => {
+        expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), {
+          securityGroup: null,
+        });
+      });
+    });
   });
 
   it('sets isLoadingRoles to RoleDropdown loading property', () => {
@@ -229,26 +245,6 @@ describe('EksClusterConfigurationForm', () => {
     });
   });
 
-  it('sets isLoadingRegions to RegionDropdown loading property', () => {
-    regionsState.isLoadingItems = true;
-
-    return Vue.nextTick().then(() => {
-      expect(findRegionDropdown().props('loading')).toBe(regionsState.isLoadingItems);
-    });
-  });
-
-  it('sets regions to RegionDropdown regions property', () => {
-    expect(findRegionDropdown().props('items')).toBe(regionsState.items);
-  });
-
-  it('sets loadingRegionsError to RegionDropdown error property', () => {
-    regionsState.loadingItemsError = new Error();
-
-    return Vue.nextTick().then(() => {
-      expect(findRegionDropdown().props('hasErrors')).toEqual(true);
-    });
-  });
-
   it('disables KeyPairDropdown when no region is selected', () => {
     expect(findKeyPairDropdown().props('disabled')).toBe(true);
   });
@@ -394,44 +390,6 @@ describe('EksClusterConfigurationForm', () => {
     });
   });
 
-  describe('when region is selected', () => {
-    const region = { name: 'us-west-2' };
-
-    beforeEach(() => {
-      findRegionDropdown().vm.$emit('input', region);
-    });
-
-    it('dispatches setRegion action', () => {
-      expect(actions.setRegion).toHaveBeenCalledWith(expect.anything(), { region });
-    });
-
-    it('fetches available vpcs', () => {
-      expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region });
-    });
-
-    it('fetches available key pairs', () => {
-      expect(keyPairsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region });
-    });
-
-    it('cleans selected vpc', () => {
-      expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc: null });
-    });
-
-    it('cleans selected key pair', () => {
-      expect(actions.setKeyPair).toHaveBeenCalledWith(expect.anything(), { keyPair: null });
-    });
-
-    it('cleans selected subnet', () => {
-      expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet: [] });
-    });
-
-    it('cleans selected security group', () => {
-      expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), {
-        securityGroup: null,
-      });
-    });
-  });
-
   it('dispatches setClusterName when cluster name input changes', () => {
     const clusterName = 'name';
 
diff --git a/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js b/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js
index 0ef09b4b87e9a..03c22c570a898 100644
--- a/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js
@@ -3,12 +3,10 @@ import EC2 from 'aws-sdk/clients/ec2';
 import {
   setAWSConfig,
   fetchRoles,
-  fetchRegions,
   fetchKeyPairs,
   fetchVpcs,
   fetchSubnets,
   fetchSecurityGroups,
-  DEFAULT_REGION,
 } from '~/create_cluster/eks_cluster/services/aws_services_facade';
 
 const mockListRolesPromise = jest.fn();
@@ -45,19 +43,17 @@ describe('awsServicesFacade', () => {
     vpc = 'vpc-2';
   });
 
-  it('setAWSConfig configures AWS SDK with provided credentials and default region', () => {
+  it('setAWSConfig configures AWS SDK with provided credentials', () => {
     const awsCredentials = {
       accessKeyId: 'access-key',
       secretAccessKey: 'secret-key',
       sessionToken: 'session-token',
+      region,
     };
 
     setAWSConfig({ awsCredentials });
 
-    expect(AWS.config).toEqual({
-      ...awsCredentials,
-      region: DEFAULT_REGION,
-    });
+    expect(AWS.config).toEqual(awsCredentials);
   });
 
   describe('when fetchRoles succeeds', () => {
@@ -79,22 +75,6 @@ describe('awsServicesFacade', () => {
     });
   });
 
-  describe('when fetchRegions succeeds', () => {
-    let regions;
-    let regionsOutput;
-
-    beforeEach(() => {
-      regions = [{ RegionName: 'east-1' }, { RegionName: 'west-2' }];
-      regionsOutput = regions.map(({ RegionName: name }) => ({ name, value: name }));
-
-      mockDescribeRegionsPromise.mockResolvedValueOnce({ Regions: regions });
-    });
-
-    it('return list of roles where each item has a name and value', () => {
-      return expect(fetchRegions()).resolves.toEqual(regionsOutput);
-    });
-  });
-
   describe('when fetchKeyPairs succeeds', () => {
     let keyPairs;
     let keyPairsOutput;
diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
index f929216689a4f..f12f300872ace 100644
--- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
@@ -23,6 +23,7 @@ import {
   REQUEST_CREATE_CLUSTER,
   CREATE_CLUSTER_ERROR,
 } from '~/create_cluster/eks_cluster/store/mutation_types';
+import { DEFAULT_REGION } from '~/create_cluster/eks_cluster/constants';
 import axios from '~/lib/utils/axios_utils';
 import { deprecatedCreateFlash as createFlash } from '~/flash';
 
@@ -109,12 +110,13 @@ describe('EKS Cluster Store Actions', () => {
       secretAccessKey: 'secret-key-id',
     };
 
-    describe('when request succeeds', () => {
+    describe('when request succeeds with default region', () => {
       beforeEach(() => {
         mock
           .onPost(state.createRolePath, {
             role_arn: payload.roleArn,
             role_external_id: payload.externalId,
+            region: DEFAULT_REGION,
           })
           .reply(201, response);
       });
@@ -125,7 +127,51 @@ describe('EKS Cluster Store Actions', () => {
           payload,
           state,
           [],
-          [{ type: 'requestCreateRole' }, { type: 'createRoleSuccess', payload: response }],
+          [
+            { type: 'requestCreateRole' },
+            {
+              type: 'createRoleSuccess',
+              payload: {
+                region: DEFAULT_REGION,
+                ...response,
+              },
+            },
+          ],
+        ));
+    });
+
+    describe('when request succeeds with custom region', () => {
+      const customRegion = 'custom-region';
+
+      beforeEach(() => {
+        mock
+          .onPost(state.createRolePath, {
+            role_arn: payload.roleArn,
+            role_external_id: payload.externalId,
+            region: customRegion,
+          })
+          .reply(201, response);
+      });
+
+      it('dispatches createRoleSuccess action', () =>
+        testAction(
+          actions.createRole,
+          {
+            selectedRegion: customRegion,
+            ...payload,
+          },
+          state,
+          [],
+          [
+            { type: 'requestCreateRole' },
+            {
+              type: 'createRoleSuccess',
+              payload: {
+                region: customRegion,
+                ...response,
+              },
+            },
+          ],
         ));
     });
 
@@ -138,6 +184,7 @@ describe('EKS Cluster Store Actions', () => {
           .onPost(state.createRolePath, {
             role_arn: payload.roleArn,
             role_external_id: payload.externalId,
+            region: DEFAULT_REGION,
           })
           .reply(400, error);
       });
@@ -160,8 +207,14 @@ describe('EKS Cluster Store Actions', () => {
   });
 
   describe('createRoleSuccess', () => {
-    it('commits createRoleSuccess mutation', () => {
-      testAction(actions.createRoleSuccess, null, state, [{ type: CREATE_ROLE_SUCCESS }]);
+    it('sets region and commits createRoleSuccess mutation', () => {
+      testAction(
+        actions.createRoleSuccess,
+        { region },
+        state,
+        [{ type: CREATE_ROLE_SUCCESS }],
+        [{ type: 'setRegion', payload: { region } }],
+      );
     });
   });
 
diff --git a/spec/services/clusters/aws/authorize_role_service_spec.rb b/spec/services/clusters/aws/authorize_role_service_spec.rb
index 5b47cf0ecde72..0659f92c92760 100644
--- a/spec/services/clusters/aws/authorize_role_service_spec.rb
+++ b/spec/services/clusters/aws/authorize_role_service_spec.rb
@@ -11,19 +11,21 @@
   let(:credentials_service) { instance_double(Clusters::Aws::FetchCredentialsService, execute: credentials) }
 
   let(:role_arn) { 'arn:my-role' }
+  let(:region) { 'region' }
   let(:params) do
     params = ActionController::Parameters.new({
       cluster: {
-        role_arn: role_arn
+        role_arn: role_arn,
+        region: region
       }
     })
 
-    params.require(:cluster).permit(:role_arn)
+    params.require(:cluster).permit(:role_arn, :region)
   end
 
   before do
     allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
-      .with(instance_of(Aws::Role)).and_return(credentials_service)
+      .with(instance_of(Aws::Role), region: region).and_return(credentials_service)
   end
 
   context 'role exists' do
diff --git a/spec/services/clusters/aws/fetch_credentials_service_spec.rb b/spec/services/clusters/aws/fetch_credentials_service_spec.rb
index a0e63d96a5cd1..1e39f63a28227 100644
--- a/spec/services/clusters/aws/fetch_credentials_service_spec.rb
+++ b/spec/services/clusters/aws/fetch_credentials_service_spec.rb
@@ -53,10 +53,12 @@
 
       context 'provider is not specifed' do
         let(:provider) { nil }
-        let(:region) { Clusters::Providers::Aws::DEFAULT_REGION }
+        let(:region) { 'custom-region' }
         let(:session_name) { "gitlab-eks-autofill-user-#{user.id}" }
         let(:session_policy) { 'policy-document' }
 
+        subject { described_class.new(provision_role, provider: provider, region: region).execute }
+
         before do
           allow(File).to receive(:read)
             .with(Rails.root.join('vendor', 'aws', 'iam', 'eks_cluster_read_only_policy.json'))
-- 
GitLab