UNPKG

briareus

Version:

Briareus assists with Feature Branch deploys to ECS

79 lines (68 loc) 2.76 kB
'use strict' const async = require('async'); const _ = require('lodash'); const AWS = require('aws-sdk'); const crypto = require('crypto'); const config = require('../config'); const utils = require('../../utilities'); const deleteSsmParameters = require('./destroy-ssm-parameters').deleteSsmParameters; let action = module.exports = function (pipeline, payload, cb) { const ssm = new AWS.SSM(); const kms = new AWS.KMS(); function putSecret(name, value, cb) { kms.decrypt({ CiphertextBlob: Buffer.from(value, 'base64') }, (err, data) => { if (err) return cb(err); let params = { Name: name, Type: 'SecureString', Value: data.Plaintext.toString(), Description: `Secret for Briareus Variant ${payload.id}`, KeyId: payload.kmsKeyArn, Overwrite: true, }; utils.awsRetry((done) => ssm.putParameter(params, done), cb); }); } function putSecrets(secrets, cb) { async.mapLimit(secrets, 3, (secret, next) => { let paramPath = `${payload.ssmParameterScopePrefix}/${secret.id}`; putSecret(paramPath, secret.value, (err, data) => { if (err) return next(err); // Hash `id` to avoid `/` in asset path. Otherwise JSON Patch will try // to set values on undefined objects. eg if `id` is `web/API_KEY` then JSON patch // will try to set `API_KEY` on object `web` (which won't exist). But we should // track SSM Parameters via `id` since this is a PUT operation. ie we override // existing parameters if the `id` is the same. let hashedId = crypto.createHash('md5').update(secret.id).digest("hex"); // Small timeout to help avoid API request throttling. setTimeout(() => { next(null, { op: 'add', path: `/assets/ssmParameters/${hashedId}`, value: { id: secret.id, hashedId: hashedId, arn: `arn:aws:ssm:${config.get('aws.region')}:${payload.awsAccountId}:parameter${paramPath}`, path: paramPath, name: secret.name, container: secret.container } }); }, 200); }); }, cb); } const secretIds = _.map(payload.secrets, 'id'); const removedParameters = _.filter(_.values(payload.assets.ssmParameters), (ssmParam) => { return secretIds.indexOf(ssmParam.id) === -1 }); async.waterfall([ (done) => putSecrets(payload.secrets, done), (ops, done) => deleteSsmParameters(removedParameters, (err, ops2) => { if (err) return done(err); done(null, [].concat(ops, ops2)); }) ], cb); } action.waiting = 'Syncing SSM Parameter Secrets'; action.done = 'SSM Parameter Secrets have been synchronized';