Class: SecretConfig::Providers::Ssm

Inherits:
Provider
  • Object
show all
Defined in:
lib/secret_config/providers/ssm.rb

Overview

Use the AWS System Manager Parameter Store for Centralized Configuration / Secrets Management

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Provider

#to_h

Constructor Details

#initialize(key_id: ENV["SECRET_CONFIG_KEY_ID"], key_alias: ENV["SECRET_CONFIG_KEY_ALIAS"], retry_count: 25, retry_max_ms: 10_000, **args) ⇒ Ssm

Returns a new instance of Ssm.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/secret_config/providers/ssm.rb', line 13

def initialize(
  key_id: ENV["SECRET_CONFIG_KEY_ID"],
  key_alias: ENV["SECRET_CONFIG_KEY_ALIAS"],
  retry_count: 25,
  retry_max_ms: 10_000,
  **args
)
  @key_id       =
    if key_alias
      key_alias =~ %r{^alias/} ? key_alias : "alias/#{key_alias}"
    else
      key_id
    end
  @retry_count  = retry_count
  @retry_max_ms = retry_max_ms
  @logger       = SemanticLogger["Aws::SSM"] if defined?(SemanticLogger)
  @client       = Aws::SSM::Client.new({logger: logger}.merge!(args))
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



11
12
13
# File 'lib/secret_config/providers/ssm.rb', line 11

def client
  @client
end

#key_idObject (readonly)

Returns the value of attribute key_id.



11
12
13
# File 'lib/secret_config/providers/ssm.rb', line 11

def key_id
  @key_id
end

#loggerObject (readonly)

Returns the value of attribute logger.



11
12
13
# File 'lib/secret_config/providers/ssm.rb', line 11

def logger
  @logger
end

#retry_countObject (readonly)

Returns the value of attribute retry_count.



11
12
13
# File 'lib/secret_config/providers/ssm.rb', line 11

def retry_count
  @retry_count
end

#retry_max_msObject (readonly)

Returns the value of attribute retry_max_ms.



11
12
13
# File 'lib/secret_config/providers/ssm.rb', line 11

def retry_max_ms
  @retry_max_ms
end

Instance Method Details

#delete(key) ⇒ Object

Deletes the key. Nothing is done if the key was not found.



79
80
81
82
# File 'lib/secret_config/providers/ssm.rb', line 79

def delete(key)
  client.delete_parameter(name: key)
rescue Aws::SSM::Errors::ParameterNotFound
end

#each(path) ⇒ Object

Yields the key with its absolute path and corresponding string value



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/secret_config/providers/ssm.rb', line 33

def each(path)
  retries = 0
  token   = nil
  loop do
    begin
      resp = client.get_parameters_by_path(
        path:            path,
        recursive:       true,
        with_decryption: true,
        next_token:      token
      )
    rescue Aws::SSM::Errors::ThrottlingException => e
      # The free tier allows 40 calls per second.
      # The Higher Throughput tier for additional cost is still limited to 100 calls per second.
      # Using a random formula since this limit is normally only exceeded during a high volume restart period
      # so we want to spread out the retries of the multiple servers.
      retries += 1
      if retry_count > retries
        sleep_seconds = rand(retry_max_ms) / 1000.0
        logger&.info("SSM Parameter Store GetParametersByPath API Requests throttle exceeded, retry: #{retries}, sleeping #{sleep_seconds} seconds.")
        sleep(sleep_seconds)
        retry
      end
      logger&.info("SSM Parameter Store GetParametersByPath API Requests throttle exceeded, retries exhausted.")
      raise(e)
    end

    resp.parameters.each { |param| yield(param.name, param.value) }
    token = resp.next_token
    break if token.nil?
  end
end

#fetch(key) ⇒ Object

Returns the value or ‘nil` if not found



85
86
87
88
# File 'lib/secret_config/providers/ssm.rb', line 85

def fetch(key)
  client.get_parameter(name: key, with_decryption: true).parameter.value
rescue Aws::SSM::Errors::ParameterNotFound
end

#set(key, value) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/secret_config/providers/ssm.rb', line 66

def set(key, value)
  client.put_parameter(
    name:      key,
    value:     value.to_s,
    type:      "SecureString",
    key_id:    key_id,
    overwrite: true,
    tier:      "Intelligent-Tiering"
  )
end