Serverless框架下如何动态获取SNS Topic ARN并配置Lambda写入权限?
Great question! Let's tackle both of your issues one by one:
1. Dynamically Fetch SNS Topic ARN in Code
Hardcoding ARNs is never a good practice—Serverless makes it easy to inject this value dynamically using environment variables. Here's how to update your serverless.yml:
Modify your graphql function definition to include an environment variable that references the auto-created SNS Topic ARN:
functions: graphql: handler: dist/app.handler environment: CONVERT_TEXT_TO_SPEECH_TOPIC_ARN: !Ref ConvertTextToSpeachTopic events: - http: path: graphql method: post cors: true convertTextToSpeach: handler: dist/tasks/convertTextToSpeach.handler events: - sns: topicName: convertTextToSpeach displayName: Convert text to speach
The !Ref ConvertTextToSpeachTopic is a CloudFormation reference that points to the ARN of the SNS Topic created by your convertTextToSpeach function's SNS event. Serverless automatically generates this logical ID based on the topic name.
Then in your GraphQL Lambda code, replace the hardcoded ARN with the environment variable:
const params = { Message: 'Test', Subject: 'Test SNS from lambda', TopicArn: process.env.CONVERT_TEXT_TO_SPEECH_TOPIC_ARN } await sns.publish(params).promise()
2. Grant SNS Publish Permission to the GraphQL Lambda
Your GraphQL Lambda needs explicit IAM permissions to publish messages to the SNS Topic. You can add this in the provider section of your serverless.yml under iamRoleStatements:
provider: name: aws runtime: nodejs6.10 iamRoleStatements: - Effect: Allow Action: - sns:Publish Resource: !Ref ConvertTextToSpeachTopic plugins: - serverless-offline
This statement grants the sns:Publish action specifically to your SNS Topic (using the same !Ref as before), ensuring the permission follows the principle of least privilege.
Alternatively, if you want to scope the permission only to the graphql function (instead of all functions in the service), you can add iamRoleStatements directly under the graphql function definition:
functions: graphql: handler: dist/app.handler environment: CONVERT_TEXT_TO_SPEECH_TOPIC_ARN: !Ref ConvertTextToSpeachTopic iamRoleStatements: - Effect: Allow Action: - sns:Publish Resource: !Ref ConvertTextToSpeachTopic events: - http: path: graphql method: post cors: true
Either approach will resolve the permission issue—pick the one that best fits your security requirements.
内容的提问来源于stack exchange,提问作者user606521

