LoginSignup
4
1

More than 1 year has passed since last update.

[AWS SAM]API Gateway + Lambdaでipアドレスを取得する方法

Last updated at Posted at 2023-04-14

はじめに

API GatewayとLambdaを使用して、リクエスト元のIPアドレスを取得する方法を紹介します。
AWS Serverless Application Model(SAM)のテンプレートを使用して、API Gatewayを設定し、OpenAPI(Swagger)を使用してAPIのスキーマを定義します。Lambda関数をデプロイして、API Gatewayに統合します。そして、Lambda関数のコードで、リクエスト元のIPアドレスを取得します。

普通にリクエストを送ってもAPI Gatewayを通してしまうとリクエスト元のIPアドレス取れないので、マッピングテンプレートを使います。その定義も含めてSAMテンプレートに記述します。

SAM template

まず、SAMテンプレートを使用して、API GatewayとLambda関数を設定します。以下は、SAMテンプレートの例です。

template.yaml
Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      OpenApiVersion: 3.0.2
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: ./apigateway.yaml
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      Handler: app.lambda_handler
      Runtime: python3.8
      Policies:
        - AmazonAPIGatewayInvokeFullAccess
      Environment:
        Variables:
          STAGE: prod
      Events:
        MyApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref MyApi
            Path: /myresource
            Method: GET

このSAMテンプレートでは、AWS::Serverless::ApiリソースとAWS::Serverless::Functionリソースが定義されています。API Gatewayの定義には、OpenAPIスキーマが使用されています。x-amazon-apigateway-integrationオブジェクトで、Lambda関数との統合が定義されています。Lambda関数は、AWS::Serverless::Functionリソースで定義され、API Gatewayによって呼び出されます。このLambda関数のコードで、リクエスト元のIPアドレスを取得します。

OpenAPI

SAMテンプレートのAPI Gateway定義には、OpenAPI(Swagger)を使用しています。OpenAPIは、APIのスキーマを定義するためのフレームワークです。以下は、このSAMテンプレートで使用されるOpenAPIの例です。

apigateway.yaml
swagger: "2.0"
info:
  title: "My API"
paths:
  /myresource:
    get:
      responses:
        '200':
          description: "Success"
          content:
            application/json:
              schema:
                type: object
                properties:
                  content:
                    type: string
      x-amazon-apigateway-integration:
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations
        passthroughBehavior: when_no_templates
        httpMethod: GET
        requestTemplates:
          application/json: '{"body": $input.json("$"), "headers": { "X-Forwarded-For": "$context.identity.sourceIp" }}'
        type: aws_proxy

このOpenAPIスキーマでは、/myresourceエンドポイントのGETリクエストが定義されています。このエンドポイントは、API GatewayからLambda関数に統合されています。x-amazon-apigateway-integrationオブジェクトで、Lambda関数の呼び出し方法が定義されています。味噌は"headers": { "X-Forwarded-For": "$context.identity.sourceIp"で、ここでリクエスト元のIPアドレスを渡しています。

Lambda側でevent.requestContext.identity.sourceIpで取得できます。

まとめ

SAM templateって意外に資料が少なくて困ること多いので備忘録的に残しておきます。
ちなみにこの記事はChatGPT3.5使って書いて、ちょっと直しただけなので結構すぐ書けました(便利)
最初はマッピングテンプレートだけコンソールで追加しようと思ったんですが、マッピングテンプレートを追加する場所がわからず、結局templateで書くことにしました。

参考文献

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1