jets
jets copied to clipboard
Auto-generated Job Names can lead to invalid permissions
- [X] Upgrade Jets: Are you using the latest version of Jets? This allows Jets to fix issues fast. There's a
jets upgrade
command that makes this a simple task. There's also an Upgrading Guide: http://rubyonjets.com/docs/upgrading/ - [X] Reproducibility: Are you reporting a bug others will be able to reproduce and not asking a question. If you're unsure or want to ask a question, do so on https://community.rubyonjets.com
- [ ] Code sample: Have you put together a code sample to reproduce the issue and make it available? Code samples help speed up fixes dramatically. If it's an easily reproducible issue, then code samples are not needed. If you're unsure, please include a code sample.
My Environment
Software | Version |
---|---|
Operating System | Ubuntu 19.10 |
Jets | 2.3.12 |
Ruby | 2.5 |
Expected Behaviour
When creating a job, I expect it to have a name that matches its permissions.
Current Behavior
The generated function name is missing a letter and doesn't match the permissions to be able to write logs.
Step-by-step reproduction instructions
I have an app called depot-photos, and in it a job called RawFileUploadJob. The autogenerated name is something like depot-photos-api-jets-pro-ProcessRawUploadLambdaFu-ZENAIAQWXNSL
.
It receives permissions to write CloudWatch Logs to arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/depot-photos-api-jets-prod-*
.
The missing d
in prod
in the function name seems to prevent the job from writing logs to CloudWatch: There is no log group created ever for that lambda function. All other functions as generated by routes/controllers work fine.
This also affects jets 2.3.18. Specifically prewarmers and cloudwatch permissions are not granted correctly when the project + controller name is long. In my case a 29 character project name + a 25 character controller#method name combo yielded a result that was too long.
The lack of cloudwatch permissions meant that I was not getting any log output from my controller function.
This is due to a CloudFormation Lambda limit. When the function name is too long, over 64 characters, CloudFormation will fail to deploy.
- CloudFormation Docs: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#aws-resource-lambda-function-properties
The name of the Lambda function, up to 64 characters in length. If you don't specify a name, AWS CloudFormation generates one.
Because of this, when jets builds the CloudFormation it won't explicitly set the function name to a pretty one.
Jets Source Code: https://github.com/boltops-tools/jets/blob/master/lib/jets/resource/lambda/function.rb#L193-L205
If you need your IAM policies to match the friendly, pretty names, believe you have to limit the app method names. It's a bummer 😢 Closing out because don't think there's a way around this.
If you need your IAM policies to match the friendly, pretty names, believe you have to limit the app method names. It's a bummer 😢 Closing out because don't think there's a way around this.
To clarify slightly: the solution is to use cloudformation native functions like Ref
and GetAtt
to pull names / ARNs of AWS objects instead of using ruby-generated names in dependent resources (e.g. an iam policy).
In my case the IAM policy could be written correctly if Jets uses the Ref
or Fn::GetAtt
cloudformation functions, since cloudformation knows the correct name / arn of the function. Further, this approach reduces coupling since now the policy is completely agnostic of the lambda function name.
Interesting. That is possible. Will review and consider PRs. Of course. No sweat either way. 👍
Quite tricky to fix. Details in #645