{Lambda}チュートリアル: API Gateway で Lambda を使用する

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-apigateway-tutorial.html
https://dev.classmethod.jp/articles/getting-started-with-api-gateway-lambda-integration/


-- 1. コマンド等のインストール

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

aws --version

-- 1.2 jqインストール
sudo yum -y install jq


-- 2. IAMポリシー作成
vim policy01.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1428341300017",
      "Action": [
        "dynamodb:DeleteItem",
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Sid": "",
      "Resource": "*",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Effect": "Allow"
    }
  ]
}

aws iam create-policy \
--policy-name policy01 \
--policy-document file://policy01.json

-- 3. IAMロール作成
vim role01.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

aws iam create-role \
--role-name role01 \
--assume-role-policy-document file://role01.json

-- 4. ポリシーをロールにアタッチ
aws iam attach-role-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01 \
--role-name role01


-- 5. Lambda関数作成

vim test.py

from __future__ import print_function
import boto3
import json
print('Loading function')
def handler(event, context):
    '''Provide an event that contains the following keys:

      - operation: one of the operations in the operations dict below
      - tableName: required for operations that interact with DynamoDB
      - payload: a parameter to pass to the operation being performed
    '''
    #print("Received event: " + json.dumps(event, indent=2))

    operation = event['operation']

    if 'tableName' in event:
        dynamo = boto3.resource('dynamodb').Table(event['tableName'])

    operations = {
        'create': lambda x: dynamo.put_item(**x),
        'read': lambda x: dynamo.get_item(**x),
        'update': lambda x: dynamo.update_item(**x),
        'delete': lambda x: dynamo.delete_item(**x),
        'list': lambda x: dynamo.scan(**x),
        'echo': lambda x: x,
        'ping': lambda x: 'pong'
    }

    if operation in operations:
        return operations[operation](event.get('payload'))
    else:
        raise ValueError('Unrecognized operation "{}"'.format(operation))


chmod 755 test.py
zip test.zip test.py

aws lambda create-function \
--function-name func01 \
--zip-file fileb://test.zip \
--handler test.handler \
--runtime python3.8 \
--role arn:aws:iam::999999999999:role/role01

 

aws lambda list-functions | grep func01

aws lambda get-function --function-name func01

-- 6. 関数をテストする

vim input.txt
{
    "operation": "echo",
    "payload": {
        "somekey1": "somevalue1",
        "somekey2": "somevalue2"
    }
}

aws lambda invoke \
--function-name func01 \
--payload file://input.txt \
output.txt \
--cli-binary-format raw-in-base64-out

AWS CLI バージョン 2 を使用している場合、cli-binary-format オプションが必要です

cat output.txt


-- 7. API Gateway を使用して REST API を作成する

-- 7.1 API を作成する

aws apigateway create-rest-api \
--name api01 \
--description "api01" \
--endpoint-configuration '{"types": ["REGIONAL"]}'

aws apigateway get-rest-apis

aws apigateway get-rest-api \
--rest-api-id 1111111111

 

-- 7.2 API でリソースを作成する
aws apigateway get-resources \
--rest-api-id 1111111111

aws apigateway create-resource \
--rest-api-id 1111111111 \
--parent-id 3333333333 \
--path-part "dynamodbmanager"

 

-- 7.3 リソースに POST メソッドを作成する

aws apigateway put-method \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--authorization-type NONE \
--no-api-key-required \
--request-parameters {}

aws apigateway put-integration \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--type AWS \
--integration-http-method POST \
--content-handling CONVERT_TO_TEXT \
--uri "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:999999999999:function:func01/invocations"

aws apigateway put-integration-response \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--status-code 200 \
--response-templates '{"application/json": ""}'


aws apigateway put-method-response \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--status-code 200 \
--response-models '{"application/json": "Empty"}'

 

aws apigateway get-method \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST

aws apigateway get-integration \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST

aws apigateway get-integration-response \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--status-code 200

aws apigateway get-method-response \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--status-code 200

 

-- 7.4 Lambda関数に権限を追加する

aws lambda add-permission \
--function-name func01 \
--statement-id apigw \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn arn:aws:execute-api:ap-northeast-1:999999999999:1111111111/*/POST/dynamodbmanager

 

aws lambda get-policy \
--function-name func01 | jq -r .Policy  | jq .

 

 

-- 8. DynamoDB テーブルの作成

aws dynamodb create-table \
--table-name tab1 \
--attribute-definitions \
    AttributeName=col1,AttributeType=S \
--key-schema \
    AttributeName=col1,KeyType=HASH \
--billing-mode=PAY_PER_REQUEST


aws dynamodb list-tables
aws dynamodb describe-table --table-name tab1


-- 9. セットアップをテストする

aws apigateway test-invoke-method \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--path-with-query-string '' \
--body '{
  "operation": "create",
  "tableName": "tab1",
  "payload": {
    "Item": {
      "col1": "1234ABCD",
      "number": 5
    }
  }
}'

aws dynamodb scan --table-name tab1

aws apigateway test-invoke-method \
--rest-api-id 1111111111 \
--resource-id 222222 \
--http-method POST \
--path-with-query-string '' \
--body '{
    "operation": "update",
    "tableName": "tab1",
    "payload": {
        "Key": {
            "col1": "1234ABCD"
        },
        "AttributeUpdates": {
            "number": {
                "Value": 10
            }
        }
    }
}'


aws dynamodb scan --table-name tab1


-- 10. クリーンアップ

-- DynamoDB テーブル削除
aws dynamodb list-tables
aws dynamodb delete-table --table-name tab1

 

-- API削除

aws apigateway get-rest-apis

aws apigateway delete-rest-api \
--rest-api-id 1111111111


-- Lambda関数の削除
aws lambda get-function --function-name func01
aws lambda delete-function --function-name func01


-- IAMロールの削除
aws iam list-roles | grep role01

aws iam detach-role-policy \
--role-name role01 \
--policy-arn arn:aws:iam::999999999999:policy/policy01

aws iam delete-role --role-name role01


-- IAMポリシーの削除
aws iam list-policies | grep policy01

aws iam delete-policy \
--policy-arn arn:aws:iam::999999999999:policy/policy01