由于状态机定义错误,无服务器部署失败



我正在尝试使用无服务器部署一个简单的应用程序,但无法完成部署。我收到以下错误:

Serverless Error ---------------------------------------
✕ State machine "checkAirtableSM" definition is invalid:
[{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"http://asl-validator.cloud/fail#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"http://asl-validator.cloud/pass#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"http://asl-validator.cloud/succeed#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"pattern","dataPath":".States['CheckAirtable'].Resource","schemaPath":"http://asl-validator.cloud/task#/properties/Resource/oneOf/0/pattern","params":{"pattern":"^arn:aws:([a-z]|-)+:([a-z]|[0-9]|-)*:[0-9]*:([a-z]|-)+:[a-zA-Z0-9-_.]+(:(\$LATEST|[a-zA-Z0-9-_]+))?$"},"message":"should match pattern "^arn:aws:([a-z]|-)+:([a-z]|[0-9]|-)*:[0-9]*:([a-z]|-)+:[a-zA-Z0-9-_.]+(:(\$LATEST|[a-zA-Z0-9-_]+))?$""},{"keyword":"type","dataPath":".States['CheckAirtable'].Resource","schemaPath":"http://asl-validator.cloud/task#/properties/Resource/oneOf/1/type","params":{"type":"object"},"message":"should be object"},{"keyword":"oneOf","dataPath":".States['CheckAirtable'].Resource","schemaPath":"http://asl-validator.cloud/task#/properties/Resource/oneOf","params":{"passingSchemas":null},"message":"should match exactly one schema in oneOf"},{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"http://asl-validator.cloud/wait#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"additionalProperties","dataPath":".States['CheckAirtable']","schemaPath":"#/additionalProperties","params":{"additionalProperty":"Resource"},"message":"should NOT have additional properties"},{"keyword":"oneOf","dataPath":".States['CheckAirtable']","schemaPath":"#/oneOf","params":{"passingSchemas":null},"message":"should match exactly one schema in oneOf"}]

以下是我的无服务器.yml文件:

# NOTE: update this with your service name
service: scheduler-api
# Create an optimized package for our functions 
package:
individually: true
plugins:
- serverless-bundle # Package our functions with Webpack
- serverless-offline
- serverless-dotenv-plugin # Load .env as environment variables
- serverless-step-functions
- serverless-pseudo-parameters
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: us-east-2
# To load environment variables externally
# rename env.example to .env and uncomment
# the following line. Also, make sure to not
# commit your .env.
#
# These environment variables are made available to our functions
# under process.env.
environment:
airtableBaseId: ${env:AIRTABLE_BASE_ID}
airtableApiKey: ${env:AIRTABLE_API_KEY}
STEP_FUNCTION_ARN: "arn:aws:states:#{AWS::Region}:#{AWS::AccountId}:stateMachine:${self:service}-${self:provider.stage}-scheduleTweetSM"
twitter_consumer_key: ${env:TWITTER_CONSUMER_KEY}
twitter_consumer_secret: ${env:TWITTER_CONSUMER_SECRET}
twitter_access_token_key: ${env:TWITTER_ACCESS_TOKEN_KEY}
twitter_access_token_secret: ${env:TWITTER_ACCESS_TOKEN_SECRET}
functions:
checkairtable:
handler: check.main
pushtweet:
handler: tweet.main
stepFunctions:
validate: true
stateMachines:
checkAirtableSM:
name: AirtableChecker
definition:
Comment: "Checks for posts that are complete and ready to be scheduled for posting in airtable and schedules them."
StartAt: CheckAirtable
States:
CheckAirtable:
Type: Task
Resource: "arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${self:provider.stage}-checkairtable"
End: true
events:
- schedule:
rate: cron(0 0/6 * * ? *)
enabled: true
scheduleTweetSM:
name: TweetScheduler
definition:
Comment: "Waits until the post time, then posts the tweet to Twitter."
StartAt: WaitForPostTime
States:
WaitForPostTime:
Type: Wait
TimestampePath: $.postTime
Next: PushPost
PushPost:
Type: Task
Resource: "arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${self:provider.stage}-pushtweet"
End: true

工作理论是,不知何故,无服务器伪参数没有按预期工作,并且使资源的 arn 畸形,然后抱怨畸形。在字符串被无服务器伪参数替换后,是否可以检查serverless deploy命令为 serverless.yaml 所做的工作?

这里的问题实际上是状态机定义中的validate: true。如果删除它,一切正常。

serverless-step-functions插件的验证阶段在伪参数被评估并替换为其值之前运行。这似乎是这两个插件之间的兼容性错误。


顺便说一句,我还要补充一点,您实际上可以在状态机定义中不使用伪参数。您可以使用Fn::GetAtt获取函数的 ARN。

service: scheduler-api
plugins:
- serverless-step-functions
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: eu-west-2
functions:
checkairtable:
handler: check.main
stepFunctions:
validate: true
stateMachines:
checkAirtableSM:
name: AirtableChecker
definition:
Comment: "Checks for posts that are complete and ready to be scheduled for posting in airtable and schedules them."
StartAt: CheckAirtable
States:
CheckAirtable:
Type: Task
Resource:
Fn::GetAtt: [checkairtable, Arn]
End: true

最新更新