diff --git a/docs/providers/aws/README.md b/docs/providers/aws/README.md
index 77374cacb..a194ca32b 100644
--- a/docs/providers/aws/README.md
+++ b/docs/providers/aws/README.md
@@ -93,6 +93,7 @@ If you have any questions, [search the forums](https://forum.serverless.com?utm_
Schedule
SNS
SQS
+ ALB
Alexa Skill
Alexa Smart Home
IoT
diff --git a/docs/providers/aws/events/alb.md b/docs/providers/aws/events/alb.md
new file mode 100644
index 000000000..001fa3d78
--- /dev/null
+++ b/docs/providers/aws/events/alb.md
@@ -0,0 +1,47 @@
+
+
+
+### [Read this on the main serverless docs site](https://www.serverless.com/framework/docs/providers/aws/events/alb)
+
+
+# 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
+```
diff --git a/docs/providers/aws/events/alexa-skill.md b/docs/providers/aws/events/alexa-skill.md
index b7355ba09..e4e76acc4 100644
--- a/docs/providers/aws/events/alexa-skill.md
+++ b/docs/providers/aws/events/alexa-skill.md
@@ -1,7 +1,7 @@
diff --git a/docs/providers/aws/events/alexa-smart-home.md b/docs/providers/aws/events/alexa-smart-home.md
index a451a4b2e..cff1a86c1 100644
--- a/docs/providers/aws/events/alexa-smart-home.md
+++ b/docs/providers/aws/events/alexa-smart-home.md
@@ -1,7 +1,7 @@
diff --git a/docs/providers/aws/events/cloudwatch-event.md b/docs/providers/aws/events/cloudwatch-event.md
index fc9d32dfb..0236e6f1b 100644
--- a/docs/providers/aws/events/cloudwatch-event.md
+++ b/docs/providers/aws/events/cloudwatch-event.md
@@ -1,7 +1,7 @@
diff --git a/docs/providers/aws/events/cloudwatch-log.md b/docs/providers/aws/events/cloudwatch-log.md
index 7942545f0..629dc5a35 100644
--- a/docs/providers/aws/events/cloudwatch-log.md
+++ b/docs/providers/aws/events/cloudwatch-log.md
@@ -1,7 +1,7 @@
diff --git a/docs/providers/aws/events/cognito-user-pool.md b/docs/providers/aws/events/cognito-user-pool.md
index 0d2662848..a4751364e 100644
--- a/docs/providers/aws/events/cognito-user-pool.md
+++ b/docs/providers/aws/events/cognito-user-pool.md
@@ -1,7 +1,7 @@
diff --git a/docs/providers/aws/events/iot.md b/docs/providers/aws/events/iot.md
index c927ff832..095b9c2a2 100644
--- a/docs/providers/aws/events/iot.md
+++ b/docs/providers/aws/events/iot.md
@@ -1,7 +1,7 @@
diff --git a/docs/providers/aws/guide/serverless.yml.md b/docs/providers/aws/guide/serverless.yml.md
index ff129c57f..ffc517636 100644
--- a/docs/providers/aws/guide/serverless.yml.md
+++ b/docs/providers/aws/guide/serverless.yml.md
@@ -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
diff --git a/lib/plugins/Plugins.json b/lib/plugins/Plugins.json
index 1e63fd66d..253d0a750 100644
--- a/lib/plugins/Plugins.json
+++ b/lib/plugins/Plugins.json
@@ -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",
diff --git a/lib/plugins/aws/lib/naming.js b/lib/plugins/aws/lib/naming.js
index 694fd1021..c99c5af61 100644
--- a/lib/plugins/aws/lib/naming.js
+++ b/lib/plugins/aws/lib/naming.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`;
+ },
};
diff --git a/lib/plugins/aws/lib/naming.test.js b/lib/plugins/aws/lib/naming.test.js
index 1b10d0198..a96536417 100644
--- a/lib/plugins/aws/lib/naming.test.js
+++ b/lib/plugins/aws/lib/naming.test.js
@@ -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');
+ });
+ });
});
diff --git a/lib/plugins/aws/package/compile/events/alb/index.js b/lib/plugins/aws/package/compile/events/alb/index.js
new file mode 100644
index 000000000..00cc1c54a
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/index.js
@@ -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;
diff --git a/lib/plugins/aws/package/compile/events/alb/index.test.js b/lib/plugins/aws/package/compile/events/alb/index.test.js
new file mode 100644
index 000000000..ba1a8b912
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/index.test.js
@@ -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']();
+ });
+ });
+});
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/listeners.js b/lib/plugins/aws/package/compile/events/alb/lib/listeners.js
new file mode 100644
index 000000000..a852af554
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/listeners.js
@@ -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();
+ },
+};
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/listeners.test.js b/lib/plugins/aws/package/compile/events/alb/lib/listeners.test.js
new file mode 100644
index 000000000..f1796b7a6
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/listeners.test.js
@@ -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',
+ },
+ });
+ });
+ });
+});
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/permissions.js b/lib/plugins/aws/package/compile/events/alb/lib/permissions.js
new file mode 100644
index 000000000..46b6c2426
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/permissions.js
@@ -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();
+ },
+};
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/permissions.test.js b/lib/plugins/aws/package/compile/events/alb/lib/permissions.test.js
new file mode 100644
index 000000000..82f8d3692
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/permissions.test.js
@@ -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'],
+ });
+ });
+ });
+});
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/targetGroups.js b/lib/plugins/aws/package/compile/events/alb/lib/targetGroups.js
new file mode 100644
index 000000000..3f85da001
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/targetGroups.js
@@ -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();
+ },
+};
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/targetGroups.test.js b/lib/plugins/aws/package/compile/events/alb/lib/targetGroups.test.js
new file mode 100644
index 000000000..dd9b28237
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/targetGroups.test.js
@@ -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'],
+ });
+ });
+ });
+});
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/validate.js b/lib/plugins/aws/package/compile/events/alb/lib/validate.js
new file mode 100644
index 000000000..e3102edb1
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/validate.js
@@ -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,
+ };
+ },
+};
diff --git a/lib/plugins/aws/package/compile/events/alb/lib/validate.test.js b/lib/plugins/aws/package/compile/events/alb/lib/validate.test.js
new file mode 100644
index 000000000..8be6969f5
--- /dev/null
+++ b/lib/plugins/aws/package/compile/events/alb/lib/validate.test.js
@@ -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',
+ },
+ ]);
+ });
+});
diff --git a/lib/plugins/create/templates/aws-clojure-gradle/serverless.yml b/lib/plugins/create/templates/aws-clojure-gradle/serverless.yml
index b167892d0..3dd357308 100644
--- a/lib/plugins/create/templates/aws-clojure-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-clojure-gradle/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-clojurescript-gradle/serverless.yml b/lib/plugins/create/templates/aws-clojurescript-gradle/serverless.yml
index a297fee2a..993def7e6 100644
--- a/lib/plugins/create/templates/aws-clojurescript-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-clojurescript-gradle/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-csharp/serverless.yml b/lib/plugins/create/templates/aws-csharp/serverless.yml
index 81c9930c5..48ce3064f 100644
--- a/lib/plugins/create/templates/aws-csharp/serverless.yml
+++ b/lib/plugins/create/templates/aws-csharp/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-fsharp/serverless.yml b/lib/plugins/create/templates/aws-fsharp/serverless.yml
index 2c304a440..4d2757657 100644
--- a/lib/plugins/create/templates/aws-fsharp/serverless.yml
+++ b/lib/plugins/create/templates/aws-fsharp/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-go-dep/serverless.yml b/lib/plugins/create/templates/aws-go-dep/serverless.yml
index b36eca0f8..b8ba76d50 100644
--- a/lib/plugins/create/templates/aws-go-dep/serverless.yml
+++ b/lib/plugins/create/templates/aws-go-dep/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-go-mod/serverless.yml b/lib/plugins/create/templates/aws-go-mod/serverless.yml
index 7cc8abe00..65082379d 100644
--- a/lib/plugins/create/templates/aws-go-mod/serverless.yml
+++ b/lib/plugins/create/templates/aws-go-mod/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-go/serverless.yml b/lib/plugins/create/templates/aws-go/serverless.yml
index fe0c0492a..9ee090fdb 100644
--- a/lib/plugins/create/templates/aws-go/serverless.yml
+++ b/lib/plugins/create/templates/aws-go/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml b/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml
index 27bbd89ba..105257433 100644
--- a/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-groovy-gradle/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-java-gradle/serverless.yml b/lib/plugins/create/templates/aws-java-gradle/serverless.yml
index faff3364a..4d9e011c2 100644
--- a/lib/plugins/create/templates/aws-java-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-java-gradle/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-java-maven/serverless.yml b/lib/plugins/create/templates/aws-java-maven/serverless.yml
index 807128ade..c39589916 100644
--- a/lib/plugins/create/templates/aws-java-maven/serverless.yml
+++ b/lib/plugins/create/templates/aws-java-maven/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-kotlin-jvm-gradle/serverless.yml b/lib/plugins/create/templates/aws-kotlin-jvm-gradle/serverless.yml
index 92bb8538f..973f28286 100644
--- a/lib/plugins/create/templates/aws-kotlin-jvm-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-kotlin-jvm-gradle/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-kotlin-jvm-maven/serverless.yml b/lib/plugins/create/templates/aws-kotlin-jvm-maven/serverless.yml
index 3702074f7..12e4b9fd4 100644
--- a/lib/plugins/create/templates/aws-kotlin-jvm-maven/serverless.yml
+++ b/lib/plugins/create/templates/aws-kotlin-jvm-maven/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-kotlin-nodejs-gradle/serverless.yml b/lib/plugins/create/templates/aws-kotlin-nodejs-gradle/serverless.yml
index a2c045481..e59789ad2 100644
--- a/lib/plugins/create/templates/aws-kotlin-nodejs-gradle/serverless.yml
+++ b/lib/plugins/create/templates/aws-kotlin-nodejs-gradle/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-nodejs/serverless.yml b/lib/plugins/create/templates/aws-nodejs/serverless.yml
index cb2f09e97..15f12f583 100644
--- a/lib/plugins/create/templates/aws-nodejs/serverless.yml
+++ b/lib/plugins/create/templates/aws-nodejs/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-provided/serverless.yml b/lib/plugins/create/templates/aws-provided/serverless.yml
index 90922dea2..757c86e78 100644
--- a/lib/plugins/create/templates/aws-provided/serverless.yml
+++ b/lib/plugins/create/templates/aws-provided/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-python/serverless.yml b/lib/plugins/create/templates/aws-python/serverless.yml
index d77ff1625..7c9111f3f 100644
--- a/lib/plugins/create/templates/aws-python/serverless.yml
+++ b/lib/plugins/create/templates/aws-python/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-python3/serverless.yml b/lib/plugins/create/templates/aws-python3/serverless.yml
index da05941bb..f2e656d84 100644
--- a/lib/plugins/create/templates/aws-python3/serverless.yml
+++ b/lib/plugins/create/templates/aws-python3/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-ruby/serverless.yml b/lib/plugins/create/templates/aws-ruby/serverless.yml
index de18084b9..079186796 100644
--- a/lib/plugins/create/templates/aws-ruby/serverless.yml
+++ b/lib/plugins/create/templates/aws-ruby/serverless.yml
@@ -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:
diff --git a/lib/plugins/create/templates/aws-scala-sbt/serverless.yml b/lib/plugins/create/templates/aws-scala-sbt/serverless.yml
index 1b4684faa..d737b96d6 100644
--- a/lib/plugins/create/templates/aws-scala-sbt/serverless.yml
+++ b/lib/plugins/create/templates/aws-scala-sbt/serverless.yml
@@ -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: