Skip to content

Instantly share code, notes, and snippets.

@knyga

knyga/handler.js Secret

Created October 14, 2022 21:48
Show Gist options
  • Save knyga/17e46f4bcc8924082a9917fc8a01a9c9 to your computer and use it in GitHub Desktop.
Save knyga/17e46f4bcc8924082a9917fc8a01a9c9 to your computer and use it in GitHub Desktop.
AWS Parameters Store research Lambda Script
/*
Weblab Technology
Oleksandr Knyga
Questions we want to find answers to:
How much time does it take to get a single parameter with and without encryption?
Does the number of parameters read affect the waiting time?
How much slower is parameter retrieval with decryption?
What is the best way to read parameters?
Min Aver Medi Max Retr N Name
217 356 322 822 10 4 FIRST concurrent getParameter (Without Decryption)
240 268 260 313 10 4 FIRST concurrent getParameter (With Decryption)
77 141 105 466 10 4 FIRST getParameters (Without Decryption)
80 96 98 112 10 4 FIRST getParameters (With Decryption)
55 80 82 101 10 4 FIRST getParametersByPath (Without Decryption)
87 107 101 167 10 4 FIRST getParametersByPath (With Decryption)
62 90 82 139 10 1 SECOND concurrent getParameter (Without Decryption)
54 88 83 138 10 1 SECOND concurrent getParameter (With Decryption)
60 78 79 97 10 1 SECOND getParameters (Without Decryption)
59 82 81 110 10 1 SECOND getParameters (With Decryption)
73 102 101 145 10 1 SECOND getParametersByPath (Without Decryption)
78 106 103 163 10 1 SECOND getParametersByPath (With Decryption)
62 94 93 159 10 1 THIRD concurrent getParameter (Without Decryption)
71 89 94 101 10 1 THIRD concurrent getParameter (With Decryption)
64 83 85 94 10 1 THIRD getParameters (Without Decryption)
64 84 82 105 10 1 THIRD getParameters (With Decryption)
60 78 79 96 10 1 THIRD getParametersByPath (Without Decryption)
78 120 99 240 10 1 THIRD getParametersByPath (With Decryption)
101 154 141 319 10 2 FORTH concurrent getParameter (Without Decryption)
108 140 135 220 10 2 FORTH concurrent getParameter (With Decryption)
63 97 84 184 10 2 FORTH getParameters (Without Decryption)
59 79 80 112 10 2 FORTH getParameters (With Decryption)
60 74 77 82 10 2 FORTH getParametersByPath (Without Decryption)
61 79 79 119 10 2 FORTH getParametersByPath (With Decryption)
*/
const AWS = require('aws-sdk')
const ssm = new AWS.SSM()
const TEST_SETS = {
FIRST: [
'/testapp/dev/core_db/username',
'/testapp/dev/core_db/password',
'/testapp/dev/core_db/permissions',
'/testapp/dev/core_db/connection',
],
SECOND: [
'/testapp/dev/core_db/username',
],
THIRD: [
'/testapp/dev/core_db/password',
],
FORTH: [
'/testapp/dev/redis/connection',
'/testapp/dev/redis/flagx',
],
}
function getParentPath(name) {
return name.replace(/\/[^\/]+$/, '')
}
function stats(nums) {
return {
retry: nums.length,
max: Math.max(...nums),
min: Math.min(...nums),
average: Math.round(nums.reduce((acc, v) => acc + v) / nums.length),
median: nums.sort((a, b) => a - b)[Math.trunc(nums.length/2)],
}
}
async function measure(name, type, configs, n = 10) {
const durations = []
let result = null
for(let i=0; i<n; i+=1) {
const d = Date.now()
result = await Promise.all(
configs.map(config => ssm[type](config).promise())
)
durations.push(Date.now() - d)
}
return {
...stats(durations),
name,
}
}
function align(inp, size = 4) {
const txt = inp.toString()
const rem = Math.max(0, size - txt.length)
return txt.substring(0, size) + new Array(rem).fill(' ').join('')
}
function printStats(stats) {
const { name, retry, max, min, average, median, n } = stats
const data = [min, average, median, max, retry, n].map((v) => align(v))
data.push(name)
console.log(data.join('\t'))
}
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
function printTable(sarr) {
printStats(Object.keys(sarr[0]).reduce((acc, key) => ({
...acc,
[key]: capitalize(key),
}), {}))
sarr.forEach(printStats)
}
function tappend(table, params, stats) {
table.push({
n: params.length,
...stats,
})
return table
}
exports.handler = async (event) => {
const table = []
for(const [SET_NAME, SET_PARAMS] of Object.entries(TEST_SETS)) {
tappend(table, SET_PARAMS, await measure(
`${SET_NAME} concurrent getParameter (Without Decryption)`, 'getParameter',
SET_PARAMS.map(Name => ({
Name,
WithDecryption: false,
}))
))
tappend(table, SET_PARAMS, await measure(
`${SET_NAME} concurrent getParameter (With Decryption)`, 'getParameter',
SET_PARAMS.map(Name => ({
Name,
WithDecryption: true,
}))
))
tappend(table, SET_PARAMS, await measure(
`${SET_NAME} getParameters (Without Decryption)`, 'getParameters',
[{
Names: SET_PARAMS,
WithDecryption: true,
}]
))
tappend(table, SET_PARAMS, await measure(
`${SET_NAME} getParameters (With Decryption)`, 'getParameters',
[{
Names: SET_PARAMS,
WithDecryption: true,
}]
))
tappend(table, SET_PARAMS, await measure(
`${SET_NAME} getParametersByPath (Without Decryption)`, 'getParametersByPath',
[{
Path: getParentPath(SET_PARAMS[0]),
WithDecryption: false,
}]
))
tappend(table, SET_PARAMS, await measure(
`${SET_NAME} getParametersByPath (With Decryption)`, 'getParametersByPath',
[{
Path: getParentPath(SET_PARAMS[0]),
WithDecryption: true,
}]
))
}
printTable(table)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment