Releasing DynamoDB Config Store

June 29, 2014

Reading time ~3 minutes

I am releasing DynamoDB Config Store open source today. The project provides easy configuration management for Python projects. The configuration options are stored in AWS DynamoDB and can be created, updated and fetched using the DynamoDBConfigStore class.

Storing configuration in DynamoDB has some advantages, for example:

  • The configuration is easily and consistently available across many nodes
  • One option can consist of many keys and values

Imaging a DynamoDB table like this:

------------+----------------+----------------+----------------+----------------
_store*     | _option**      | host           | port           | secret-key
------------+----------------+----------------+----------------+----------------
prod        | db             | db-cluster.com | 27017          |
prod        | external-port  |                | 80             |
prod        | secret-key     |                |                | abcd1234
test        | db             | localhost      | 27017          |
test        | external-port  |                | 4000           |
prod        | secret-key     |                |                | test1234
------------+----------------+----------------+----------------+----------------

*) Hash key
**) Range key

The table contains two Stores (prod and test) and each Store has three Options. Take a closer look at the db option. It contains both a host key and a port key.

DynamoDB Config Store supports a few different ways to retrieve configuration. Currently we support:

  • Simple config store (SimpleConfigStore)
  • Time based config store (TimeBasedConfigStore)

The Simple config store will always query DynamoDB for the latest configuration option. This behavior will consume more reads, but in return you’ll always get the latest configuration back.

The Time based config store read data from DynamoDB on a schedule and exposes all options as instance attributes, e.g. store.config.option. That approach reduces the read unit consumption, but is not “strongly” consistent as all configuration updates are not reflect until the next config reload.

I will go through the details of the SimpleConfigStore below.

Installation

The easiest way to install DynamoDB Config Store is via pip:

pip install dynamodb-config-store

Instanciate a Store

A store can be instanciated like this:

from dynamodb_config_store import DynamoDBConfigStore

store = DynamoDBConfigStore(
    connection,                 # boto.dynamodb2.layer1.DynamoDBConnection
    table_name,                 # Table name to use
    store_name)                 # Store name to use

When the Store is instanciated it will create the table if it does not exist. Currently a table with 1 read unit and 1 write unit will be created.

If the Store is instanciated towards an existing table, it will check that the table schema matches the expected Store schema. In other words it will check that store_key is the table hash key and that option_key is the table range key.

Write configuration

You can insert new items in the configuration via the set method.

# 'option' is the name of the option where you want to store the values
store.set('option', {'key1': 'value', 'key2': 'value'})

set takes an option (str) and a dict with keys and values.

Reading configuration

Read a specific Option

Specific Options can be fetched like this:

store.config.get('option')

You will get a dict with all Keys related to the given Option:

{
    'key1': 'value1',
    'key2': 'value2',
    'key3': 'value3',
    'key4': 'value4'
}

Get specific Keys from an Option

If you don’t need all Keys in the response, you can select which Keys you want to retrieve by adding the keys parameter:

store.config.get('option', keys=['key1', 'key4'])

Returns:

{
    'key1': 'value1',
    'key4': 'value4'
}

Fetching all Options in a Store

If you want to retrieve all Options within a Stor, simply omit the option in the request:

store.config.get()

You will get an dictionary like this in return:

{
    'option1': {
        'key1': 'value1',
        'key2': 'value2'
    },
    'option2': {
        'key1': 'value1',
        'key4': 'value2'
    }
}

Wrapping up

Thanks for reading this long post :). Let me know if you find any issues with the project, and don’t forget to star it on GitHub!.