require 'aws-sdk-ssm' require 'timeout' module Docker module Pipeline class ExcessiveThrottlingError < StandardError; end class SsmParameters CLIENT = Aws::SSM::Client.new def self.at(path) new(path).to_h end def to_h env end private attr_reader :path attr_reader :env def initialize(path) @path = path @env = {} @pages = 0 next_token = nil Timeout::timeout(60) do loop do next_token = read_page next_page(next_token) break unless next_token end end end def read_page(page) page.parameters.each do |parameter| key = parameter.name.split('/').last value = parameter.value env[key] = value end page.next_token end def next_page(next_token) @pages += 1 with_exponential_backoff do CLIENT.get_parameters_by_path( path: path, with_decryption: true, next_token: next_token ) end end def with_exponential_backoff(max_attempts = 10, backoff = 0.5) max_attempts.times do |try| begin return yield rescue Aws::SSM::Errors::ThrottlingException raise ExcessiveThrottlingError unless try < (max_attempts - 1) puts 'Backing off and retrying due to API throttling' sleep (try ** backoff) + (rand * 1.5) end end end end end end