mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
Add Application Load Balancer event source
This commit is contained in:
parent
9d1cc66681
commit
0738f7b8f4
@ -93,6 +93,7 @@ If you have any questions, [search the forums](https://forum.serverless.com?utm_
|
||||
<li><a href="./events/schedule.md">Schedule</a></li>
|
||||
<li><a href="./events/sns.md">SNS</a></li>
|
||||
<li><a href="./events/sqs.md">SQS</a></li>
|
||||
<li><a href="./evetns/alb.md">ALB</a></li>
|
||||
<li><a href="./events/alexa-skill.md">Alexa Skill</a></li>
|
||||
<li><a href="./events/alexa-smart-home.md">Alexa Smart Home</a></li>
|
||||
<li><a href="./events/iot.md">IoT</a></li>
|
||||
|
||||
47
docs/providers/aws/events/alb.md
Normal file
47
docs/providers/aws/events/alb.md
Normal file
@ -0,0 +1,47 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - ALB
|
||||
menuText: Application Load Balancer
|
||||
menuOrder: 8
|
||||
description: Setting up AWS Application Load Balancer events with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
<!-- DOCS-SITE-LINK:START automatically generated -->
|
||||
### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/alb)
|
||||
<!-- DOCS-SITE-LINK:END -->
|
||||
|
||||
# Application Load Balancer
|
||||
|
||||
[Application Load Balancers](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html) can be used to re-route requests when certain traffic patterns are met. While traffic can be routed to services such as EC2 it [can also be routed to Lambda functions](https://aws.amazon.com/de/blogs/networking-and-content-delivery/lambda-functions-as-targets-for-application-load-balancers/) which can in turn be used process incoming requests.
|
||||
|
||||
The Serverless Framework makes it possible to setup the connection between Application Load Balancers and Lamdba functions with the help of the `alb` event.
|
||||
|
||||
## Event definition
|
||||
|
||||
The following code will setup an alb using a HTTPS-based listener.
|
||||
|
||||
```yml
|
||||
functions:
|
||||
albEventConsumer:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- alb:
|
||||
loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
certificateArn: arn:aws:iam::123456:server-certificate/ProdServerCert
|
||||
name: alb-handler-https
|
||||
listener: HTTPS:443
|
||||
```
|
||||
|
||||
The Application Load Balancer `arn` can also be referenced via `Ref`. HTTP listeners don't require the `certificateArn` property to be set.
|
||||
|
||||
```yml
|
||||
functions:
|
||||
albEventConsumer:
|
||||
handler: handler.hello
|
||||
events:
|
||||
- alb:
|
||||
loadBalancerArn:
|
||||
Ref: MyApplicationLoadBalancer
|
||||
name: alb-handler-http
|
||||
listener: HTTP:80
|
||||
```
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - Alexa Skill
|
||||
menuText: Alexa Skill
|
||||
menuOrder: 8
|
||||
menuOrder: 9
|
||||
description: Setting up AWS Alexa Skill Events with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - Alexa Smart Home
|
||||
menuText: Alexa Smart Home
|
||||
menuOrder: 13
|
||||
menuOrder: 10
|
||||
description: Setting up AWS Alexa Smart Home Events with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - CloudWatch Event
|
||||
menuText: CloudWatch Event
|
||||
menuOrder: 10
|
||||
menuOrder: 12
|
||||
description: Setting up AWS CloudWatch Events with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - CloudWatch Log
|
||||
menuText: CloudWatch Log
|
||||
menuOrder: 11
|
||||
menuOrder: 13
|
||||
description: Setting up AWS CloudWatch Logs with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - Cognito User Pool
|
||||
menuText: Cognito User Pool
|
||||
menuOrder: 12
|
||||
menuOrder: 14
|
||||
description: Setting up AWS Cognito User Pool Triggers with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<!--
|
||||
title: Serverless Framework - AWS Lambda Events - IoT
|
||||
menuText: IoT
|
||||
menuOrder: 9
|
||||
menuOrder: 11
|
||||
description: Setting up AWS IoT Events with AWS Lambda via the Serverless Framework
|
||||
layout: Doc
|
||||
-->
|
||||
|
||||
@ -269,6 +269,11 @@ functions:
|
||||
- cognitoUserPool:
|
||||
pool: MyUserPool
|
||||
trigger: PreSignUp
|
||||
- alb:
|
||||
loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert # only required when HTTPS is used
|
||||
name: alb-handler-https
|
||||
listener: HTTPS:443
|
||||
|
||||
layers:
|
||||
hello: # A Lambda layer
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
"./aws/package/compile/events/websockets/index.js",
|
||||
"./aws/package/compile/events/sns/index.js",
|
||||
"./aws/package/compile/events/stream/index.js",
|
||||
"./aws/package/compile/events/alb/index.js",
|
||||
"./aws/package/compile/events/alexaSkill/index.js",
|
||||
"./aws/package/compile/events/alexaSmartHome/index.js",
|
||||
"./aws/package/compile/events/iot/index.js",
|
||||
|
||||
@ -369,6 +369,14 @@ module.exports = {
|
||||
}`;
|
||||
},
|
||||
|
||||
// ALB
|
||||
getAlbTargetGroupLogicalId(functionName) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}AlbTargetGroup`;
|
||||
},
|
||||
getAlbListenerLogicalId(functionName, idx) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}AlbListener${idx}`;
|
||||
},
|
||||
|
||||
// Permissions
|
||||
getLambdaS3PermissionLogicalId(functionName, bucketName) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}LambdaPermission${this
|
||||
@ -411,4 +419,7 @@ module.exports = {
|
||||
.getNormalizedFunctionName(functionName)}LambdaPermissionCognitoUserPool${
|
||||
this.normalizeNameToAlphaNumericOnly(poolId)}TriggerSource${triggerSource}`;
|
||||
},
|
||||
getLambdaAlbPermissionLogicalId(functionName) {
|
||||
return `${this.getNormalizedFunctionName(functionName)}LambdaPermissionAlb`;
|
||||
},
|
||||
};
|
||||
|
||||
@ -674,6 +674,13 @@ describe('#naming()', () => {
|
||||
'CustomMessage'
|
||||
)).to.equal('FunctionNameLambdaPermissionCognitoUserPoolPool1TriggerSourceCustomMessage');
|
||||
});
|
||||
|
||||
describe('#getLambdaAlbPermissionLogicalId()', () => {
|
||||
it('should normalize the function name', () => {
|
||||
expect(sdk.naming.getLambdaAlbPermissionLogicalId('functionName'))
|
||||
.to.equal('FunctionNameLambdaPermissionAlb');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getQueueLogicalId()', () => {
|
||||
@ -682,4 +689,18 @@ describe('#naming()', () => {
|
||||
.to.equal('FunctionNameEventSourceMappingSQSMyQueue');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getAlbTargetGroupLogicalId()', () => {
|
||||
it('should normalize the function name', () => {
|
||||
expect(sdk.naming.getAlbTargetGroupLogicalId('functionName'))
|
||||
.to.equal('FunctionNameAlbTargetGroup');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getAlbListenerLogicalId()', () => {
|
||||
it('should normalize the function name and add an index', () => {
|
||||
expect(sdk.naming.getAlbListenerLogicalId('functionName', 0))
|
||||
.to.equal('FunctionNameAlbListener0');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
41
lib/plugins/aws/package/compile/events/alb/index.js
Normal file
41
lib/plugins/aws/package/compile/events/alb/index.js
Normal file
@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
const BbPromise = require('bluebird');
|
||||
|
||||
const validate = require('./lib/validate');
|
||||
const compileTargetGroups = require('./lib/targetGroups');
|
||||
const compileListeners = require('./lib/listeners');
|
||||
const compilePermissions = require('./lib/permissions');
|
||||
|
||||
class AwsCompileAlbEvents {
|
||||
constructor(serverless, options) {
|
||||
this.serverless = serverless;
|
||||
this.options = options;
|
||||
this.provider = this.serverless.getProvider('aws');
|
||||
|
||||
Object.assign(
|
||||
this,
|
||||
validate,
|
||||
compileTargetGroups,
|
||||
compileListeners,
|
||||
compilePermissions
|
||||
);
|
||||
|
||||
this.hooks = {
|
||||
'package:compileEvents': () => {
|
||||
this.validated = this.validate();
|
||||
|
||||
if (this.validated.events.length === 0) {
|
||||
return BbPromise.resolve();
|
||||
}
|
||||
|
||||
return BbPromise.bind(this)
|
||||
.then(this.compileTargetGroups)
|
||||
.then(this.compileListeners)
|
||||
.then(this.compilePermissions);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AwsCompileAlbEvents;
|
||||
81
lib/plugins/aws/package/compile/events/alb/index.test.js
Normal file
81
lib/plugins/aws/package/compile/events/alb/index.test.js
Normal file
@ -0,0 +1,81 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const AwsProvider = require('../../../../provider/awsProvider');
|
||||
const AwsCompileAlbEvents = require('./index');
|
||||
const Serverless = require('../../../../../../Serverless');
|
||||
|
||||
describe('AwsCompileAlbEvents', () => {
|
||||
let awsCompileAlbEvents;
|
||||
|
||||
beforeEach(() => {
|
||||
const serverless = new Serverless();
|
||||
const options = {
|
||||
stage: 'dev',
|
||||
region: 'us-east-1',
|
||||
};
|
||||
serverless.setProvider('aws', new AwsProvider(serverless, options));
|
||||
awsCompileAlbEvents = new AwsCompileAlbEvents(serverless, options);
|
||||
});
|
||||
|
||||
describe('#constructor()', () => {
|
||||
let compileTargetGroupsStub;
|
||||
let compileListenersStub;
|
||||
let compilePermissionsStub;
|
||||
|
||||
beforeEach(() => {
|
||||
compileTargetGroupsStub = sinon
|
||||
.stub(awsCompileAlbEvents, 'compileTargetGroups').resolves();
|
||||
compileListenersStub = sinon
|
||||
.stub(awsCompileAlbEvents, 'compileListeners').resolves();
|
||||
compilePermissionsStub = sinon
|
||||
.stub(awsCompileAlbEvents, 'compilePermissions').resolves();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
awsCompileAlbEvents.compileTargetGroups.restore();
|
||||
awsCompileAlbEvents.compileListeners.restore();
|
||||
awsCompileAlbEvents.compilePermissions.restore();
|
||||
});
|
||||
|
||||
it('should have hooks', () => expect(awsCompileAlbEvents.hooks).to.be.not.empty);
|
||||
|
||||
it('should set the provider variable to be an instanceof AwsProvider', () =>
|
||||
expect(awsCompileAlbEvents.provider).to.be.instanceof(AwsProvider));
|
||||
|
||||
describe('"package:compileEvents" promise chain', () => {
|
||||
afterEach(() => {
|
||||
awsCompileAlbEvents.validate.restore();
|
||||
});
|
||||
|
||||
it('should run the promise chain in order', () => {
|
||||
const validateStub = sinon
|
||||
.stub(awsCompileAlbEvents, 'validate').returns({
|
||||
events: [
|
||||
{
|
||||
functionName: 'first',
|
||||
listener: 'HTTPS:443',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-1',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return awsCompileAlbEvents.hooks['package:compileEvents']().then(() => {
|
||||
expect(validateStub.calledOnce).to.be.equal(true);
|
||||
expect(compileTargetGroupsStub.calledAfter(validateStub)).to.be.equal(true);
|
||||
expect(compileListenersStub.calledAfter(compileTargetGroupsStub)).to.be.equal(true);
|
||||
expect(compilePermissionsStub.calledAfter(compileListenersStub)).to.be.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should resolve if no functions are given', () => {
|
||||
awsCompileAlbEvents.serverless.service.functions = {};
|
||||
|
||||
return awsCompileAlbEvents.hooks['package:compileEvents']();
|
||||
});
|
||||
});
|
||||
});
|
||||
52
lib/plugins/aws/package/compile/events/alb/lib/listeners.js
Normal file
52
lib/plugins/aws/package/compile/events/alb/lib/listeners.js
Normal file
@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
const BbPromise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
compileListeners() {
|
||||
this.validated.events.forEach((event, idx) => {
|
||||
const targetGroupLogicalId = this.provider.naming
|
||||
.getAlbTargetGroupLogicalId(event.name);
|
||||
const listenerLogicalId = this.provider.naming
|
||||
.getAlbListenerLogicalId(event.functionName, idx);
|
||||
|
||||
const listener = event.listener;
|
||||
const Protocol = listener.split(':')[0].toUpperCase();
|
||||
const Port = listener.split(':')[1];
|
||||
const LoadBalancerArn = event.loadBalancerArn;
|
||||
const CertificateArn = event.certificateArn || null;
|
||||
|
||||
let Certificates = [];
|
||||
if (CertificateArn) {
|
||||
Certificates = [
|
||||
{
|
||||
CertificateArn,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
|
||||
[listenerLogicalId]: {
|
||||
Type: 'AWS::ElasticLoadBalancingV2::Listener',
|
||||
Properties: {
|
||||
DefaultActions: [
|
||||
{
|
||||
TargetGroupArn: {
|
||||
Ref: targetGroupLogicalId,
|
||||
},
|
||||
Type: 'forward',
|
||||
},
|
||||
],
|
||||
LoadBalancerArn,
|
||||
Certificates,
|
||||
Protocol,
|
||||
Port,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return BbPromise.resolve();
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsCompileAlbEvents = require('../index');
|
||||
const Serverless = require('../../../../../../../Serverless');
|
||||
const AwsProvider = require('../../../../../provider/awsProvider');
|
||||
|
||||
describe('#compileListeners()', () => {
|
||||
let awsCompileAlbEvents;
|
||||
|
||||
beforeEach(() => {
|
||||
const serverless = new Serverless();
|
||||
serverless.setProvider('aws', new AwsProvider(serverless));
|
||||
serverless.service.service = 'some-service';
|
||||
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
|
||||
|
||||
awsCompileAlbEvents = new AwsCompileAlbEvents(serverless);
|
||||
});
|
||||
|
||||
it('should create ELB listener resources', () => {
|
||||
awsCompileAlbEvents.validated = {
|
||||
events: [
|
||||
{
|
||||
functionName: 'first',
|
||||
listener: 'HTTPS:443',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-1',
|
||||
},
|
||||
{
|
||||
functionName: 'second',
|
||||
listener: 'HTTP:80',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
name: 'some-alb-event-2',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return awsCompileAlbEvents.compileListeners().then(() => {
|
||||
const resources = awsCompileAlbEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources;
|
||||
|
||||
expect(resources.FirstAlbListener0).to.deep.equal({
|
||||
Type: 'AWS::ElasticLoadBalancingV2::Listener',
|
||||
Properties: {
|
||||
Certificates: [
|
||||
{
|
||||
CertificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
},
|
||||
],
|
||||
DefaultActions: [
|
||||
{
|
||||
TargetGroupArn: {
|
||||
Ref: 'SomeDashalbDasheventDash1AlbTargetGroup',
|
||||
},
|
||||
Type: 'forward',
|
||||
},
|
||||
],
|
||||
LoadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
Port: '443',
|
||||
Protocol: 'HTTPS',
|
||||
},
|
||||
});
|
||||
expect(resources.SecondAlbListener1).to.deep.equal({
|
||||
Type: 'AWS::ElasticLoadBalancingV2::Listener',
|
||||
Properties: {
|
||||
Certificates: [],
|
||||
DefaultActions: [
|
||||
{
|
||||
TargetGroupArn: {
|
||||
Ref: 'SomeDashalbDasheventDash2AlbTargetGroup',
|
||||
},
|
||||
Type: 'forward',
|
||||
},
|
||||
],
|
||||
LoadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
Port: '80',
|
||||
Protocol: 'HTTP',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const BbPromise = require('bluebird');
|
||||
|
||||
module.exports = {
|
||||
compilePermissions() {
|
||||
this.validated.events.forEach((event) => {
|
||||
const lambdaLogicalId = this.provider.naming.getLambdaLogicalId(event.functionName);
|
||||
|
||||
const albPermissionLogicalId = this.provider.naming
|
||||
.getLambdaAlbPermissionLogicalId(event.functionName);
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
|
||||
[albPermissionLogicalId]: {
|
||||
Type: 'AWS::Lambda::Permission',
|
||||
Properties: {
|
||||
FunctionName: {
|
||||
'Fn::GetAtt': [lambdaLogicalId, 'Arn'],
|
||||
},
|
||||
Action: 'lambda:InvokeFunction',
|
||||
Principal: 'elasticloadbalancing.amazonaws.com',
|
||||
},
|
||||
DependsOn: [lambdaLogicalId],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return BbPromise.resolve();
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,74 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsCompileAlbEvents = require('../index');
|
||||
const Serverless = require('../../../../../../../Serverless');
|
||||
const AwsProvider = require('../../../../../provider/awsProvider');
|
||||
|
||||
describe('#compilePermissions()', () => {
|
||||
let awsCompileAlbEvents;
|
||||
|
||||
beforeEach(() => {
|
||||
const serverless = new Serverless();
|
||||
serverless.setProvider('aws', new AwsProvider(serverless));
|
||||
serverless.service.service = 'some-service';
|
||||
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
|
||||
|
||||
awsCompileAlbEvents = new AwsCompileAlbEvents(serverless);
|
||||
});
|
||||
|
||||
it('should create Lambda permission resources', () => {
|
||||
awsCompileAlbEvents.validated = {
|
||||
events: [
|
||||
{
|
||||
functionName: 'first',
|
||||
listener: 'HTTPS:443',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-1',
|
||||
},
|
||||
{
|
||||
functionName: 'second',
|
||||
listener: 'HTTP:80',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-2',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return awsCompileAlbEvents.compilePermissions().then(() => {
|
||||
const resources = awsCompileAlbEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources;
|
||||
|
||||
expect(resources.FirstLambdaPermissionAlb).to.deep.equal({
|
||||
Type: 'AWS::Lambda::Permission',
|
||||
Properties: {
|
||||
Action: 'lambda:InvokeFunction',
|
||||
FunctionName: {
|
||||
'Fn::GetAtt': [
|
||||
'FirstLambdaFunction',
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
Principal: 'elasticloadbalancing.amazonaws.com',
|
||||
},
|
||||
DependsOn: ['FirstLambdaFunction'],
|
||||
});
|
||||
expect(resources.SecondLambdaPermissionAlb).to.deep.equal({
|
||||
Type: 'AWS::Lambda::Permission',
|
||||
Properties: {
|
||||
Action: 'lambda:InvokeFunction',
|
||||
FunctionName: {
|
||||
'Fn::GetAtt': [
|
||||
'SecondLambdaFunction',
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
Principal: 'elasticloadbalancing.amazonaws.com',
|
||||
},
|
||||
DependsOn: ['SecondLambdaFunction'],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
const BbPromise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
compileTargetGroups() {
|
||||
this.validated.events.forEach((event) => {
|
||||
const targetGroupLogicalId = this.provider.naming
|
||||
.getAlbTargetGroupLogicalId(event.name);
|
||||
const lambdaLogicalId = this.provider.naming
|
||||
.getLambdaLogicalId(event.functionName);
|
||||
const lambdaPermissionLogicalId = this.provider.naming
|
||||
.getLambdaAlbPermissionLogicalId(event.functionName);
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
|
||||
[targetGroupLogicalId]: {
|
||||
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup',
|
||||
Properties: {
|
||||
TargetType: 'lambda',
|
||||
Targets: [
|
||||
{
|
||||
Id: {
|
||||
'Fn::GetAtt': [lambdaLogicalId, 'Arn'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
DependsOn: [lambdaPermissionLogicalId],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return BbPromise.resolve();
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsCompileAlbEvents = require('../index');
|
||||
const Serverless = require('../../../../../../../Serverless');
|
||||
const AwsProvider = require('../../../../../provider/awsProvider');
|
||||
|
||||
describe('#compileTargetGroups()', () => {
|
||||
let awsCompileAlbEvents;
|
||||
|
||||
beforeEach(() => {
|
||||
const serverless = new Serverless();
|
||||
serverless.setProvider('aws', new AwsProvider(serverless));
|
||||
serverless.service.service = 'some-service';
|
||||
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
|
||||
|
||||
awsCompileAlbEvents = new AwsCompileAlbEvents(serverless);
|
||||
});
|
||||
|
||||
it('should create ELB target group resources', () => {
|
||||
awsCompileAlbEvents.validated = {
|
||||
events: [
|
||||
{
|
||||
functionName: 'first',
|
||||
listener: 'HTTPS:443',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-1',
|
||||
},
|
||||
{
|
||||
functionName: 'second',
|
||||
listener: 'HTTP:80',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-2',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return awsCompileAlbEvents.compileTargetGroups().then(() => {
|
||||
const resources = awsCompileAlbEvents.serverless.service.provider
|
||||
.compiledCloudFormationTemplate.Resources;
|
||||
|
||||
expect(resources.SomeDashalbDasheventDash1AlbTargetGroup).to.deep.equal({
|
||||
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup',
|
||||
Properties: {
|
||||
TargetType: 'lambda',
|
||||
Targets: [
|
||||
{
|
||||
Id: {
|
||||
'Fn::GetAtt': [
|
||||
'FirstLambdaFunction',
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
DependsOn: ['FirstLambdaPermissionAlb'],
|
||||
});
|
||||
expect(resources.SomeDashalbDasheventDash2AlbTargetGroup).to.deep.equal({
|
||||
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup',
|
||||
Properties: {
|
||||
TargetType: 'lambda',
|
||||
Targets: [
|
||||
{
|
||||
Id: {
|
||||
'Fn::GetAtt': [
|
||||
'SecondLambdaFunction',
|
||||
'Arn',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
DependsOn: ['SecondLambdaPermissionAlb'],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
31
lib/plugins/aws/package/compile/events/alb/lib/validate.js
Normal file
31
lib/plugins/aws/package/compile/events/alb/lib/validate.js
Normal file
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
validate() {
|
||||
const events = [];
|
||||
|
||||
_.forEach(this.serverless.service.functions, (functionObject, functionName) => {
|
||||
_.forEach(functionObject.events, (event) => {
|
||||
if (_.has(event, 'alb')) {
|
||||
if (_.isObject(event.alb)) {
|
||||
const albObj = {
|
||||
name: event.alb.name,
|
||||
loadBalancerArn: event.alb.loadBalancerArn,
|
||||
certificateArn: event.alb.certificateArn,
|
||||
listener: event.alb.listener,
|
||||
// the following is data which is not defined on the event-level
|
||||
functionName,
|
||||
};
|
||||
events.push(albObj);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
events,
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsCompileAlbEvents = require('../index');
|
||||
const Serverless = require('../../../../../../../Serverless');
|
||||
const AwsProvider = require('../../../../../provider/awsProvider');
|
||||
|
||||
describe('#validate()', () => {
|
||||
let awsCompileAlbEvents;
|
||||
|
||||
beforeEach(() => {
|
||||
const serverless = new Serverless();
|
||||
serverless.setProvider('aws', new AwsProvider(serverless));
|
||||
serverless.service.service = 'some-service';
|
||||
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
|
||||
|
||||
awsCompileAlbEvents = new AwsCompileAlbEvents(serverless);
|
||||
});
|
||||
|
||||
it('should detect alb event definitions', () => {
|
||||
awsCompileAlbEvents.serverless.service.functions = {
|
||||
first: {
|
||||
events: [
|
||||
{
|
||||
alb: {
|
||||
listener: 'HTTPS:443',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-1',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
second: {
|
||||
events: [
|
||||
{
|
||||
alb: {
|
||||
listener: 'HTTP:80',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-2',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const validated = awsCompileAlbEvents.validate();
|
||||
|
||||
expect(validated.events).to.deep.equal([
|
||||
{
|
||||
functionName: 'first',
|
||||
listener: 'HTTPS:443',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-1',
|
||||
},
|
||||
{
|
||||
functionName: 'second',
|
||||
listener: 'HTTP:80',
|
||||
loadBalancerArn: 'arn:aws:elasticloadbalancing:us-east-1:123456:loadbalancer/app/my-load-balancer/50dc6c495c0c9188', // eslint-disable-line
|
||||
certificateArn: 'arn:aws:iam::123456:server-certificate/ProdServerCert',
|
||||
name: 'some-alb-event-2',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@ -90,6 +90,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -99,6 +99,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -90,6 +90,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -87,6 +87,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -98,6 +98,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -98,6 +98,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -98,6 +98,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -84,6 +84,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -84,6 +84,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -84,6 +84,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -84,6 +84,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -84,6 +84,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -80,6 +80,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -89,6 +89,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -89,6 +89,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -89,6 +89,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -89,6 +89,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -89,6 +89,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
@ -86,6 +86,11 @@ functions:
|
||||
# - cognitoUserPool:
|
||||
# pool: MyUserPool
|
||||
# trigger: PreSignUp
|
||||
# - alb:
|
||||
# loadBalancerArn: arn:aws:elasticloadbalancing:us-east-1:XXXXXX:loadbalancer/app/my-load-balancer/50dc6c495c0c9188
|
||||
# certificateArn: arn:aws:iam::XXXXXX:server-certificate/ProdServerCert
|
||||
# name: alb-handler-https
|
||||
# listener: HTTPS:443
|
||||
|
||||
# Define function environment variables here
|
||||
# environment:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user