thoreinstein / serverless-offline-ssm

Read SSM parameters from a .env file instead of AWS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Upgrade to new Variables resolver of Serverless Framework

medikoo opened this issue · comments

This plugin seems to rely on old variable resolver that is scheduled to be removed with v3 version of a Framework:

https://github.com/janders223/serverless-offline-ssm/blob/cd12de830a6a88f40120e98d1103580766799eef/src/index.ts#L55

To remain working on grounds of v3 it needs to be updated to not depend on it

@medikoo, did you fork this to make that happen? Do you know how the new resolution works? I was looking to make this update for my uses as well.

@wweaver I did not, and as I think of it, this plugin cannot really work in v3, as in v3 variables are resolved even before plugins are initialized.

Framework may allow to introduce extension that loads earlier, but it's just a proposal at this point: serverless/serverless#9311 (share your interest by adding +1)

@medikoo this thread has promise for me. Trying it out.

#145

Made my own custom version

const fs = require('fs');

function getValueFromEnv(key) {
    return new Promise((resolve, reject) => {
        if (!fs.existsSync('.env')) {
            resolve();
            return;
        }
        fs.readFile('.env', { encoding: 'utf-8' }, (err, data) => {
            if (err) {
                reject(err);
                return;
            }
            const values = data
                .trim()
                .split('\n')
                .map((line) => line.split(/=(.*)/))
                .reduce(
                    (accumulation, [key, value]) => Object.assign(Object.assign({}, accumulation), { [key]: value }),
                    {},
                );
            resolve(values[key]);
        });
    });
}

class OfflineSSM {
    constructor(serverless, options) {
        this.serverless = serverless;
        this.service = serverless.service;
        this.config = (this.service.custom && this.service.custom['serverless-offline-ssm']) || {};
        this.stage = serverless.service.provider.stage;

        if (!this.shouldExecute()) {
            return;
        }

        const aws = this.serverless.getProvider('aws');
        const originalRequest = aws.request.bind(aws);

        aws.request = async (service, method, params) => {
            if (service !== 'SSM' || method !== 'getParameter') {
                return originalRequest(service, method, params, options);
            }
            const Value = await getValueFromEnv(params.Name);
            return { Parameter: { Value, Type: 'String', ...params } };
        };

        this.serverless.setProvider('aws', aws);
    }

    shouldExecute() {
        if (this.config.stages && this.config.stages.includes(this.stage)) {
            return true;
        }
        return false;
    }
}

module.exports = OfflineSSM;