UNPKG

@sudolabs-io/aws-ssm-cli

Version:

Command line tool for AWS Systems Manager Parameter Store

109 lines (90 loc) 2.63 kB
import _ from 'lodash' import { SSMClient, PutParameterCommand, ParameterType } from '@aws-sdk/client-ssm' import { parseDotenv } from './dotenv' import { createClient, addThrottleMiddleware } from './client' import { pullParameters } from './pull' import { ClientConfig, Parameters } from './types' interface Analyze { client: SSMClient prefix: string file: string } async function analyze({ client, prefix, file }: Analyze) { const parsedParameters = parseDotenv(file) const remoteParameters = await pullParameters({ client, prefix }) let skipped = 0 let updated = 0 let created = 0 const parametersToUpdate = _.reduce( parsedParameters, (toUpdate: Parameters, value, name) => { if (_.has(remoteParameters, name)) { if (remoteParameters[name] === value) { skipped++ } else { updated++ toUpdate[name] = value } } else { created++ toUpdate[name] = value } return toUpdate }, {} ) return { total: _.size(parsedParameters), skipped, updated, created, parameters: parametersToUpdate, } } type Stat = { total: number skipped: number updated: number created: number } function printStat({ total, skipped, updated, created }: Stat) { const padSize = _.max([skipped, updated, created])?.toString().length const padStart = (n: number) => _.padStart(n.toString(), padSize) console.log( [ `Total ${total} of parameters:`, ` ${padStart(skipped)} up-to-date`, `~ ${padStart(updated)} updated`, `+ ${padStart(created)} created`, ].join('\n') ) } export interface Push extends ClientConfig { prefix: string file: string } /** * Parameters are sent one by one with 1 second delay after each 10 requests to avoid `ThrottlingException: Rate exceeded`. * See docs: * https://aws.amazon.com/premiumsupport/knowledge-center/ssm-parameter-store-rate-exceeded/ * https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm */ export async function pushParameters({ prefix, file, ...config }: Push): Promise<void> { const client = createClient(config) const { parameters, ...stat } = await analyze({ client, prefix, file }) addThrottleMiddleware(client, { batchSize: 10, wait: 1_000 }) const putCommands = _.map( parameters, (value, name) => new PutParameterCommand({ Type: ParameterType.STRING, Overwrite: true, Name: `${prefix}${name}`, Value: value, }) ) for (const putCommand of putCommands) { await client.send(putCommand) } printStat(stat) }