All Projects → alexcasalboni → Ssm Cache Python

alexcasalboni / Ssm Cache Python

Licence: mit
AWS System Manager Parameter Store caching client for Python

Programming Languages

python
139335 projects - #7 most used programming language
python3
1442 projects
python2
120 projects

Projects that are alternatives of or similar to Ssm Cache Python

Awsmobile Cli
CLI experience for Frontend developers in the JavaScript ecosystem.
Stars: ✭ 147 (-16.95%)
Mutual labels:  aws, aws-lambda, aws-s3
Tensorflow Lambda Layer
Lets you import Tensorflow + Keras from an AWS lambda
Stars: ✭ 79 (-55.37%)
Mutual labels:  aws, aws-lambda, cloud-computing
Curso Aws Com Terraform
🎦 🇧🇷 Arquivos do curso "DevOps: AWS com Terraform Automatizando sua infraestrutura" publicado na Udemy. Você pode me ajudar comprando o curso utilizando o link abaixo.
Stars: ✭ 62 (-64.97%)
Mutual labels:  aws, aws-lambda, aws-s3
0x4447 product s3 email
📫 A serverless email server on AWS using S3 and SES
Stars: ✭ 2,905 (+1541.24%)
Mutual labels:  aws, aws-lambda, aws-s3
Athena Express
athena-express makes it easier to execute SQL queries on Amazon Athena by chaining together a bunch of methods in the AWS SDK. This allows you to execute SQL queries AND fetch JSON results in the same synchronous call - well suited for web applications.
Stars: ✭ 111 (-37.29%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Aws Auto Terminate Idle Emr
AWS Auto Terminate Idle AWS EMR Clusters Framework is an AWS based solution using AWS CloudWatch and AWS Lambda using a Python script that is using Boto3 to terminate AWS EMR clusters that have been idle for a specified period of time.
Stars: ✭ 21 (-88.14%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Autospotting
Saves up to 90% of AWS EC2 costs by automating the use of spot instances on existing AutoScaling groups. Installs in minutes using CloudFormation or Terraform. Convenient to deploy at scale using StackSets. Uses tagging to avoid launch configuration changes. Automated spot termination handling. Reliable fallback to on-demand instances.
Stars: ✭ 2,014 (+1037.85%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Serverless Photo Recognition
A collection of 3 lambda functions that are invoked by Amazon S3 or Amazon API Gateway to analyze uploaded images with Amazon Rekognition and save picture labels to ElasticSearch (written in Kotlin)
Stars: ✭ 345 (+94.92%)
Mutual labels:  aws, aws-lambda, aws-s3
Aws Csa Notes 2018
My AWS Certified Solutions Architect Associate Study Notes!
Stars: ✭ 167 (-5.65%)
Mutual labels:  aws-lambda, aws-s3, amazon-web-services
Serverless Image Processor
AWS Lambda image processor
Stars: ✭ 106 (-40.11%)
Mutual labels:  aws, aws-lambda, aws-s3
Touchdown
Cloud service orchestration framework for python
Stars: ✭ 10 (-94.35%)
Mutual labels:  aws, aws-lambda, aws-s3
Aws Appsync Rds Aurora Sample
An AWS AppSync Serverless resolver for the Amazon Aurora relational database.
Stars: ✭ 122 (-31.07%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Aws S3 Virusscan
Antivirus for Amazon S3 buckets
Stars: ✭ 400 (+125.99%)
Mutual labels:  aws, aws-s3, amazon-web-services
Serverless Es Logs
A Serverless plugin to transport logs to ElasticSearch
Stars: ✭ 51 (-71.19%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Howtheyaws
A curated collection of publicly available resources on how technology and tech-savvy organizations around the world use Amazon Web Services (AWS)
Stars: ✭ 389 (+119.77%)
Mutual labels:  aws, cloud-computing, amazon-web-services
Aws Github Actions
Deploy 🚀 to AWS ☁️ with GitHub Actions!
Stars: ✭ 70 (-60.45%)
Mutual labels:  aws, aws-lambda, aws-s3
Aws Auto Cleanup
Open-source application to programmatically clean your AWS resources based on a whitelist and time to live (TTL) settings
Stars: ✭ 276 (+55.93%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Amazon Rekognition Video Analyzer
A working prototype for capturing frames off of a live MJPEG video stream, identifying objects in near real-time using deep learning, and triggering actions based on an objects watch list.
Stars: ✭ 309 (+74.58%)
Mutual labels:  aws, aws-lambda, amazon-web-services
Smart Security Camera
A Pi Zero and Motion based webcamera that forwards images to Amazon Web Services for Image Processing
Stars: ✭ 103 (-41.81%)
Mutual labels:  aws, aws-lambda, aws-s3
Serverless Docker Image Resize
Simple serverless image resize on-the-fly - Deploy with one command - Built with AWS Lambda and S3
Stars: ✭ 114 (-35.59%)
Mutual labels:  aws, aws-lambda, aws-s3

AWS System Manager Parameter Store Caching Client for Python (Python 2.7 Python 3.6 Python 3.7)

Build Status Coverage Status PyPI version GitHub license Maintenance GitHub issues Open Source Love svg2 GitHub stars

This module wraps the AWS Parameter Store and adds a caching and grouping layer with max-age invalidation.

You can use this module with AWS Lambda to read and refresh parameters and secrets. Your IAM role will require ssm:GetParameters permissions (optionally, also kms:Decrypt if you use SecureString params).

How to install

Install the module with pip:

pip install ssm-cache

How to use it

Simplest use case

A single parameter, configured by name.

from ssm_cache import SSMParameter
param = SSMParameter('my_param_name')
value = param.value

With cache invalidation

You can configure the max_age in seconds, after which the values will be automatically refreshed.

from ssm_cache import SSMParameter
param_1 = SSMParameter('param_1', max_age=300)  # 5 min
value_1 = param.value

param_2 = SSMParameter('param_2', max_age=3600)  # 1 hour
value_2 = param_2.value

With multiple parameters

You can configure more than one parameter to be fetched/cached/decrypted as a group.

from ssm_cache import SSMParameterGroup
group = SSMParameterGroup(max_age=300)
param_1 = group.parameter('param_1')
param_2 = group.parameter('param_2')

value_1 = param_1.value
value_2 = param_2.value

With hierarchical parameters

You can fetch/cache a group of parameters under a given prefix. Optionally, the group itself could have its own base path.

from ssm_cache import SSMParameterGroup
group = SSMParameterGroup(base_path="/Foo")
foo_bar = group.parameter('/Bar')  # will fetch /Foo/Bar
baz_params = group.parameters('/Baz')  # will fetch /Foo/Baz/1 and /Foo/Baz/2

assert len(group) == 3

Note: you can call group.parameters(...) multiple times. If caching is enabled, the group's cache will expire when the firstly fetched parameters expire.

Hierarchical parameters and filters

You can filter by parameter Type and KMS KeyId, either building the filter object manually or using a class-based approach (which provides some additional checks before invoking the API).

from ssm_cache import SSMParameterGroup
from ssm_cache.filters import SSMFilterType

group = SSMParameterGroup()

# manual filter definition
params = group.parameters(
    path="/Foo/Bar",
    filters=[{
        'Key': 'Type',
        'Option': 'Equals',
        'Values': ['StringList']
    }],
)

# class-based filter
params = group.parameters(
    path="/Foo/Bar",
    filters=[SSMFilterType().value('StringList')],  # will validate allowed value(s)
)

Hierarchical parameters and non-recursiveness

You can disable recursion when fetching parameters via prefix.

from ssm_cache import SSMParameterGroup
group = SSMParameterGroup()

# will fetch /Foo/1, but not /Foo/Bar/1
params = group.parameters(
    path="/Foo",
    recursive=False,
)

With StringList parameters

StringList parameters (documentation here) are automatically converted to Python lists with no additional configuration.

from ssm_cache import SSMParameter
# "my_twitter_api_keys" is a StringList parameter (four comma-separated values)
twitter_params = SSMParameter('my_twitter_api_keys')
key, secret, access_token, access_token_secret = twitter_params.value

Explicit refresh

You can manually force a refresh on a parameter or parameter group. Note that if a parameter is part of a group, the refresh operation will involve the entire group.

from ssm_cache import SSMParameter
param = SSMParameter('my_param_name')
value = param.value
param.refresh()
new_value = param.value
from ssm_cache import SSMParameterGroup
group = SSMParameterGroup()
param_1 = group.parameter('param_1')
param_2 = group.parameter('param_2')

value_1 = param_1.value
value_2 = param_2.value

group.refresh()
new_value_1 = param_1.value
new_value_2 = param_2.value

param_1.refresh()
new_new_value_1 = param_1.value
new_new_value_2 = param_2.value # one parameter refreshes the whole group

Without decryption

Decryption is enabled by default, but you can explicitly disable it (works for SSMParameter and SSMGroup).

from ssm_cache import SSMParameter
param = SSMParameter('my_param_name', with_decryption=False)
value = param.value

AWS Secrets Manager Integration

You can read AWS Secrets Manager secrets transparently by using the SecretsManagerParameter class, which comes with the same interface of SSMParameter and performs some additional prefixing and validation.

from ssm_cache import SecretsManagerParameter
secret = SecretsManagerParameter('my_secret_name')
value = secret.value

Secrets can be added to a SSMParameterGroup as well, although no group prefix will be applied.

from ssm_cache import SSMParameterGroup
group = SSMParameterGroup()
param = group.parameter('my_param')
secret = group.secret('my_secret')

param_value = param.value
secret_value = secret.value

Versioning support

SSM Parameter Store supports version selectors (documentation here).

By default, the latest version is fetched if you don't specify it.

Here is how you can retrieve a specific parameter version:

from ssm_cache import SSMParameter
param = SSMParameter('my_param_name:2')
value = param.value

Please note that invoking param.refresh() will not fetch newer versions. This is the intended behavior, as version selection should be used only when you need a specific parameter version.

If you don't specify any version, you can always read the current version of a parameter. In this case, invoking param.refresh() will invoke the new version.

from ssm_cache import SSMParameter
param = SSMParameter('my_param_name')
print(param.version)  # will print an int

Usage with AWS Lambda

Your AWS Lambda code will look similar to the following snippet.

from ssm_cache import SSMParameter, SecretsManagerParameter
param = SSMParameter('my_param_name')
secret = SecretsManagerParameter('my_secret_name')

def lambda_handler(event, context):
    dbname = param.value
    password = secret.value
    return 'Hello from Lambda with dbname %s and password %s' % (dbname, password)

Complex invalidation based on "signals"

You may want to explicitly refresh the parameter cache when you believe the cached value expired.

In the example below, we refresh the parameter value when an InvalidCredentials exception is detected (see the decorator utility for a simpler version!).

from ssm_cache import SSMParameter
from my_db_lib import Client, InvalidCredentials  # pseudo-code

param = SSMParameter('my_db_password')
my_db_client = Client(password=param.value)

def read_record(is_retry=False):
    try:
        return my_db_client.read_record()
    except InvalidCredentials:
        if not is_retry:  # avoid infinite recursion
            param.refresh()  # force parameter refresh
            my_db_client = Client(password=param.value)  # re-configure db client
            return read_record(is_retry=True)  # let's try again :)

def lambda_handler(event, context):
    return {
        'record': read_record(),
    }

Decorator utility

The retry logic shown above can be simplified with the decorator method provided by each SSMParameter and SSMParameterGroup object.

The @refresh_on_error decorator will intercept errors (or a specific error_class, if given), refresh the parameters values, and attempt to re-call the decorated function. Optionally, you can provide a callback argument to implement your own logic (in the example below, to create a new db client with the new password).

from ssm_cache import SSMParameter
from my_db_lib import Client, InvalidCredentials  # pseudo-code

param = SSMParameter('my_db_password')
my_db_client = Client(password=param.value)

def on_error_callback():
    my_db_client = Client(password=param.value)

@param.refresh_on_error(InvalidCredentials, on_error_callback)
def read_record(is_retry=False):
    return my_db_client.read_record()

def lambda_handler(event, context):
    return {
        'record': read_record(),
    }

The refresh_on_error decorator supports the following arguments:

  • error_class (default: Exception)
  • error_callback (default: None)
  • retry_argument (default: "is_retry")

Replacing the SSM client

If you want to replace the default boto3 SSM client, SSMParameter allows you to call set_ssm_client and provide your own boto3 client or even a custom object. Note that such custom object will need to implement two methods: get_parameters and get_parameters_by_path.

For example, here's how you could inject a Placebo client for local tests:

import placebo, boto3
from ssm_cache import SSMParameter

# create regular boto3 session
session = boto3.Session()
# attach placebo to the session
pill = placebo.attach(session, data_path=PLACEBO_PATH)
pill.playback()
# create special boto3 client
client = session.client('ssm')
# inject special client into SSMParameter or SSMParameterGroup
SSMParameter.set_ssm_client(client)

How to contribute

Clone this repository, create a virtualenv and install all the dev dependencies:

git clone https://github.com/alexcasalboni/ssm-cache-python.git
cd ssm-cache-python
virtualenv env
source env/bin/activate
pip install -r requirements-dev.txt

You can run tests with nose:

nosetests

Generate a coverage report:

nosetests --with-coverage --cover-erase --cover-html --cover-package=ssm_cache
open cover/index.html

Run pylint:

pylint ssm_cache

Note: when you open a new PR, GitHub will run tests on multiple Python environments and verify the new coverage for you, but we highly recommend you run these tasks locally as well before submitting new code.

What's new?

  • version 2.9: bugfix, versioning support, tests with Python 3.7
  • version 2.8: bugfix, new tests, fixed Travis build config
  • version 2.7: support for AWS Secrets Manager integration
  • version 2.5: hierarchical parameters, filters, and non-recursiveness support
  • version 2.3: StringList parameters support (auto-conversion)
  • version 2.2: client replacement and boto3/botocore minimum requirements
  • version 2.1: group refresh bugfix
  • version 2.0: new interface, SSMParameterGroup support
  • version 1.3: Python3 support
  • version 1.0: initial release

References and articles

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].