与 CloudFront 分配关联的 Lambda 函数无效或没有所需的权限

问题描述 投票:0回答:3

因此,作为借口,我几乎不知道该怎么办。我研究了大约两个小时,通常我会继续下去,但我发现的信息都没有用。我怀疑这与 YAML (serverless.yml) 文件有关,但我不确定。我对该文件进行了多次更新,因此我将发布初始代码和当前代码,尽管没有任何区别。该代码在开发中完美运行,但在生产中会引发错误。您可以查看 https://www.evote.space 来复制此内容。

当前

myNextApplication:
  service: myService
  component: "@sls-next/[email protected]"
  provider:
    name: aws
    runtime: nodejs12.x
    stage: dev
    profile: evote
    iam:
    role: rolenamegoesherebutnotonstackoverflow
  inputs:
    domain: "evote.space"
  functions:
    createuser:
      handler: data.createuser
    readTable:
      handler: data.readTable
  resources:
    Resources:
      usersTable:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: Users
          AttributeDefinitions:
          - AttributeName: userHash
            AttributeType: N
          KeySchema:
          - AttributeName: userHash
            KeyType: HASH
      votersTable:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: Voters
          AttributeDefinitions:
          - AttributeName: voterHash
            AttributeType: N
          KeySchema:
          - AttributeName: voterHash
            KeyType: HASH
      electionsTable:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: Elections
          AttributeDefinitions:
          - AttributeName: electionHash
            AttributeType: N
          KeySchema:
          - AttributeName: electionHash
            KeyType: HASH
      ballotsTable:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: Ballots
          AttributeDefinitions:
          - AttributeName: ballotHash
            AttributeType: N
          KeySchema:
          - AttributeName: ballotHash
            KeyType: HASH

初始(首次部署时出现错误)

myNextApplication:
  service: myService
  component: "@sls-next/[email protected]"
  provider:
    name: aws
    runtime: nodejs12.x
    stage: dev
    profile: evote
  inputs:
    domain: "evote.space"

我的代码库非常庞大,由许多页面和组件组成。到目前为止,我所做的只是一个登录函数,但在注册页面上,它调用 api 返回用户(用于重复电子邮件验证),它返回我们都太熟悉的错误“意外令牌< in JSON at position 0" if you go back then load the page again you can get the console to reveal a source on that error which reads:

503 错误 该请求无法得到满足。 与 CloudFront 分配关联的 Lambda 函数无效或不具有所需的权限。目前我们无法连接到此应用程序或网站的服务器。可能存在流量过多或配置错误。请稍后重试,或联系应用程序或网站所有者。 如果您通过 CloudFront 向客户提供内容,则可以通过查看 CloudFront 文档找到解决问题的步骤并帮助防止此错误。 由云前端 (CloudFront) 生成 请求 ID:No0_qVJ3gcOpg48rMXqvgyipx4wKWmV-hRewQblZ-loyaaiVJLqGIA==

所以,如果你能帮忙,请帮忙。

编辑: 导致问题的代码是以下块

NewUser.getInitialProps = async ({ req }) => {
  if (req) {
    // this is server side
    return {
      users: await data.readTable("Users")
    };
  } else {
    // we are client side
    const response = await fetch("/api/users");
    return { users: await response.json() };
  }
};

处理这个问题的 api 最初看起来像这样:

import data from "../../../data"

export default async (req, res) => {
  console.log("/api/users HIT!");
  res.status(200).json(await data.readTable("Users"));
};

但我更改了它,以便可以将其标记为 lambda,所以现在它看起来像这样(尽管没有什么区别):

import data from "../../../data";

module.exports.read = async (event, context, callback) => {
  console.log("/api/users HIT!");
  callback(null, {statusCode: 200}).json(await data.readTable("Users"));
}
aws-lambda amazon-cloudfront serverless-framework serverless
3个回答
7
投票

因此,经过仔细研究,我做了以下操作,这显然是一个非常常见的问题,因此我建议其他遇到此问题的人也执行以下操作。请记住,这是针对 serverless-nextjs 组件的,而不仅仅是无服务器框架,尽管同样的情况也适用于那里:

  1. 我仔细研究了存储库自述文件并遵循了所有说明。
  2. 我登录到AWS控制台,发现我认为是主要问题,但实际上是第三个问题; Lambda@Edge 仅配置了基本的 CloudWatch Logging 权限。我使用所有必要的权限更新了它,同时确保最佳实践
  3. 更新 Lambda 后,请确保将其部署到 Lambda@Edge(在“操作”菜单下)
  4. 然后我导航到 CloudWatch 并检查正确区域中的日志,并在调用 API 后发现错误。
  5. 不知何故,我的 DynamoDB 表被删除或未正确复制,因此我使用 npm run infra 及之后从 SDK 重新部署了它们。

有这样的经历总是一件好事。对于代码中真正愚蠢的错误,您绝不是无敌的。 99% 的情况下,如果您陷入困境并认为它很复杂并且解决它是不现实的,请退后一步并问:“这可能是最愚蠢的事情是什么?”

而且总是这样。


1
投票

对我来说,使用Alpha版本的Serverless解决了这个错误消息 '与 CloudFront 分配关联的 Lambda 函数无效或没有所需的权限'

serverless.yml 文件:

# component: "@sls-next/[email protected]"
component: "@sls-next/[email protected]"

我们可以在这里找到最新版本:https://www.npmjs.com/package/@sls-next/serverless-component


0
投票

我遇到这个问题是因为我的 Lambda 代码中存在错误并且失败了。

我检查了 Lambda 函数的 CloudWatch 日志(针对我访问 CloudFront 站点的区域,该区域不是 us-east-1),其中包含错误消息,这让我意识到 Lambda 函数失败并显示错误。

修复错误并让 Lambda@Edge 函数正常运行后,CloudFront 错误就消失了。

我决定创建一个简短的测试文件,可以使用 Node 在我的计算机上本地运行,该文件将测试 Lambda@Edge 函数,以确保它在部署之前正常工作而没有任何错误:

// Run with `node test.mjs`

import test from 'node:test';
import assert from 'node:assert/strict';

import { handler } from './my-lambda-edge-function.mjs';

// Test a URL that returns a HTTP 302 redirect.
async function testRedirect(from, to) {
    const result = await handler({
        Records: [
            {
                cf: {
                    request: {
                        uri: from,
                    },
                },
            },
        ],
    });

    assert(result.status === '302');
    assert(result.headers.location[0].value === to);
}

// Test a URL that returns data from a different upstream file.
async function testMutate(from, to) {
    const result = await handler({
        Records: [
            {
                cf: {
                    request: {
                        uri: from,
                    },
                },
            },
        ],
    });

    assert(result.uri === to);
}

test('Mutations', async () => {
    // Make sure the Lambda@Edge adds 'index.html' onto the end of folders.
    await testMutate('/admin/', '/admin/index.html');

    // Make sure the Lambda@Edge adds '/admin' onto the front of certain URLs.
    await testMutate('/static/images/test.jpg', '/admin/static/images/test.jpg');

    // Make sure '/admin' URLs are left unchanged.
    await testMutate('/admin/templates/default.html', '/admin/templates/default.html');

    // Combination of the above.
    await testMutate('/subscribe/', '/admin/static/subscribe/index.html');
});

test('Redirects', async () => {
    // Make sure requests to the root get HTTP 302 redirected to another URL.
    await testRedirect('/', '/subscribe/');
});
© www.soinside.com 2019 - 2024. All rights reserved.