Lambdaのhttpsリクエストを試してみる


lambdaがhttpsリクエストに対応したとのことなので試してみました。

https://aws.amazon.com/jp/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/

作成

lambdaの関数をデフォルトのままで作成して、設定のタブに移動すると、「関数 URL - 新規」という項目があるので選択します。

関数URLを作成を選択して、作成していきます。
認証タイプを「AWS_IAM」と「NONE」から選択して、CORSの設定をすれば、URLが公開されます。

NONEのアクセス

「NONE」を設定後、eventにログだけ仕込んでアクセスしてみました。

curl "https://zuksfx3kpofw5jrarpkju3c45u0vztbr.lambda-url.ap-northeast-1.on.aws/test?param=true" \
    -X POST \
    -H "SignatureHeader: XYZ" \
    -H "Content-type: application/json" \
    -d '{"type": "payment-succeeded"}'
  • ログを見た感じでは普通のhttpsのリクエストとして利用できそうな感じに見えます。
{
  version: '2.0',
  routeKey: '$default',
  rawPath: '/test',
  rawQueryString: 'param=true',
  headers: {
    'x-amzn-trace-id': 'Root=1-624e32ed-740a44c5619c101d7e8fd44a',
    'x-forwarded-proto': 'https',
    host: 'zuksfx3kpofw5jrarpkju3c45u0vztbr.lambda-url.ap-northeast-1.on.aws',
    'x-forwarded-port': '443',
    'content-type': 'application/json',
    'x-forwarded-for': 'xxx.xxx.xxx.xxx',
    signatureheader: 'XYZ',
    accept: '*/*',
    'user-agent': 'curl/7.68.0'
  },
  queryStringParameters: { param: 'true' },
  requestContext: {
    accountId: 'anonymous',
    apiId: 'zuksfx3kpofw5jrarpkju3c45u0vztbr',
    domainName: 'zuksfx3kpofw5jrarpkju3c45u0vztbr.lambda-url.ap-northeast-1.on.aws',
    domainPrefix: 'zuksfx3kpofw5jrarpkju3c45u0vztbr',
    http: {
      method: 'POST',
      path: '/test',
      protocol: 'HTTP/1.1',
      sourceIp: 'xxx.xxx.xxx.xxx',
      userAgent: 'curl/7.68.0'
    },
    requestId: '454b3ade-8808-42c2-a65e-b5ed9cc7f1bb',
    routeKey: '$default',
    stage: '$default',
    time: '07/Apr/2022:00:40:13 +0000',
    timeEpoch: 1649292013195
  },
  body: '{"type": "payment-succeeded"}',
  isBase64Encoded: false
}
  • 余談ですが、 Content-type: application/json を付けないでクエリパラメータを付けて実行すると、以下のようなエラーが出ます。また、bodyの中身がbase64になるので注意してください。

{"message":"When Content-Type:application/x-www-form-urlencoded, URL cannot include query-string parameters (after '?'): '/test?param=true'"}

IAMのアクセス

  • IAMに設定して、URLにアクセスすると403のステータスが返ってきます

{"Message":"Forbidden"}

別のlambdaを作成して呼び出してみようと思ったのですがうまくいかず。アクセスできたら更新します。

https://docs.aws.amazon.com/lambda/latest/dg/urls-auth.html

serverless frameworkで試す

serverless frameworkでも対応しているとのことなのでさくっと試してみました。

https://www.serverless.com/blog/aws-lambda-function-urls-with-serverless-framework

まず、テンプレートから作成します。

npx serverless create -t aws-nodejs-typescript -n sls-url-test

serverless frameworkが3.12からの対応なので、修正します。

  "devDependencies": {
-    "@serverless/typescript": "^2.23.0",
+    "@serverless/typescript": "^3.8.0",
    "@types/aws-lambda": "^8.10.71",
    "@types/node": "^14.14.25",
    "json-schema-to-ts": "^1.5.0",
-    "serverless": "^2.23.0",
+    "serverless": "^3.12.0",
    "serverless-webpack": "^5.3.5",
    "ts-loader": "^8.0.15",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "tsconfig-paths-webpack-plugin": "^3.3.0",
    "typescript": "^4.1.3",
    "webpack": "^5.20.2",
    "webpack-node-externals": "^2.5.2"
  },

src/functions/hello/index.tsを修正します

- import schema from './schema';
import { handlerPath } from '@libs/handlerResolver';

export default {
  handler: `${handlerPath(__dirname)}/handler.main`,
+  url: true
-  events: [
-    {
-      http: {
-        method: 'post',
-        path: 'hello',
-        request: {
-          schemas: {
-            'application/json': schema
-          }
-        }
-      }
-    }
-  ]
}

バージョンが3系になるので、serverless.tsを修正します

-  frameworkVersion: '2',
+  frameworkVersion: '3',

準備が整ったのでデプロイします。これで制限のないURLアクセスができるようになります。

npm install
npx serverless deploy