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