Commit 0a334926 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'sh-aws-sdk-use-iam-profile' into 'master'

Support instance profiles for IAM role for Amazon EKS integration

See merge request gitlab-org/gitlab!49212
parents 7721e063 e5b57ab7
......@@ -367,11 +367,11 @@ class ApplicationSetting < ApplicationRecord
validates :eks_access_key_id,
length: { in: 16..128 },
if: :eks_integration_enabled?
if: -> (setting) { setting.eks_integration_enabled? && setting.eks_access_key_id.present? }
validates :eks_secret_access_key,
presence: true,
if: :eks_integration_enabled?
if: -> (setting) { setting.eks_integration_enabled? && setting.eks_access_key_id.present? }
validates_with X509CertificateCredentialsValidator,
certificate: :external_auth_client_cert,
......
......@@ -30,10 +30,17 @@ module Clusters
attr_reader :provider, :region
def client
::Aws::STS::Client.new(credentials: gitlab_credentials, region: region)
::Aws::STS::Client.new(**client_args)
end
def client_args
{ region: region, credentials: gitlab_credentials }.compact
end
def gitlab_credentials
# These are not needed for IAM instance profiles
return unless access_key_id.present? && secret_access_key.present?
::Aws::Credentials.new(access_key_id, secret_access_key)
end
......
......@@ -24,8 +24,13 @@
.form-group
= f.label :eks_access_key_id, 'Access key ID', class: 'label-bold'
= f.text_field :eks_access_key_id, class: 'form-control'
.form-text.text-muted
= _('AWS Access Key. Only required if not using role instance credentials')
.form-group
= f.label :eks_secret_access_key, 'Secret access key', class: 'label-bold'
= f.password_field :eks_secret_access_key, autocomplete: 'off', class: 'form-control'
.form-text.text-muted
= _('AWS Secret Access Key. Only required if not using role instance credentials')
= f.submit 'Save changes', class: "gl-button btn btn-success"
---
title: Support instance profiles for IAM role for Amazon EKS integration
merge_request: 49212
author:
type: added
......@@ -259,7 +259,18 @@ RSpec.describe ApplicationSetting do
it { is_expected.to allow_value('access-key-id-12').for(:eks_access_key_id) }
it { is_expected.not_to allow_value('a' * 129).for(:eks_access_key_id) }
it { is_expected.not_to allow_value('short-key').for(:eks_access_key_id) }
it { is_expected.not_to allow_value(nil).for(:eks_access_key_id) }
it { is_expected.to allow_value(nil).for(:eks_access_key_id) }
it { is_expected.to allow_value('secret-access-key').for(:eks_secret_access_key) }
it { is_expected.to allow_value(nil).for(:eks_secret_access_key) }
end
context 'access key is specified' do
let(:eks_enabled) { true }
before do
setting.eks_access_key_id = '123456789012'
end
it { is_expected.to allow_value('secret-access-key').for(:eks_secret_access_key) }
it { is_expected.not_to allow_value(nil).for(:eks_secret_access_key) }
......
......@@ -81,5 +81,59 @@ RSpec.describe Clusters::Aws::FetchCredentialsService do
expect { subject }.to raise_error(described_class::MissingRoleError, 'AWS provisioning role not configured')
end
end
context 'with an instance profile attached to an IAM role' do
let(:sts_client) { Aws::STS::Client.new(region: region, stub_responses: true) }
let(:provision_role) { create(:aws_role, user: user, region: 'custom-region') }
before do
stub_application_setting(eks_access_key_id: nil)
stub_application_setting(eks_secret_access_key: nil)
expect(Aws::STS::Client).to receive(:new)
.with(region: region)
.and_return(sts_client)
expect(Aws::AssumeRoleCredentials).to receive(:new)
.with(
client: sts_client,
role_arn: provision_role.role_arn,
role_session_name: session_name,
external_id: provision_role.role_external_id,
policy: session_policy
).and_call_original
end
context 'provider is specified' do
let(:region) { provider.region }
let(:session_name) { "gitlab-eks-cluster-#{provider.cluster_id}-user-#{user.id}" }
let(:session_policy) { nil }
it 'returns credentials', :aggregate_failures do
expect(subject.access_key_id).to be_present
expect(subject.secret_access_key).to be_present
expect(subject.session_token).to be_present
end
end
context 'provider is not specifed' do
let(:provider) { nil }
let(:region) { provision_role.region }
let(:session_name) { "gitlab-eks-autofill-user-#{user.id}" }
let(:session_policy) { 'policy-document' }
before do
stub_file_read(Rails.root.join('vendor', 'aws', 'iam', 'eks_cluster_read_only_policy.json'), content: session_policy)
end
subject { described_class.new(provision_role, provider: provider).execute }
it 'returns credentials', :aggregate_failures do
expect(subject.access_key_id).to be_present
expect(subject.secret_access_key).to be_present
expect(subject.session_token).to be_present
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment