Skip to content

Commit

Permalink
Add support for vpc link integration discussed as part of serverless#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Satyam Shandilya committed Apr 25, 2019
1 parent fdd8335 commit 9b0dcbb
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 6 deletions.
20 changes: 20 additions & 0 deletions docs/providers/aws/events/apigateway.md
Expand Up @@ -1089,6 +1089,26 @@ endpoint of your proxy, and the URI you want to set a proxy to.
Now that you have these two CloudFormation templates defined in your `serverless.yml` file, you can simply run
`serverless deploy` and that will deploy these custom resources for you along with your service and set up a proxy on your Rest API.

## Accessing private resources using VPC Link
If you have an Edge Optimized or Regional API Gateway, you can access the internal VPC resources using VPC Link. Please refer [AWS documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-private-integration.html) to know more about API Gateway private integration.

We can use following configuration to have an http-proxy vpc integration.

```yml
- http:
path: v1/repository
method: get
integration: http-proxy
connectionType: vpc-link
connectionId: "{your-vpc-link-id}"
cors: true
request:
uri: http://www.github.com/v1/repository
method: get

```


## Share API Gateway and API Resources

As your application grows, you will likely need to break it out into multiple, smaller services. By default, each Serverless project generates a new API Gateway. However, you can share the same API Gateway between multiple projects by referencing its REST API ID and Root Resource ID in `serverless.yml` as follows:
Expand Down
Expand Up @@ -81,6 +81,13 @@ module.exports = {
Uri: http.request && http.request.uri,
IntegrationHttpMethod: _.toUpper((http.request && http.request.method) || http.method),
});

if (http.connectionType && http.connectionType === 'VPC_LINK') {
_.assign(integration, {
ConnectionType: http.connectionType,
ConnectionId: http.connectionId,
});
}
} else if (type === 'MOCK') {
// nothing to do but kept here for reference
}
Expand Down
47 changes: 41 additions & 6 deletions lib/plugins/aws/package/compile/events/apiGateway/lib/validate.js
Expand Up @@ -76,14 +76,24 @@ module.exports = {

http.integration = this.getIntegration(http, functionName);

if ((http.integration === 'HTTP' || http.integration === 'HTTP_PROXY') &&
(!http.request || !http.request.uri)) {
const errorMessage = [
`You need to set the request uri when using the ${http.integration} integration.`,
];
throw new this.serverless.classes.Error(errorMessage);
if (http.integration === 'HTTP' || http.integration === 'HTTP_PROXY') {
if (!http.request || !http.request.uri) {
const errorMessage = [
`You need to set the request uri when using the ${http.integration} integration.`,
];
throw new this.serverless.classes.Error(errorMessage);
}

http.connectionType = this.getConnectionType(http, functionName);
if (http.connectionType === 'VPC_LINK' && !http.connectionId) {
const errorMessage = [
`You need to set connectionId when using ${http.connectionType} connectionType.`,
];
throw new this.serverless.classes.Error(errorMessage);
}
}


if (http.integration === 'AWS' || http.integration === 'HTTP') {
http.request = this.getRequest(http);
http.request.passThrough = this.getRequestPassThrough(http);
Expand Down Expand Up @@ -398,6 +408,31 @@ module.exports = {
return 'AWS_PROXY';
},


getConnectionType(http, functionName) {
if (http.connectionType) {
// normalize the connection type for further processing
const normalizedConnectionType = http.connectionType.toUpperCase().replace('-', '_');
const allowedConnectionTypes = [
'VPC_LINK',
];
// check if the user has entered a non-valid integration
if (allowedConnectionTypes.indexOf(normalizedConnectionType) === NOT_FOUND) {
const errorMessage = [
`Invalid APIG connectionType "${http.connectionType}"`,
` in function "${functionName}".`,
' Supported connectionTyps are:',
' vpc-link.',
].join('');
throw new this.serverless.classes.Error(errorMessage);
}
return normalizedConnectionType;
}

return null;
},


getRequest(http) {
if (http.request) {
const request = http.request;
Expand Down
Expand Up @@ -1782,6 +1782,96 @@ describe('#validate()', () => {
expect(validated.events[0].http.request.passThrough).to.equal(undefined);
});

it('should support VPC_LINK integration', () => {
awsCompileApigEvents.serverless.service.functions = {
first: {
events: [
{
http: {
method: 'GET',
path: 'users/list',
integration: 'http-proxy',
connectionType: 'vpc-link',
connectionId: 'deltabravo',
request: {
uri: 'http://my.uri/me',
},
},
},
],
},
};

const validated = awsCompileApigEvents.validate();
expect(validated.events).to.be.an('Array').with.length(1);
expect(validated.events[0].http.connectionType).to.equal('VPC_LINK');
});

it('should throw an error when connectionId is not provided with VPC_LINK', () => {
awsCompileApigEvents.serverless.service.functions = {
first: {
events: [
{
http: {
method: 'GET',
path: 'users/list',
integration: 'http-proxy',
connectionType: 'vpc-link',
request: {
uri: 'http://my.uri/me',
},
},
},
],
},
};

expect(() => awsCompileApigEvents.validate()).to.throw(Error);
});

it('should not show a warning message when using request.parameter with VPC_LINK', () => {
awsCompileApigEvents.serverless.service.functions = {
first: {
events: [
{
http: {
method: 'GET',
path: 'users/list',
integration: 'http-proxy',
connectionType: 'vpc-link',
connectionId: 'deltabravo',
request: {
uri: 'http://www.example.com',
parameters: {
querystrings: {
foo: true,
bar: false,
},
paths: {
foo: true,
bar: false,
},
headers: {
foo: true,
bar: false,
},
},
},
},
},
],
},
};
// initialize so we get the log method from the CLI in place
serverless.init();

const logStub = sinon.stub(serverless.cli, 'log');

awsCompileApigEvents.validate();

expect(logStub.called).to.be.equal(false);
});

it('should set default statusCodes to response for lambda by default', () => {
awsCompileApigEvents.serverless.service.functions = {
first: {
Expand Down

0 comments on commit 9b0dcbb

Please sign in to comment.