Skip to content

Commit 1f2b387

Browse files
authored
Merge pull request #33 from HyperBrain/support-cw-events
Support CW events.
2 parents 47c8106 + 94c83f7 commit 1f2b387

File tree

3 files changed

+76
-6
lines changed

3 files changed

+76
-6
lines changed

README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,6 @@ hook into the deployment process.
3232
Additionally the new `alias` command is added to Serverless which offers some
3333
functionality for aliases.
3434

35-
## Interoperability
36-
37-
Care has to be taken when using other plugins that modify the CF output too.
38-
I will add configuration instructions in this section for these plugin combinations.
39-
4035
## Deploy the default alias
4136

4237
The default alias (for the stage) is deployed just by doing a standard stage
@@ -226,6 +221,19 @@ the alias stack has been removed.
226221
The alias plugin is compatible with all standard Serverless commands and switches.
227222
For example, you can use `--noDeploy` and the plugin will behave accordingly.
228223

224+
## Interoperability
225+
226+
Care has to be taken when using other plugins that modify the CF output too.
227+
I will add configuration instructions in this section for these plugin combinations.
228+
229+
### [serverless-plugin-warmup](https://github.com/FidelLimited/serverless-plugin-warmup)
230+
231+
The warmup plugin will keep your Lambdas warm and reduce the cold start time
232+
effectively. When using the plugin, it must be listed **before** the alias plugin
233+
in the plugin list of _serverless.yml_. The warmup lambda created by the plugin
234+
will be aliased too, so that the warmup plugin can be configured differently
235+
per deployed alias.
236+
229237
## Test it
230238

231239
In case you wanna test how it behaves, I provided a predefined test service in
@@ -307,6 +315,8 @@ and _serverless.service.provider.deployedAliasTemplates[]_.
307315

308316
* 0.5.0-alpha1 Fixes a bug with deploying event sources introduced with 0.4.0
309317
Use new event model introduced in SLS 1.12. Needs SLS 1.12 or greater from now on.
318+
Add support for CW events.
319+
Set SERVERLESS_ALIAS environment variable on deployed functions.
310320
* 0.4.0-alpha1 APIG support fixed. Support external IAM roles. BREAKING.
311321
* 0.3.4-alpha1 Bugfixes. IAM policy consolitaion. Show master alias information.
312322
* 0.3.3-alpha1 Bugfixes. Allow manual resource overrides. Allow methods attached to APIG root resource.

lib/aliasRestructureStack.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ module.exports = {
9191
}
9292
};
9393

94+
// Set SERVERLESS_ALIAS environment variable
95+
_.forOwn(stageStack.Resources, resource => {
96+
if (resource.Type === 'AWS::Lambda::Function') {
97+
_.set(resource, 'Properties.Environment.Variables.SERVERLESS_ALIAS', this._alias);
98+
}
99+
});
94100

95101
const versions = _.assign({}, _.pickBy(stageStack.Resources, [ 'Type', 'AWS::Lambda::Version' ]));
96102
if (!_.isEmpty(versions)) {
@@ -313,6 +319,55 @@ module.exports = {
313319
return BbPromise.resolve([ currentTemplate, aliasStackTemplates, currentAliasStackTemplate ]);
314320
},
315321

322+
aliasHandleCWEvents(currentTemplate, aliasStackTemplates, currentAliasStackTemplate) {
323+
324+
const stageStack = this._serverless.service.provider.compiledCloudFormationTemplate;
325+
const aliasStack = this._serverless.service.provider.compiledCloudFormationAliasTemplate;
326+
327+
const cwEvents = _.assign({}, _.pickBy(_.get(stageStack, 'Resources', {}), [ 'Type', 'AWS::Events::Rule' ]));
328+
const cwEventLambdaPermissions =
329+
_.assign({},
330+
_.pickBy(_.pickBy(stageStack.Resources, [ 'Type', 'AWS::Lambda::Permission' ]),
331+
['Properties.Principal', 'events.amazonaws.com']));
332+
333+
_.forOwn(cwEvents, (cwEvent, name) => {
334+
// Reference alias as FunctionName
335+
const targetRefs = utils.findAllReferences(_.get(cwEvent, 'Properties.Targets'));
336+
cwEvent.DependsOn = cwEvent.DependsOn || [];
337+
_.forEach(targetRefs, ref => {
338+
const functionName = _.replace(ref.ref, /LambdaFunction$/, '');
339+
_.set(cwEvent.Properties.Targets, ref.path, { Ref: `${functionName}Alias` });
340+
cwEvent.DependsOn.push(`${functionName}Alias`);
341+
});
342+
343+
// Remove mapping from stage stack
344+
delete stageStack.Resources[name];
345+
});
346+
347+
// Move event subscriptions to alias stack
348+
_.defaults(aliasStack.Resources, cwEvents);
349+
350+
// Adjust permission to reference the function aliases
351+
_.forOwn(cwEventLambdaPermissions, (permission, name) => {
352+
const targetFunctionRef = utils.findAllReferences(_.get(permission, 'Properties.FunctionName'));
353+
const functionName = _.replace(targetFunctionRef[0].ref, /LambdaFunction$/, '');
354+
355+
// Adjust references and alias permissions
356+
permission.Properties.FunctionName = { Ref: `${functionName}Alias` };
357+
358+
// Add dependency on function alias
359+
permission.DependsOn = [ `${functionName}Alias` ];
360+
361+
delete stageStack.Resources[name];
362+
});
363+
364+
// Add all alias stack owned resources
365+
_.defaults(aliasStack.Resources, cwEventLambdaPermissions);
366+
367+
// Forward inputs to the promise chain
368+
return BbPromise.resolve([ currentTemplate, aliasStackTemplates, currentAliasStackTemplate ]);
369+
},
370+
316371
aliasFinalize(currentTemplate, aliasStackTemplates, currentAliasStackTemplate) {
317372
const aliasStack = this._serverless.service.provider.compiledCloudFormationAliasTemplate;
318373

@@ -336,6 +391,7 @@ module.exports = {
336391
.spread(this.aliasHandleFunctions)
337392
.spread(this.aliasHandleApiGateway)
338393
.spread(this.aliasHandleEvents)
394+
.spread(this.aliasHandleCWEvents)
339395
.spread(this.aliasFinalize)
340396
.then(() => BbPromise.resolve());
341397
}

lib/stackops/apiGateway.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
9595
}
9696

9797
// Fetch lambda permissions, methods and resources. These have to be updated later to allow the aliased functions.
98-
const apiLambdaPermissions = _.assign({}, _.pickBy(stageStack.Resources, [ 'Type', 'AWS::Lambda::Permission' ]));
98+
const apiLambdaPermissions =
99+
_.assign({},
100+
_.pickBy(_.pickBy(stageStack.Resources, [ 'Type', 'AWS::Lambda::Permission' ]),
101+
['Properties.Principal', 'apigateway.amazonaws.com']));
102+
99103
const apiMethods = _.assign({}, _.pickBy(stageStack.Resources, [ 'Type', 'AWS::ApiGateway::Method' ]));
100104
//const apiResources = _.assign({}, _.pickBy(stageStack.Resources, [ 'Type', 'AWS::ApiGateway::Resource' ]));
101105
const aliases = _.assign({}, _.pickBy(aliasStack.Resources, [ 'Type', 'AWS::Lambda::Alias' ]));

0 commit comments

Comments
 (0)