Skip to content

Implement AWS Secrets Manager Resolver

Description

Create a resolver for AWS Secrets Manager that transforms CI configuration into a format that GitLab Runner can understand and use to fetch secrets.

Goals

  • Create a new resolver class for AWS Secrets Manager
  • Implement logic to transform CI configuration into Runner format
  • Ensure proper error handling

Implementation Plan

Step 1: Create Resolver Class

Create a new resolver class in the appropriate directory:

# lib/gitlab/ci/secrets/resolvers/aws_secret_manager.rb

module Gitlab
  module Ci
    module Secrets
      module Resolvers
        class AwsSecretManager
          def initialize(secret_entry)
            @secret_entry = secret_entry
          end
          
          def resolve(id_token_reference)
            aws_config = @secret_entry[:aws_secret_manager]
            
            {
              provider: 'aws-secret-manager',
              name: aws_config[:name],
              region: aws_config[:region],
              version_id: aws_config[:version_id],
              version_stage: aws_config[:version_stage],
              token: id_token_reference
            }.compact
          end
        end
      end
    end
  end
end

Step 2: Register the Resolver

Register the new resolver in the resolver factory or registry:

# lib/gitlab/ci/secrets/resolvers.rb (or similar)

module Gitlab
  module Ci
    module Secrets
      module Resolvers
        def self.for(secret_entry)
          return AwsSecretManager.new(secret_entry) if secret_entry[:aws_secret_manager].present?
          # Other resolvers...
        end
      end
    end
  end
end

Step 3: Update Main Secrets Resolver

If necessary, update the main secrets resolver to handle AWS Secrets Manager:

# In the main resolver class

def resolve_secrets
  # Existing code...
  
  if secret.has_key?(:aws_secret_manager)
    resolver = Gitlab::Ci::Secrets::Resolvers::AwsSecretManager.new(secret)
    resolved_secret = resolver.resolve(id_token_reference)
    # Process resolved_secret...
  end
  
  # More existing code...
end

Testing Plan

Step 1: Write Unit Tests for Resolver

# spec/lib/gitlab/ci/secrets/resolvers/aws_secret_manager_spec.rb

RSpec.describe Gitlab::Ci::Secrets::Resolvers::AwsSecretManager do
  describe '#resolve' do
    let(:secret_entry) do
      {
        aws_secret_manager: {
          name: 'db-password',
          region: 'us-east-1',
          version_id: 'abc123',
          version_stage: 'AWSCURRENT'
        }
      }
    end
    
    let(:resolver) { described_class.new(secret_entry) }
    let(:id_token_reference) { '$MY_ID_TOKEN' }
    
    it 'returns properly formatted AWS secret manager configuration' do
      resolved = resolver.resolve(id_token_reference)
      
      expect(resolved).to eq({
        provider: 'aws-secret-manager',
        name: 'db-password',
        region: 'us-east-1',
        version_id: 'abc123',
        version_stage: 'AWSCURRENT',
        token: '$MY_ID_TOKEN'
      })
    end
    
    context 'with minimal configuration' do
      let(:secret_entry) do
        {
          aws_secret_manager: {
            name: 'db-password',
            region: 'us-east-1'
          }
        }
      end
      
      it 'omits optional fields' do
        resolved = resolver.resolve(id_token_reference)
        
        expect(resolved).to eq({
          provider: 'aws-secret-manager',
          name: 'db-password',
          region: 'us-east-1',
          token: '$MY_ID_TOKEN'
        })
      end
    end
  end
end

Step 2: Test Integration with Secrets System

# spec/lib/gitlab/ci/secrets/resolvers_spec.rb

RSpec.describe Gitlab::Ci::Secrets::Resolvers do
  describe '.for' do
    context 'with aws_secret_manager' do
      let(:secret_entry) do
        {
          aws_secret_manager: {
            name: 'db-password',
            region: 'us-east-1'
          }
        }
      end
      
      it 'returns an AWS Secret Manager resolver' do
        resolver = described_class.for(secret_entry)
        expect(resolver).to be_a(Gitlab::Ci::Secrets::Resolvers::AwsSecretManager)
      end
    end
  end
end

Acceptance Criteria

  • AWS Secrets Manager resolver is properly implemented
  • Resolver correctly transforms CI configuration into Runner format
  • All required and optional fields are properly handled
  • Integration with the existing secrets system works correctly
  • All tests pass

Dependencies

Edited by Aditya Tiwari