Open6

localstackを用いてlambdaとrdsを作成してみる

niinii

対戦よろしくお願いします

https://docs.localstack.cloud/getting-started/


$ brew install localstack/tap/localstack-cli
$ localstack --version
3.3.0
localstack start

これだけで立ち上がった。便利。

次にawscli-localを入れる。これを使えばいちいちパラメータを指定しなくてもlocalstackを見に行ってくれるみたい。
awscli-local --version とやらないように注意(2敗)

$ brew install awscli-local
$ awslocal --version
aws-cli/2.9.12 Python/3.9.11 Darwin/23.2.0 exe/x86_64 prompt/off
niinii

lambda

注意点

$ awslocal lambda create-function --function-name auto_webscraping --zip-file fileb://my_deployment_package.zip --handler lambda_function.lambda_handler --runtime python3.9 --role arn:aws:iam::000000000000:role/sample

$ awslocal lambda list-functions
{
    "Functions": [
        {
            "FunctionName": "auto_webscraping",
            "FunctionArn": "arn:aws:lambda:ap-northeast-1:000000000000:function:auto_webscraping",
            "Runtime": "python3.9",
            "Role": "arn:aws:iam::000000000000:role/sample",
            "Handler": "lambda_function.lambda_handler",
            "CodeSize": 21047848,
            "Description": "",
            "Timeout": 3,
            "MemorySize": 128,
            "LastModified": "2024-04-04T10:31:34.442756+0000",
            "CodeSha256": "cxvt7LM6DLhvHZgF2pG47yC5hm9fi2GQg4K2/dk5Tow=",
            "Version": "$LATEST",
            "TracingConfig": {
                "Mode": "PassThrough"
            },
            "RevisionId": "ae9e975c-44ba-4853-88f8-9ac30b6a6b4b",
            "PackageType": "Zip",
            "Architectures": [
                "x86_64"
            ],
            "EphemeralStorage": {
                "Size": 512
            },
            "SnapStart": {
                "ApplyOn": "None",
                "OptimizationStatus": "Off"
            }
        }
    ]
}

思ったより簡単にできた。localstackすごい。
次に実行環境を作成する

involeで実行できる:
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/invoke.html

$ awslocal lambda invoke --function-name arn:aws:lambda:ap-northeast-1:000000000000:function:auto_webscraping ./result.txt
{
    "StatusCode": 200,
    "FunctionError": "Unhandled",
    "ExecutedVersion": "$LATEST"
}

200で帰ってきているため、実行はできてそうだが Unhandled エラーが発生している。
outfile で指定したresult.txt を確認する。

$  cat result.txt 
{"errorMessage": "'bucket'", "errorType": "KeyError", "requestId": "efd78967-e1ad-4142-9283-298ad3f886d6", "stackTrace": ["  File \"/var/task/lambda_function.py\", line 93, in lambda_handler\n    bucket = event[\"bucket\"]\n"]}

lambda内にinputを渡せていないのが原因。

$ awslocal lambda invoke --function-name arn:aws:lambda:ap-northeast-1:000000000000:function:auto_webscraping --payload '{"bucket":"nii-local"}' ./result.txt 

Invalid base64: "{"bucket":"nii-local"}"

base64形式で渡せとのこと。
https://dev.classmethod.jp/articles/aws-cli-v2-blob-default-base64/

$ awslocal lambda invoke --function-name arn:aws:lambda:ap-northeast-1:000000000000:function:auto_webscraping --payload $(echo '{"bucket":"nii-local"}' | base64 ) ./result.txt 

ついでに環境変数もやる

$ awslocal lambda update-function-configuration --function-name auto_webscraping --environment '{"Variables":{"hoge":"piyo"}}'
{
    "FunctionName": "auto_webscraping",
    ...(略)
    "Environment": {
        "Variables": {
            "hoge": "piyo"
        }
    },
    ...(略)
}

これで動いた。
次はつなぎ込みを行うRDSを立ち上げる。

memo: lambda更新したらどうやってuploadするのん
こいつでいけそう
https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-code.html

niinii

RDS

ここみるよ
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/rds/index.html

$ awslocal rds create-db-cluster --db-cluster-identifier rds-local --engine mysql --engine-version 8.0 --database-name english_frequency --master-username hoge --master-user-password hoge

An error occurred (InternalFailure) when calling the CreateDBCluster operation: API for service 'rds' not yet implemented or pro feature - please check https://docs.localstack.cloud/references/coverage/ for further information

pro買えってさ。解散。終わり。終了。完。

API for service 'rds' not yet implemented or pro feature


というわけにもいかないので、localstack EC2にMySQL入れるか、local環境のmysqlに接続するようにしたい。今回は後者で。

niinii

別のmysqlコンテナを立ち上げてみる

docker-compose.ymlに追記した方が早かった

version: '3'

services:
  mysql:
    image: mysql:8.2.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: xxxx
      MYSQL_PASSWORD: xxxx
      MYSQL_ROOT_PASSWORD: xxxx
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Gateway
      - "127.0.0.1:4510-4559:4510-4559"  # external services port range
    environment:
      # LocalStack configuration: https://docs.localstack.cloud/references/configuration/
      - DEBUG=${DEBUG:-0}
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

あとはlambda batchに渡すhostをmysqlにすればOK!
私のlambdaソースは環境変数から取得するようにしているので、下記のようにlambdaを修正。ついでにタイムアウトも伸ばしまくり

awslocal lambda update-function-configuration --function-name auto_webscraping --environment '{"Variables":{"host":"mysql"}}' --timeout 300