What would you use sreda
for?
There is a very nice article by Yan Cui that
explains very well, why you should use AWS SSM/KMS
and also why you should
build your own client to do so.
There is a couple of reasons for your own implementation:
- caching
- hot-swapping of configurations
You can find more about it in Yan's article on medium.
sreda
takes the inspiration from the Yan's medium article and this gist from Aaron Ackerman, which was probably also inspired by Yan Cui and packs it all into an npm
package.
sreda
exposes two functions:
load
- loads the configurationkeys
- returns ajson
object with yourkey/value
pairs
If you want to load the configuration for certain keys from SSM, you have to:
const { read } = require('sreda')
const AWS = require('aws-sdk')
const ssm = new AWS.SSM({
region: 'us-west-1'
})
const config = read(
ssm,
['foo', 'bar'],
30000) // cache configuration for 30 seconds
const anotherConfig = read(
ssm,
['fizz', 'buzz']) // default cache expiration is 3 minutes
exports.handler = async (event, context, callback) => {
let keys = {
foo: await config.keys.foo,
bar: await config.keys.bar,
fizz: await anotherConfig.keys.fizz,
buzz: await anotherConfig.keys.buzz
}
const response = {
statusCode: 200,
body: JSON.stringify({
message: `SSM Keys`,
keys
})
}
callback(null, response)
}
Alternatively you can make use of the keys
function that return a json
object with key/value
pairs of your ssm
keys, e.g.
const { keys } = require('sreda')
const AWS = require('aws-sdk')
const ssm = new AWS.SSM({
region: 'us-west-1'
})
exports.handler = async (event, context, callback) => {
let keys = await keys(ssm, ['foo', 'bar'])
const response = {
statusCode: 200,
body: JSON.stringify({
message: `SSM Keys`,
keys
})
}
callback(null, response)
}
In order for your lambda function to access the SSM
it has to:
- have access to the internet
- have rights to get the parameters from
SSM
To allow your lambda function to access SSM
you have to put similar
iamRoleStatements
section into your provider
block
Please note, in order to be able to use CloudFormation Pseudo Parameters, like
${AWS::Region} and ${AWS::AccountId} you have to use a variableSyntax
parameter with the value you see in the example below and you should use
'Fn::Sub'
when assembling your Resource
provider:
name: aws
runtime: nodejs8.10
variableSyntax: "\\${((?!AWS)[ ~:a-zA-Z0-9._'\",\\-\\/\\(\\)]+?)}"
iamRoleStatements:
- Effect: 'Allow'
Action: 'ssm:GetParameters'
Resource:
- 'Fn::Sub': 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/*'
- Effect: 'Allow'
Action: 'kms:Decrypt'
Resource:
- 'Fn::Sub': 'arn:aws:kms:us-east-1:${AWS::AccountId}:key/<your-kms-key>'
Through the iamRoleStatements
you can also granulary manage the access of
your lambda function to SSM
provider:
name: aws
runtime: nodejs8.10
variableSyntax: "\\${((?!AWS)[ ~:a-zA-Z0-9._'\",\\-\\/\\(\\)]+?)}"
iamRoleStatements:
- Effect: 'Allow'
Action: 'ssm:GetParameters'
Resource:
- 'Fn::Sub':
'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/foo'
- 'Fn::Sub':
'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/bar'
- Effect: 'Allow'
Action: 'kms:Decrypt'
Resource:
- 'Fn::Sub': 'arn:aws:kms:us-east-1:${AWS::AccountId}:key/<your-kms-key>'
If you use sreda
while developing locally, you can set process.env.NODE_ENV = 'local'
and use the environment variables set in process.env
.