New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - Added support for using an existing ApiGateway #3934

Closed
wants to merge 4 commits into
base: master
from

Conversation

Projects
None yet
@eahefnawy
Member

eahefnawy commented Jul 12, 2017

What did you implement:

Closes #3078
Added support for specifying an existing ApiGateway, and hence sharing this ApiGateway with multiple services. Inspired by @HyperBrain ideas 馃槉

How did you implement it:

Users need to provide a Rest Api Id and Rest Api Root Resource Id for that existing ApiGateway. The framework will use this configuration instead of creating a rest api from scratch.

How can we verify it:

You can provide the new configuration by providing strings directly:

service:
  name: sls-shared-api

provider:
  name: aws
  runtime: nodejs6.10
  apiGatewayRestApiId: 6fyzt1pfpk # can be found in aws console
  apiGatewayRestApiRootResourceId: z5d4qh4oqi # can be found in aws console

functions:
  hello:
    handler: handler.hello
    events:
      - http: POST hello
      - http: POST hello/again

or by using an intrinsic function such as Ref, GetAttr, ImportValue...etc:

service:
  name: sls-shared-api

provider:
  name: aws
  runtime: nodejs6.10
  apiGatewayRestApiId:
    Ref: MySharedApiGatewayRestApi
  apiGatewayRestApiRootResourceId: { 'Fn::GetAtt': [MySharedApiGatewayRestApi, 'RootResourceId'] }
    

functions:
  hello:
    handler: handler.hello
    events:
      - http: POST hello
      - http: POST hello/again

resources:
  Resources:
    MySharedApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: dev-my-shared-api-gateway

Todos:

  • Write tests
  • Write documentation
  • Fix linting errors
  • Make sure code coverage hasn't dropped
  • Provide verification config / commands / resources
  • Enable "Allow edits from maintainers" for this PR
  • Update the messages below

Is this ready for review?: YES
Is it a breaking change?: NO

@eahefnawy eahefnawy added this to the 1.18 milestone Jul 12, 2017

@eahefnawy

This comment has been minimized.

Show comment
Hide comment
@eahefnawy

eahefnawy Jul 12, 2017

Member

One issue I'm having with this PR is that the user has to specify a Rest API Root Resource Id. I was hopping specifying a Rest API Id would be enough, but unfortunately the framework would need to figure out the root resource of that existing API somehow. One solution is to fetch and filter all the APIG resources using the AWS SDK by providing the Rest API Id, but what if the user is not providing the Rest API Id directly but rather with an intrinsic function like Ref or GetAttr.

Another issue, is that multiple services can't have endpoints of the same path. Like the following:

# service A
functions:
  hello:
    handler: handler.hello
    events:
      - http: GET hello
# service B
functions:
  hello:
    handler: handler.hello
    events:
      - http: POST hello

Because the second service would attempt to create that same hello path/resource which is managed by service A stack. So this ends up throwing a "resource of the same parent and path already exists" error. You'd see this error too even when using this PR with one service that is trying to hook up with an existing Rest APIG that has that hello resource already defined.

A possible solution is to, again, using the SDK, only create the hello resource if it does not already exist, but then again, what if the user does not specify the Rest API Id directly?

Member

eahefnawy commented Jul 12, 2017

One issue I'm having with this PR is that the user has to specify a Rest API Root Resource Id. I was hopping specifying a Rest API Id would be enough, but unfortunately the framework would need to figure out the root resource of that existing API somehow. One solution is to fetch and filter all the APIG resources using the AWS SDK by providing the Rest API Id, but what if the user is not providing the Rest API Id directly but rather with an intrinsic function like Ref or GetAttr.

Another issue, is that multiple services can't have endpoints of the same path. Like the following:

# service A
functions:
  hello:
    handler: handler.hello
    events:
      - http: GET hello
# service B
functions:
  hello:
    handler: handler.hello
    events:
      - http: POST hello

Because the second service would attempt to create that same hello path/resource which is managed by service A stack. So this ends up throwing a "resource of the same parent and path already exists" error. You'd see this error too even when using this PR with one service that is trying to hook up with an existing Rest APIG that has that hello resource already defined.

A possible solution is to, again, using the SDK, only create the hello resource if it does not already exist, but then again, what if the user does not specify the Rest API Id directly?

@eahefnawy eahefnawy requested review from laardee and removed request for laardee Jul 12, 2017

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Jul 12, 2017

Member

Path problems / conflicts

Theory and problem analysis

Seen from a higher point of view, each serverless service is an isolated
and integral group of functions, endpoints and resources.

When adding multiple Serverless services to one APIG API this basic concept
should be continued and followed. If we take a look at any API, the concept
of integral groups can only applied to complete hives located somewhere within
the API's path structure.

As a result (keeping consistency) Serverless services should be deployed into their
own hive in existing APIs. The hive must be seen as owned by the service.

Practical solution proposal

Configuration and deployment

Taking the theoretical approach into account, there have to be some additions to the current
PR implementation:

The API hive has to be configured. I would use something like

provider:
  name: aws
  runtime: nodejs6.10
  apiGatewayRestApiId: 6fyzt1pfpk # can be found in aws console
  apiGatewayRootPath: /myteam/v1/apis/accounts

This would mean that the service owns the /myteam/v1/apis/accounts path and Serverless will
prepend this path to all defined http endpoints in the service automatically. Of course it must only
do that if a common ApiId is defined. The behavior without a shared API must not be changed!

It is the user's responsibility to define distinct root paths for the services.

The root path problem

As each service sets a root path, that can have parts in common, another problem arises. These root path
parts can only be defined in one CF stack. Otherwise it would conflict due to existing resources.

Sample:

service A => /myteam/v1/apis/accounts
service B => /myteam/v1/apis/pages
service C => /myteam/v1/tools/editor

In this case the CF resources for /myteam, /myteam/v1, /myteam/v1/tools and /myteam/v1/apis must be defined in the CF template.
From a deployment perspective, the first service that deploys its part of the API has to define these. This leads to races between deployed projects.

The root path solution

So we need a solution for that. After some thinking, the only way to eliminate all possible races, would be to extract all CF path resources for all projects that reference the same API in their configuration
into a separate CF stack. The stack must not be associated with a specific project, but with the API id as multiple independent projects can take part in the deployment.

Let's stick with the example above:

If the first service is deployed, Serverless would check if an API path stack for the given API name already exists.
A suitable name for such a stack would be: sls-api-{apiId}.

Stack does not yet exist

Serverless create the API stack, and the following resources and outputs:

  • RES: AWS::ApiGateway::Resource -> All path resources
  • OUT (exported): Ref: AWS::ApiGateway::API
  • OUT (exported): Ref: All AWS::ApiGateway::Resource
Stack exists

Serverless retrieves the original current CF template of the stack with the getTemplate call and
merges its resources in (deleting its own resources first). It can exactly determine its own resources
by using the apiApiGatewayRootPath.
Then it updates the API stack with the consolidated template.

Further common handling by Serverless

Remove all elements that are now in the API stack from the service CF template and reference the
APIG API export and the APIG::Resource exports of the API stack in the method resources. This will also protect the API stack from deletion as long as there is any service deployed there.

Caveats

  • All path parts (up to the root) that are used by SLS services deployed to the API must be exclusively used by Serverless projects as the CF resources reside in the API stack.

  • Switching a project from API integration to standard and vice versa will need a service removal before.

Open questions

  • Can the API itself be created by the participating services? This would mean that the API is still under
    full control of Serverless and nothing has to be added or created manually. How would the naming of the Api be done in that case? Normally the service name is used.

As always: This behavior should only be triggered if a common API is set in the configuration. Just had a crazy idea: If we had a separate API path stack (only path resources, nothing else) in general, it would solve the resource count exceeded problem automatically (just an idea - open for discussion :-) )

It would be cool if you let me know if I have some errors in my proposal or if something is in there that is not consistent or where is missed important things => is it all BS?

Member

HyperBrain commented Jul 12, 2017

Path problems / conflicts

Theory and problem analysis

Seen from a higher point of view, each serverless service is an isolated
and integral group of functions, endpoints and resources.

When adding multiple Serverless services to one APIG API this basic concept
should be continued and followed. If we take a look at any API, the concept
of integral groups can only applied to complete hives located somewhere within
the API's path structure.

As a result (keeping consistency) Serverless services should be deployed into their
own hive in existing APIs. The hive must be seen as owned by the service.

Practical solution proposal

Configuration and deployment

Taking the theoretical approach into account, there have to be some additions to the current
PR implementation:

The API hive has to be configured. I would use something like

provider:
  name: aws
  runtime: nodejs6.10
  apiGatewayRestApiId: 6fyzt1pfpk # can be found in aws console
  apiGatewayRootPath: /myteam/v1/apis/accounts

This would mean that the service owns the /myteam/v1/apis/accounts path and Serverless will
prepend this path to all defined http endpoints in the service automatically. Of course it must only
do that if a common ApiId is defined. The behavior without a shared API must not be changed!

It is the user's responsibility to define distinct root paths for the services.

The root path problem

As each service sets a root path, that can have parts in common, another problem arises. These root path
parts can only be defined in one CF stack. Otherwise it would conflict due to existing resources.

Sample:

service A => /myteam/v1/apis/accounts
service B => /myteam/v1/apis/pages
service C => /myteam/v1/tools/editor

In this case the CF resources for /myteam, /myteam/v1, /myteam/v1/tools and /myteam/v1/apis must be defined in the CF template.
From a deployment perspective, the first service that deploys its part of the API has to define these. This leads to races between deployed projects.

The root path solution

So we need a solution for that. After some thinking, the only way to eliminate all possible races, would be to extract all CF path resources for all projects that reference the same API in their configuration
into a separate CF stack. The stack must not be associated with a specific project, but with the API id as multiple independent projects can take part in the deployment.

Let's stick with the example above:

If the first service is deployed, Serverless would check if an API path stack for the given API name already exists.
A suitable name for such a stack would be: sls-api-{apiId}.

Stack does not yet exist

Serverless create the API stack, and the following resources and outputs:

  • RES: AWS::ApiGateway::Resource -> All path resources
  • OUT (exported): Ref: AWS::ApiGateway::API
  • OUT (exported): Ref: All AWS::ApiGateway::Resource
Stack exists

Serverless retrieves the original current CF template of the stack with the getTemplate call and
merges its resources in (deleting its own resources first). It can exactly determine its own resources
by using the apiApiGatewayRootPath.
Then it updates the API stack with the consolidated template.

Further common handling by Serverless

Remove all elements that are now in the API stack from the service CF template and reference the
APIG API export and the APIG::Resource exports of the API stack in the method resources. This will also protect the API stack from deletion as long as there is any service deployed there.

Caveats

  • All path parts (up to the root) that are used by SLS services deployed to the API must be exclusively used by Serverless projects as the CF resources reside in the API stack.

  • Switching a project from API integration to standard and vice versa will need a service removal before.

Open questions

  • Can the API itself be created by the participating services? This would mean that the API is still under
    full control of Serverless and nothing has to be added or created manually. How would the naming of the Api be done in that case? Normally the service name is used.

As always: This behavior should only be triggered if a common API is set in the configuration. Just had a crazy idea: If we had a separate API path stack (only path resources, nothing else) in general, it would solve the resource count exceeded problem automatically (just an idea - open for discussion :-) )

It would be cool if you let me know if I have some errors in my proposal or if something is in there that is not consistent or where is missed important things => is it all BS?

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Jul 12, 2017

Member

I have also some thoughts about the retrieval of the root resource idea, but just forgot that to add.... I'll add these here later. Took me more time than expected to write the stuff above 馃槃

Member

HyperBrain commented Jul 12, 2017

I have also some thoughts about the retrieval of the root resource idea, but just forgot that to add.... I'll add these here later. Took me more time than expected to write the stuff above 馃槃

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Jul 12, 2017

Member

@eahefnawy Please let me know what you think After reading my proposal again, I even think this would effort and risk wise fit into a separate plugin.

Member

HyperBrain commented Jul 12, 2017

@eahefnawy Please let me know what you think After reading my proposal again, I even think this would effort and risk wise fit into a separate plugin.

@pmuens pmuens self-requested a review Jul 12, 2017

@kerryhatcher

This comment has been minimized.

Show comment
Hide comment
@kerryhatcher

kerryhatcher Jul 13, 2017

@HyperBrain Your path logic seems sound. Generally, we would have a group of related services centered around a common namespace, and that namespace is handled by a unique team of folks and handled as a unique project. We've run into similar issues with our on-prem microservices solution. In the end, it was resolved by having a couple senior engineers that are somewhat like a domain registrar. They maintain a list of approved namespaces and keep a record of them in a wiki.

I would see something akin to that for a large serverless project (which we want to do). It's not automagic and I think the URL path conflict ("resource of the same parent and path already exists") would just a valid warning to the devs that there is a conflict.

So if we had some theoretical namespaces of "meta" services then:

apiGatewayRootPath: /myatc/
profile service => /myatc/profile
favortes service => /myatc/favortes

apiGatewayRootPath: /autosearch/
findcar service => /autosearch/findcar
details service => /autosearch/deatils/$vin

apiGatewayRootPath: /reviews/
dealer service => /dealer/
car service => /car/

TL;DR; setting some common path to be prepended to all services in a project would be great.

kerryhatcher commented Jul 13, 2017

@HyperBrain Your path logic seems sound. Generally, we would have a group of related services centered around a common namespace, and that namespace is handled by a unique team of folks and handled as a unique project. We've run into similar issues with our on-prem microservices solution. In the end, it was resolved by having a couple senior engineers that are somewhat like a domain registrar. They maintain a list of approved namespaces and keep a record of them in a wiki.

I would see something akin to that for a large serverless project (which we want to do). It's not automagic and I think the URL path conflict ("resource of the same parent and path already exists") would just a valid warning to the devs that there is a conflict.

So if we had some theoretical namespaces of "meta" services then:

apiGatewayRootPath: /myatc/
profile service => /myatc/profile
favortes service => /myatc/favortes

apiGatewayRootPath: /autosearch/
findcar service => /autosearch/findcar
details service => /autosearch/deatils/$vin

apiGatewayRootPath: /reviews/
dealer service => /dealer/
car service => /car/

TL;DR; setting some common path to be prepended to all services in a project would be great.

@eahefnawy

This comment has been minimized.

Show comment
Hide comment
@eahefnawy

eahefnawy Jul 13, 2017

Member

@HyperBrain great write up! Thanks a lot for thinking this through. I do agree with most of what you said, and while I think this could would solve the problems listed above, I'm worried more problems would come out of this not-so-simple solution. For example, I'm worried the deployment speed would suffer significantly by introducing a new stack to be created/updated. I think our current deployment speed is already not so great. Do you think there's a way to get it working without introducing a new stack?

Member

eahefnawy commented Jul 13, 2017

@HyperBrain great write up! Thanks a lot for thinking this through. I do agree with most of what you said, and while I think this could would solve the problems listed above, I'm worried more problems would come out of this not-so-simple solution. For example, I'm worried the deployment speed would suffer significantly by introducing a new stack to be created/updated. I think our current deployment speed is already not so great. Do you think there's a way to get it working without introducing a new stack?

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Jul 13, 2017

Member

I thought quite a long time about solving the path problem. This was the only solution I came to that would solve it without the risk of running into problems. The major problem is imo, that the services are distinct and do not know which resources are used in common, and which aren't. For CF a conflict is a terminating condition, that will abort the deployment if a resource already exists (at least as far as I know). I fully agree that deployment performance is a major point and should not be affected by features that are not used by the majority of users.

If the api root (first path element) - as shown in @kerryhatcher 's comment above - has to be different per service (declared as fixed requirement for the functionality), it would work without a separate stack, but in that case it's the user's responsibility to prevent clashes. Such a definition must be well documented and cannot be checked for compliance automatically by Serverless. That way it could go into the core framework.

For the full fledged solution, a way to go would be to put the common API support into a separate plugin (maybe owned by Serverless to make sure that it always works with the core framework). For these users who make use of it, the decreased deployment speed would be ok in favor of the feature - all others would not experience any worsening.

I think, in the end it comes to the decision - have it with the fixed root path requirement in core, or have it fully configurable in a separate plugin.

Member

HyperBrain commented Jul 13, 2017

I thought quite a long time about solving the path problem. This was the only solution I came to that would solve it without the risk of running into problems. The major problem is imo, that the services are distinct and do not know which resources are used in common, and which aren't. For CF a conflict is a terminating condition, that will abort the deployment if a resource already exists (at least as far as I know). I fully agree that deployment performance is a major point and should not be affected by features that are not used by the majority of users.

If the api root (first path element) - as shown in @kerryhatcher 's comment above - has to be different per service (declared as fixed requirement for the functionality), it would work without a separate stack, but in that case it's the user's responsibility to prevent clashes. Such a definition must be well documented and cannot be checked for compliance automatically by Serverless. That way it could go into the core framework.

For the full fledged solution, a way to go would be to put the common API support into a separate plugin (maybe owned by Serverless to make sure that it always works with the core framework). For these users who make use of it, the decreased deployment speed would be ok in favor of the feature - all others would not experience any worsening.

I think, in the end it comes to the decision - have it with the fixed root path requirement in core, or have it fully configurable in a separate plugin.

@pmuens

pmuens requested changes Jul 17, 2017 edited

Thanks @eahefnawy for kicking off the implementation and thanks @HyperBrain and @kerryhatcher for the in-depth feedback!

I agree that you should be able to use the same path in multiple stacks and prefixing the paths with a Stack related naming sounds like a good solution 馃憤

I share the concerns @eahefnawy has with managing an additional Stack since it introduces more complexity and opens the door for some weird edge cases to pop up.

One thing to keep in mind is that this shared API Gateway will very likely be introduced in a later stage of the respective project. This means that a non-breaking update-path should be essential.


One quick note about the config. I'd propose to use a config like this:

service:
  name: sls-shared-api

provider:
  name: aws
  runtime: nodejs6.10
  apiGateway:
    restApiId: 6fyzt1pfpk
    restApiRootResourceId: z5d4qh4oqi

functions:
  hello:
    handler: handler.hello
    events:
      - http: POST hello
      - http: POST hello/again

So everything nested in apiGateway.

The reason for that is that we have many different API Gateway related config parameters such as usagePlan or apiKeys which will be moved to a apiGateway config section soon. This PR could be a good start to introduce it. A related issue which discusses this nesting for API Gateway config can be found here.

Additionally it would be nice to list this new config in the serverless.yml.md file.

@@ -146,22 +146,11 @@ class AwsProvider {
f()
.then(resolve)
.catch((e) => {
const err = e;
if (err.statusCode === 429) {
if (e.statusCode === 429) {

This comment has been minimized.

@pmuens

pmuens Jul 17, 2017

Member

Can we quick-fix this bug in a separate PR since it's unrelated to the shared API Gateway PR (I can do that since I broke it recently 馃槵).

Edit: Turns out that this is already fixed in master. Rebasing should remove this code from this PR.

@pmuens

pmuens Jul 17, 2017

Member

Can we quick-fix this bug in a separate PR since it's unrelated to the shared API Gateway PR (I can do that since I broke it recently 馃槵).

Edit: Turns out that this is already fixed in master. Rebasing should remove this code from this PR.

@potocnika

This comment has been minimized.

Show comment
Hide comment
@potocnika

potocnika Aug 25, 2017

What's needed to fix the failing builds? Really looking forward to this feature being merged. Can anyone help?

potocnika commented Aug 25, 2017

What's needed to fix the failing builds? Really looking forward to this feature being merged. Can anyone help?

@haines

This comment has been minimized.

Show comment
Hide comment
@haines

haines Aug 25, 2017

Re: the path problem, what if it were possible to specify (and require) that some of the API gateway resources will already exist, as well as the gateway?

Our use case is that we would like to manage the API gateway in Terraform and deploy into it with Serverless (this allows us, among other things, to hook in a custom domain name with Terraform). In that case, it would be simple for us to manage the "root path" resources along with the gateway.

I wonder if it would be sufficient to make that a documented caveat of this feature (if multiple services deployed to the same gateway are to share a root path, then those common resources need to be managed externally)?

haines commented Aug 25, 2017

Re: the path problem, what if it were possible to specify (and require) that some of the API gateway resources will already exist, as well as the gateway?

Our use case is that we would like to manage the API gateway in Terraform and deploy into it with Serverless (this allows us, among other things, to hook in a custom domain name with Terraform). In that case, it would be simple for us to manage the "root path" resources along with the gateway.

I wonder if it would be sufficient to make that a documented caveat of this feature (if multiple services deployed to the same gateway are to share a root path, then those common resources need to be managed externally)?

@ynnr85

This comment has been minimized.

Show comment
Hide comment
@ynnr85

ynnr85 Aug 31, 2017

Any update about it?

ynnr85 commented Aug 31, 2017

Any update about it?

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Aug 31, 2017

Contributor

In our real-world project, because of some bad API design from previous developer, we encounter much conflict of predefined resources

# Service A:
/users/{userId}
/users/{userId}/posts
# Service B:
/users/jobs
/users/{userId}/jobs

So we need more than one root resource. The applicable solution is, define many deployed resource as you can:

provider:
  apiGateway:
    restApiId: abcdef
    restApiRootResourceId: abcxyz
    restApiResources:
      '/users': { Ref: ApiResourceUsers }
      '/users/{userId}': { Ref: ApiResourceUserDetail }

functions:
  userPosts:
    handler: handler.userPosts
    events:
      - http: GET /users/{userId}/posts

  userInfo:
    handler: handler.userInfo
    events:
      - http: GET /users/info

  tags:
    handler: handler.tags
    events:
      - http: GET /tags

Under the hood, the compiler auto generate resource config from root path, then children resources and methods reference the parent ID. In this case, with predefined resources, we can map these paths with resource tree, and ignore creation for them.

If there are other paths that need to be auto-generated, the compiler can still do it. (In this case, path /tags are auto-created, in the same serverless.yml config file )

I can't wait for this PR to be merged, so I checkout @eahefnawy code with some modification. And it run smoothly.

Contributor

hgiasac commented Aug 31, 2017

In our real-world project, because of some bad API design from previous developer, we encounter much conflict of predefined resources

# Service A:
/users/{userId}
/users/{userId}/posts
# Service B:
/users/jobs
/users/{userId}/jobs

So we need more than one root resource. The applicable solution is, define many deployed resource as you can:

provider:
  apiGateway:
    restApiId: abcdef
    restApiRootResourceId: abcxyz
    restApiResources:
      '/users': { Ref: ApiResourceUsers }
      '/users/{userId}': { Ref: ApiResourceUserDetail }

functions:
  userPosts:
    handler: handler.userPosts
    events:
      - http: GET /users/{userId}/posts

  userInfo:
    handler: handler.userInfo
    events:
      - http: GET /users/info

  tags:
    handler: handler.tags
    events:
      - http: GET /tags

Under the hood, the compiler auto generate resource config from root path, then children resources and methods reference the parent ID. In this case, with predefined resources, we can map these paths with resource tree, and ignore creation for them.

If there are other paths that need to be auto-generated, the compiler can still do it. (In this case, path /tags are auto-created, in the same serverless.yml config file )

I can't wait for this PR to be merged, so I checkout @eahefnawy code with some modification. And it run smoothly.

@eahefnawy

This comment has been minimized.

Show comment
Hide comment
@eahefnawy

eahefnawy Sep 1, 2017

Member

thanks for sharing your thoughts @hgiasac 馃槉 ... curious what modification you've added to this PR. We'd probably need them here too

Member

eahefnawy commented Sep 1, 2017

thanks for sharing your thoughts @hgiasac 馃槉 ... curious what modification you've added to this PR. We'd probably need them here too

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Sep 2, 2017

Contributor

@eahefnawy I create a branch in my forked repo, feel free to check it out
https://github.com/hgiasac/serverless/tree/sls-shared-api

The config is same as my early post. I change it from the requested change of @pmuens
You can add many root resource paths. If there is conflict path, we will know specific path where resourceId need to be assigned

Contributor

hgiasac commented Sep 2, 2017

@eahefnawy I create a branch in my forked repo, feel free to check it out
https://github.com/hgiasac/serverless/tree/sls-shared-api

The config is same as my early post. I change it from the requested change of @pmuens
You can add many root resource paths. If there is conflict path, we will know specific path where resourceId need to be assigned

@pmuens

This comment has been minimized.

Show comment
Hide comment
@pmuens

pmuens Sep 2, 2017

Member

@eahefnawy I create a branch in my forked repo, feel free to check it out
https://github.com/hgiasac/serverless/tree/sls-shared-api

The config is same as my early post. I change it from the requested change of @pmuens
You can add many root resource paths. If there is conflict path, we will know specific path where resourceId need to be assigned

Great! Thanks for PRing the changes @hgiasac 馃憤

Member

pmuens commented Sep 2, 2017

@eahefnawy I create a branch in my forked repo, feel free to check it out
https://github.com/hgiasac/serverless/tree/sls-shared-api

The config is same as my early post. I change it from the requested change of @pmuens
You can add many root resource paths. If there is conflict path, we will know specific path where resourceId need to be assigned

Great! Thanks for PRing the changes @hgiasac 馃憤

@pkubat

This comment has been minimized.

Show comment
Hide comment
@pkubat

pkubat Sep 7, 2017

These PR changes do pass test locally with the current master. What is the best means to get this PR updated with the current master? (NOTE: The lint fails due to needing an extra newline in providers). So this can be merged? Thanks!

pkubat commented Sep 7, 2017

These PR changes do pass test locally with the current master. What is the best means to get this PR updated with the current master? (NOTE: The lint fails due to needing an extra newline in providers). So this can be merged? Thanks!

@j0k3r

This comment has been minimized.

Show comment
Hide comment
@j0k3r

j0k3r Sep 7, 2017

Contributor

@pkubat you can create a new branch from shared-api branch, fix the problem and then open a new PR targetting the shared-api branch. When it'll be merged, test will then be ok here.

Contributor

j0k3r commented Sep 7, 2017

@pkubat you can create a new branch from shared-api branch, fix the problem and then open a new PR targetting the shared-api branch. When it'll be merged, test will then be ok here.

@Christoph-Schabert

This comment has been minimized.

Show comment
Hide comment
@Christoph-Schabert

Christoph-Schabert Sep 8, 2017

Would it not be simple to write a custom resource for the API gateway resource resource?
This would check if the path is already created and remove the path if nothing is attached?
This would reduce the complexity a lot and make it simpler until cloudformatation support already existing resources.

I try to create this plugin but I am not very familiar with node is

Christoph-Schabert commented Sep 8, 2017

Would it not be simple to write a custom resource for the API gateway resource resource?
This would check if the path is already created and remove the path if nothing is attached?
This would reduce the complexity a lot and make it simpler until cloudformatation support already existing resources.

I try to create this plugin but I am not very familiar with node is

@pkubat pkubat referenced this pull request Sep 8, 2017

Closed

WIP - Added support for using an existing ApiGateway #4235

5 of 7 tasks complete
@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Sep 9, 2017

Contributor

So have anyone checked out my branch repo (#3934 (comment))? Do you have any feedback about my idea ? Can I create another PR too. Thanks

Contributor

hgiasac commented Sep 9, 2017

So have anyone checked out my branch repo (#3934 (comment))? Do you have any feedback about my idea ? Can I create another PR too. Thanks

@a-panickar

This comment has been minimized.

Show comment
Hide comment
@a-panickar

a-panickar Oct 26, 2017

Getting the following error while deploying with a custom domain using the serverless-domain-manager plugin.

Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template

This is the stack trace:

Error: The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template
    at provider.request.catch (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/lib/validateTemplate.js:25:13)
From previous event:
    at AwsDeploy.validateTemplate (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/lib/validateTemplate.js:20:12)
From previous event:
    at AwsDeploy.BbPromise.bind.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:117:39)
From previous event:
    at Object.aws:deploy:deploy:validateTemplate [as hook] (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:113:10)
    at BbPromise.reduce (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:55)
From previous event:
    at PluginManager.invoke (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:22)
    at PluginManager.spawn (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:254:17)
    at AwsDeploy.BbPromise.bind.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:91:48)
From previous event:
    at Object.deploy:deploy [as hook] (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:87:10)
    at BbPromise.reduce (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:55)
From previous event:
    at PluginManager.invoke (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:22)
    at PluginManager.run (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:261:17)
    at variables.populateService.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/Serverless.js:99:33)
    at runCallback (timers.js:781:20)
    at tryOnImmediate (timers.js:743:5)
    at processImmediate [as _immediateCallback] (timers.js:714:5)
From previous event:
    at Serverless.run (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/Serverless.js:86:74)
    at serverless.init.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/bin/serverless:39:50)
    at <anonymous>
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.6.0
     Serverless Version:     1.23.0


This is what my serverless.yml file looks like:

service: serverlessfw-dtsvc

plugins:
  - authorizer-arn-from-id-plugin
  - serverless-domain-manager

custom:
  appconfig: ${file(../common/appconfig.yml)}
  customDomain:
    domainName: api.######.com
    basePath: ''
    stage: ${self:provider.stage}
    createRoute53Record: true  

provider:
  name: aws
  runtime: ${self:custom.appconfig.LambdaRuntime}
  memorySize: ${self:custom.appconfig.LambdaMemorySize}
  deploymentBucket: ${self:custom.appconfig.DeployS3Bucket}
  versionFunctions: ${self:custom.appconfig.Lambda_Versioning}
  role: 
    Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-lambda-iam-role
  apiGateway:
    restApiId: 
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-id
    restApiRootResourceId:
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-root-resource-id
  stackTags: ${self:custom.appconfig.StandardTags}

functions:
  dt-svc:
    handler: handler.getServerDateTime
    events:
      - http: 
          path: serverdate
          method: get
          authorizer: 
            type: CUSTOM
            authorizerId: 
              Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-authorizer-id
    vpc:
      securityGroupIds: 
        - Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-lambda-sg
      subnetIds: ${self:custom.appconfig.VPCInternalSubnetIDs}

Not sure if i have set this up incorrectly?

a-panickar commented Oct 26, 2017

Getting the following error while deploying with a custom domain using the serverless-domain-manager plugin.

Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template

This is the stack trace:

Error: The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template
    at provider.request.catch (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/lib/validateTemplate.js:25:13)
From previous event:
    at AwsDeploy.validateTemplate (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/lib/validateTemplate.js:20:12)
From previous event:
    at AwsDeploy.BbPromise.bind.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:117:39)
From previous event:
    at Object.aws:deploy:deploy:validateTemplate [as hook] (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:113:10)
    at BbPromise.reduce (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:55)
From previous event:
    at PluginManager.invoke (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:22)
    at PluginManager.spawn (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:254:17)
    at AwsDeploy.BbPromise.bind.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:91:48)
From previous event:
    at Object.deploy:deploy [as hook] (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/plugins/aws/deploy/index.js:87:10)
    at BbPromise.reduce (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:55)
From previous event:
    at PluginManager.invoke (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:242:22)
    at PluginManager.run (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/classes/PluginManager.js:261:17)
    at variables.populateService.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/Serverless.js:99:33)
    at runCallback (timers.js:781:20)
    at tryOnImmediate (timers.js:743:5)
    at processImmediate [as _immediateCallback] (timers.js:714:5)
From previous event:
    at Serverless.run (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/lib/Serverless.js:86:74)
    at serverless.init.then (/Users/ap/Documents/Code/serverlessfw-experiments/serverless-sls-shared-api/bin/serverless:39:50)
    at <anonymous>
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.6.0
     Serverless Version:     1.23.0


This is what my serverless.yml file looks like:

service: serverlessfw-dtsvc

plugins:
  - authorizer-arn-from-id-plugin
  - serverless-domain-manager

custom:
  appconfig: ${file(../common/appconfig.yml)}
  customDomain:
    domainName: api.######.com
    basePath: ''
    stage: ${self:provider.stage}
    createRoute53Record: true  

provider:
  name: aws
  runtime: ${self:custom.appconfig.LambdaRuntime}
  memorySize: ${self:custom.appconfig.LambdaMemorySize}
  deploymentBucket: ${self:custom.appconfig.DeployS3Bucket}
  versionFunctions: ${self:custom.appconfig.Lambda_Versioning}
  role: 
    Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-lambda-iam-role
  apiGateway:
    restApiId: 
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-id
    restApiRootResourceId:
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-root-resource-id
  stackTags: ${self:custom.appconfig.StandardTags}

functions:
  dt-svc:
    handler: handler.getServerDateTime
    events:
      - http: 
          path: serverdate
          method: get
          authorizer: 
            type: CUSTOM
            authorizerId: 
              Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-authorizer-id
    vpc:
      securityGroupIds: 
        - Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-lambda-sg
      subnetIds: ${self:custom.appconfig.VPCInternalSubnetIDs}

Not sure if i have set this up incorrectly?

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Oct 26, 2017

Member

@abhilash80 I think this is your problem:

 apiGateway:
    restApiId: 
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-id
    restApiRootResourceId:
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-root-resource-id

That means that the stack does not contain an ApiGatewayRestApi resource nor an ApiGatewayRootResource on which the plugin might depend. I'm pretty sure that this has to be fixed in the plugin, as the behavior to set a custom APIG API is quite new. BTW: the aws-alias plugin does have the same problem.

So I'd expect that it will take some time until all plugins that modify the APIG parts in the template are all adapted properly. Until then the functionality is only guaranteed to run with vanilla Serverless.

@eahefnawy @pkubat @hgiasac Any opinion here?

Member

HyperBrain commented Oct 26, 2017

@abhilash80 I think this is your problem:

 apiGateway:
    restApiId: 
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-id
    restApiRootResourceId:
      Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-apigw-root-resource-id

That means that the stack does not contain an ApiGatewayRestApi resource nor an ApiGatewayRootResource on which the plugin might depend. I'm pretty sure that this has to be fixed in the plugin, as the behavior to set a custom APIG API is quite new. BTW: the aws-alias plugin does have the same problem.

So I'd expect that it will take some time until all plugins that modify the APIG parts in the template are all adapted properly. Until then the functionality is only guaranteed to run with vanilla Serverless.

@eahefnawy @pkubat @hgiasac Any opinion here?

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Oct 26, 2017

Contributor

@abhilash80 you can check with hard-coded API Gateway ID first. We don't know that referenced AGW resource have exists in CloudFormation stack yet. Did you create AWS::ApiGateway::RestApi API resource and output it before?

Contributor

hgiasac commented Oct 26, 2017

@abhilash80 you can check with hard-coded API Gateway ID first. We don't know that referenced AGW resource have exists in CloudFormation stack yet. Did you create AWS::ApiGateway::RestApi API resource and output it before?

@a-panickar

This comment has been minimized.

Show comment
Hide comment
@a-panickar

a-panickar Oct 26, 2017

@HyperBrain @hgiasac

Appreciate the quick response!

I get the same error with the hard coded values as well - following is the yaml snippet:

  name: aws
  runtime: ${self:custom.appconfig.LambdaRuntime}
  memorySize: ${self:custom.appconfig.LambdaMemorySize}
  deploymentBucket: ${self:custom.appconfig.DeployS3Bucket}
  versionFunctions: ${self:custom.appconfig.Lambda_Versioning}
  role: 
    Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-lambda-iam-role
  apiGateway:
    restApiId: ndxyt6kqv6
    restApiRootResourceId: 66ob90flgk
  stackTags: ${self:custom.appconfig.StandardTags}

The API Gateway has been created in a separate stack and the id's exported as output:

  ApiGatewayRestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: serverlessfw-apigw

Outputs:
  ServerlessFWAPIGWID:
    Description: API Gateway API ID
    Value: 
      Ref: ApiGatewayRestApi
    Export:
      Name:
        Fn::Sub: "${AWS::StackName}-apigw-id"

  # API Gateway Root Resource ID
  ServerlessFWAPIGWRootResourceID:
    Description: API GW Root Resource ID
    Value: !GetAtt ApiGatewayRestApi.RootResourceId
    Export:
      Name:
        Fn::Sub: "${AWS::StackName}-apigw-root-resource-id"

The stack is already provisioned and I can see the exported values in the console:

image

a-panickar commented Oct 26, 2017

@HyperBrain @hgiasac

Appreciate the quick response!

I get the same error with the hard coded values as well - following is the yaml snippet:

  name: aws
  runtime: ${self:custom.appconfig.LambdaRuntime}
  memorySize: ${self:custom.appconfig.LambdaMemorySize}
  deploymentBucket: ${self:custom.appconfig.DeployS3Bucket}
  versionFunctions: ${self:custom.appconfig.Lambda_Versioning}
  role: 
    Fn::ImportValue: ${self:custom.appconfig.CommonStackName}-lambda-iam-role
  apiGateway:
    restApiId: ndxyt6kqv6
    restApiRootResourceId: 66ob90flgk
  stackTags: ${self:custom.appconfig.StandardTags}

The API Gateway has been created in a separate stack and the id's exported as output:

  ApiGatewayRestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: serverlessfw-apigw

Outputs:
  ServerlessFWAPIGWID:
    Description: API Gateway API ID
    Value: 
      Ref: ApiGatewayRestApi
    Export:
      Name:
        Fn::Sub: "${AWS::StackName}-apigw-id"

  # API Gateway Root Resource ID
  ServerlessFWAPIGWRootResourceID:
    Description: API GW Root Resource ID
    Value: !GetAtt ApiGatewayRestApi.RootResourceId
    Export:
      Name:
        Fn::Sub: "${AWS::StackName}-apigw-root-resource-id"

The stack is already provisioned and I can see the exported values in the console:

image

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Oct 26, 2017

Member

@abhilash80 I strongly assume that the domain name plugin depends on an existing APIGateway resource IN the serverless stack (as it needs to reference it) - it injects the domain name mappings into the template and thus creates invalid references (as each other plugin will do that is not yet adapted).

Can you try if it works when you remove the plugin? If this solves the problem, this task has to be explicitly flagged as BREAKING, @horike37 and must be targeted for a major release.

Member

HyperBrain commented Oct 26, 2017

@abhilash80 I strongly assume that the domain name plugin depends on an existing APIGateway resource IN the serverless stack (as it needs to reference it) - it injects the domain name mappings into the template and thus creates invalid references (as each other plugin will do that is not yet adapted).

Can you try if it works when you remove the plugin? If this solves the problem, this task has to be explicitly flagged as BREAKING, @horike37 and must be targeted for a major release.

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Oct 26, 2017

Contributor

I think the issue is in custom domain plugin, because it reference default API Gateway resource that is created automatically by serverless framework. Meanwhile we use another AGW Resource name, default ApiGatewayRestApi resource does not exists in current stack

Contributor

hgiasac commented Oct 26, 2017

I think the issue is in custom domain plugin, because it reference default API Gateway resource that is created automatically by serverless framework. Meanwhile we use another AGW Resource name, default ApiGatewayRestApi resource does not exists in current stack

@a-panickar

This comment has been minimized.

Show comment
Hide comment
@a-panickar

a-panickar Oct 26, 2017

I tried it out and it looks like the problem occurs when the cross-domain plugin is used. Do you guys have any suggestions or workarounds?

I will try starting a thread with the plugin to see what they have to say.

a-panickar commented Oct 26, 2017

I tried it out and it looks like the problem occurs when the cross-domain plugin is used. Do you guys have any suggestions or workarounds?

I will try starting a thread with the plugin to see what they have to say.

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Oct 26, 2017

Member

@abhilash80 I think ALL plugins that modify APIG resources will not work anymore. Imo it will take some time to get them all updated (because that is most likely not that easy - especially as e.g. the owner of the domain mapping resource is then unclear). What if a different service that uses the same API also adds a domain name mapping? This might collide.

Member

HyperBrain commented Oct 26, 2017

@abhilash80 I think ALL plugins that modify APIG resources will not work anymore. Imo it will take some time to get them all updated (because that is most likely not that easy - especially as e.g. the owner of the domain mapping resource is then unclear). What if a different service that uses the same API also adds a domain name mapping? This might collide.

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Oct 26, 2017

Contributor

@abhilash80 You must use the plugin in master serverless.yml project that define ApiGatewayRestApi resource only. No need to re-use it in cross-stack projects. API Gateway is created in master project only. Children projects just reference the master's

It is same for all serverless projects that use plugins related to AGW. API Gateway ID isn't created again in children projects anymore, so we need to initialize the AGW and plugins in master project only

Contributor

hgiasac commented Oct 26, 2017

@abhilash80 You must use the plugin in master serverless.yml project that define ApiGatewayRestApi resource only. No need to re-use it in cross-stack projects. API Gateway is created in master project only. Children projects just reference the master's

It is same for all serverless projects that use plugins related to AGW. API Gateway ID isn't created again in children projects anymore, so we need to initialize the AGW and plugins in master project only

@HyperBrain

This comment has been minimized.

Show comment
Hide comment
@HyperBrain

HyperBrain Oct 26, 2017

Member

@hgiasac But that only works for plugins that are stateless, i.e. do only static things. The majority of plugins will do their operations depending on the project/service they are run in.
However we should streamline a discussion about these incompatibilities and proper solution ideas in this thread - together with the plugin authors. It does not make sense to come up with a solution that fits for plugin A but does not work with the other plugins.
I know that this is a tough thing, but imo it is the only way to resolve it before this gets into master (honestly, I even think that this is kind of blocker for the merge as people will start using the feature as soon as it's in - with the plugins they are currently using).

Member

HyperBrain commented Oct 26, 2017

@hgiasac But that only works for plugins that are stateless, i.e. do only static things. The majority of plugins will do their operations depending on the project/service they are run in.
However we should streamline a discussion about these incompatibilities and proper solution ideas in this thread - together with the plugin authors. It does not make sense to come up with a solution that fits for plugin A but does not work with the other plugins.
I know that this is a tough thing, but imo it is the only way to resolve it before this gets into master (honestly, I even think that this is kind of blocker for the merge as people will start using the feature as soon as it's in - with the plugins they are currently using).

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Oct 26, 2017

Contributor

@HyperBrain you're right. AGW-related plugins need to be update to work if this PR is merged
@abhilash80 Have you tried with my suggestion? Does it work? Just remove the plugin from child AGW projects

Contributor

hgiasac commented Oct 26, 2017

@HyperBrain you're right. AGW-related plugins need to be update to work if this PR is merged
@abhilash80 Have you tried with my suggestion? Does it work? Just remove the plugin from child AGW projects

@a-panickar

This comment has been minimized.

Show comment
Hide comment
@a-panickar

a-panickar Oct 26, 2017

@hgiasac Thanks for the suggestion!

I get the following error when I try to move the custom domain plugin into the master serverless.yml file:

Error: Cannot find AWS::ApiGateway::Deployment Try running sls create_domain first.

And I had run the create-domain command before so the domain is provisioned and initialized.

a-panickar commented Oct 26, 2017

@hgiasac Thanks for the suggestion!

I get the following error when I try to move the custom domain plugin into the master serverless.yml file:

Error: Cannot find AWS::ApiGateway::Deployment Try running sls create_domain first.

And I had run the create-domain command before so the domain is provisioned and initialized.

@aalarcong

This comment has been minimized.

Show comment
Hide comment
@aalarcong

aalarcong Dec 7, 2017

Hello.
Whats the status of this feature?

aalarcong commented Dec 7, 2017

Hello.
Whats the status of this feature?

@a-suenami

This comment has been minimized.

Show comment
Hide comment
@a-suenami

a-suenami Dec 8, 2017

It's been on also my mind. I want this feature.

a-suenami commented Dec 8, 2017

It's been on also my mind. I want this feature.

@fazelmk

This comment has been minimized.

Show comment
Hide comment
@fazelmk

fazelmk Dec 17, 2017

Does it work on this branch?
Tried to use with apiId and didn't work. If it works how I use it?

fazelmk commented Dec 17, 2017

Does it work on this branch?
Tried to use with apiId and didn't work. If it works how I use it?

@hgiasac

This comment has been minimized.

Show comment
Hide comment
@hgiasac

hgiasac Dec 17, 2017

Contributor

@fazelmk You should change to this branch #4247. This feature will be official in version 1.26

Contributor

hgiasac commented Dec 17, 2017

@fazelmk You should change to this branch #4247. This feature will be official in version 1.26

@horike37

This comment has been minimized.

Show comment
Hide comment
@horike37

horike37 Jan 6, 2018

Member

Closing this issue for now since this work in progress on #4247.

Member

horike37 commented Jan 6, 2018

Closing this issue for now since this work in progress on #4247.

@horike37 horike37 closed this Jan 6, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment