-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot activate API gateway logs for shared API gateway #7036
Comments
Will be fixed with: #7034 Note, that for shared APIGW, logs need to be configured in place in which APIGW is configured (and not in services which refer to it) |
Yes, that’s what I was trying, see the example above. |
Sorry (I was fast reading) indeed it's a different case, and for your case, bug is here: serverless/lib/plugins/aws/package/compile/events/apiGateway/lib/hack/updateStage.js Line 101 in 0b3f021
Let me prepare PR |
Hi @medikoo , thanks for supplying this fix so soon. However, it's still not working. There is still the issue, that updateStage.js is not called unless I remove this line. I can submit a PR that removes the line but I'm not sure of the implications Even after removing the line, it does not immediately work. The issue is that initially there is no stage - so the log settings cannot be applied. If I deploy the API gateway, then the first service and then the API gateway again, it works. Do you prefer if I create a new issue for this or is it fine to track it in here? |
@tinexw indeed, it shouldn't be like that. It's updateStage logic that should eventually discard changes if it finds no API GW configured and sees no http events. PR to fix it, is very welcome |
Using following
Am I missing something here? If I delete the custom API GW and let serverless create the GW itself, the logging is enabled as expected. |
@lunascat Logging should be set in context of stack with which API Gateway is created. In your case you're referencing an external stack, and in such case Framework does not attempt to tweak logging settings (as that's just not safe). Issue is that Framework doesn't crash with meaningful error on such configuration. if you wish to see that, please open a new bug report |
@medikoo Thanks for the quick reply. The API Gateway is created within the same stack (see Resources part at the end). For me, it looks like the same case as in the original example above, except for the http function part (and the restApi reference in provider.apiGateway). What is the difference from serverless' point of view? |
Then please remove |
So, if I remove shared api-gateway serverless.ymlservice: nodejs-auth-example
provider:
name: aws
runtime: nodejs12.x
stage: ${opt:stage, 'dev'}
region: eu-central-1
logRetentionInDays: 30
apiGateway:
metrics: true
tracing:
apiGateway: true
lambda: true
logs:
restApi: true
functions:
authorizer:
handler: src/functions/authorize.handler
description: Lambda authorizer for the api gateway.
resources:
Resources:
RestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: nodejs-auth-example
Description: API GW with auth to test enabling logging, tracing and metrics
RestApiRoot:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref RestApi
ParentId: !GetAtt RestApi.RootResourceId
PathPart: "test"
ApiAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
AuthorizerResultTtlInSeconds: 3600
IdentitySource: method.request.header.Authorization
Name: authorizer
RestApiId: !Ref RestApi
Type: TOKEN
AuthorizerUri:
!Join [ '', [ arn:aws:apigateway:eu-central-1:lambda:path/2015-03-31/functions/, !GetAtt AuthorizerLambdaFunction.Arn, /invocations ] ]
ApiAuthorizerPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt AuthorizerLambdaFunction.Arn
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
Outputs:
RestApiId:
Value: !Ref RestApi
Export: { Name: "api-gw:RestApiId" }
RestApiRoot:
Value: !Ref RestApiRoot
Export: { Name: "api-gw:RestApiRootId" }
AuthorizerId:
Value: !Ref ApiAuthorizer
Export: { Name: "api-gw:ApiAuthorizer"} service serverless.ymlservice: hello
provider:
name: aws
runtime: nodejs12.x
stage: ${opt:stage, 'dev'}
region: eu-central-1
apiGateway:
restApiId: ${self:custom.restApiId}
restApiRootResourceId: ${self:custom.restApiRootId}
custom:
restApiId: !ImportValue api-gw:RestApiId
restApiRootId: !ImportValue api-gw:RestApiRootId
authorizerId: !ImportValue api-gw:ApiAuthorizer
functions:
hello:
handler: src/functions/handler.hello
description: This is a test lambda to test secured access to API Gateway methods.
events:
- http:
path: /hello
method: get
authorizer:
type: CUSTOM
authorizerId: ${self:custom.authorizerId} Are we supposed to define a custom log ressource in this case, because it's a custom API Gateway, not managed by serverless? On the other hand, the deployment with the defined stage is made by serverless and the stage contains the log settings, so serverless should also apply them. |
@lunascat If I see correctly you miss Note that logging can only be configured on a deployed API Gateway stage (we need a deployment resource there) |
@medikoo Thanks, that works like a charm! For reference, here's the Deployment ressource definition: plugins:
- serverless-plugin-bind-deployment-id
resources:
Resources:
RestApi:
...
RestApiRoot:
...
__deployment__:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref RestApi |
I have hit the same issue. I will attempt to move the logging config to Terraform, as you suggest. It is not straightforward as the log settings are per Stage and Serverless creates the Stage. It would be much better if Serverless raised an error if it is asked to configure an externally provided restApi, if it refuses to do so, rather than silently ignoring these settings. |
That's expected. Logs are turned only, if REST API is created with a stack, and not when you reference an externally setup API (in this case, we do not mess with global settings of it, as all its setting should be set by entity which created it) |
a) I didn't expect it, as the docs don't mention that caveat at all. b) as mentioned above, I can see that this is a reasonable thing to do, but I think serverless should raise a warning or error if it is going to ignore this setting |
@RichardBradley that's a very good points
it's reference of all configuration options. So this configuration as a whole cannot be used. Still I agree that it could be stated here, that setting applies only to API Gateway as created with a stack
I fully agree, I've created a request to improve that: #9139 |
Understood. I couldn't find a doc page about the "logs: restApi:" feature in isolation, just the release announcement.
Thanks |
I am a bit late but have hit this myself, same with the xray tracing. Can someone explain to me why exactly sls considers it unsafe to set logging options? The API gateway is created externally but the logging and tracing options are on a stage, the stage is deployed as part of the sls cloudformation stack, it would seem that anyone creating an api gw externally and then using sls to attach functions would not be attaching them in say, terraform. What is the reasoning behind the decision? It seems for me its actually impossible to get the logging working because the stages are never created by terraform, but the api gateway is. |
@paulalex In Framework, we do not assume that service owns the stage when shared API is used, but that it owns only configured endpoints (and other endpoints for same API and stage may be configured elsewhere). Allowing stage wide settings in such context creates conflict, imagine two different services defining different endpoints, deploying to same stage, but with different logging setup. |
Ok fair point, I didnt realise you could define the stage outside serverless and then deploy functions into it, its not something I considered but would actually get around my issue, thinking about it I could always define the stage inside terraform and knowing I can then attach functions to a stage instead of just an API gateway is great to know! Could you point me at a sample config which demonstrates this by any chance? Right now I pass the API gw details into SSM and then read these into the SLS at deployment time, but I could easily build the stage in terraform and then pass the stage details into SSM. |
I moved my logging config to Terraform and outside of Serverless, but now terraform thinks it owns the "stage" and the "deployment" (these two are linked), so Terraform will roll back the AWS::ApiGateway::Deployment created by Serverless each time it runs. Is there any way to have Serverless use a provided APIG but also to configure logging on the APIG? |
I know this has been closed for awhile but I had a similar error and you should check which was which Aws API type you're using, as how logs are enabled are slightly different between if you're using REST API or HTTP Api. In my case I was using the rest syntax when I needed to be using the http syntax.
This is posted as reference that there is a difference and may be worth checking if someone is struggling |
Hey there, running into the exact same issue, would love if there was a good solution for this? I suppose you could maybe use some lifecycle hooks to prevent terraform from overwriting the sls deployment? Hopefully? Not a pretty solution, even if it did work 😬 Edit: yes i think https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes would do it |
Bug Report
Description
The API gateway log settings are not applied when using a shared API gateway as described here.
serverless.yml
my copying the example from the docs and addedsls deploy
serverless.yml
file?SLS_DEBUG=*
environment variable (e.g.SLS_DEBUG=* serverless deploy
)No difference. However, if I add a http function I can see that the AWS CLI is used to set the log settings. If no http function is defined, updateStage.js is not called.
I tried to remove this line, but then I get
I guess as a workaround I can define my own resources. However, I would gladly submit a PR to allow setting this with the log level properties.
Similar or dependent issues:
The text was updated successfully, but these errors were encountered: