🐍

AWS LambdaとAPI GatewayをPythonで使ってみる(ついでにRDSも

2023/02/22に公開

前置き

どうも地元の鉄道の廃線を願っている人です。
(帰れない理由作りにもなるからマジで廃線になってほしい)
今日はLambdaを使ってサーバーレスを体験してみます。
ユーザー定義関数さえ理解していれば使えるようなサービスとなっています。
ただAWS Lambdaに合わせてコードを書く必要もあるのが欠点でしょうか
そのかわりコストがかなり低くなるのと他のAWSサービスとの連携がしやすいので
AWSを使うならマスターしておきたいところです。
永年無料枠も用意されているので他のサービスと比べて試しやすい気がします。

関数を作成する

まずはLambdaの画面へ行きます。

次にオレンジ色の「関数を作成」を押します。

・ 関数名 お好みで (日本語不可)
・ ランタイム Python3.9
・ アーキテクチャ x86_64

「基本的な Lambda アクセス権限で新しいロールを作成」 を選択

こんな感じの画面になったら成功です。

すでにサンプルのコードが入力されているのでこのまま次に進みます

LambdaをAPI Gatewayからアクセス出来るようにする

設定 → 関数URL → 関数URLを作成 を順にクリックしていきます。

・認証タイプ NONE

「保存」を押して作成します。

完了するとこんな感じでURLが表示されます(2つとも同じURLです。)

ブラウザからアクセスしてみる

表示されているURLをクリックするとアクセスできます。

出たー!出た! 出たぁ〜

次に前回やったことをLambdaで実現させるために再度RDSを作ります(コストの懸念があって削除したため)

RDSインスタンスを作る

まずはRDSの画面に行きます

次に「データベース」を選択します。

オレンジ色の「データベースの作成」をクリックします。

・ エンジンのオプション Mariadb
・ エンジンバージョン 10.6.10 (お試しなので極端に古くなければ問題無い)

・ テンプレート 開発/テスト
・ DB インスタンス識別子 お好みで
・ マスターユーザー名 お好みで
・ マスターパスワード お好みで


「以前の世代のクラスを含める」 のチェックを入れる
・ DB インスタンスクラス バースト可能クラス (t クラスを含む) db.t2.micro
・ ストレージタイプ 汎用SSD (gpt2)
・ ストレージ割り当て 20 gib
・ ストレージの自動スケーリング ストレージの自動スケーリングを有効にする のチェックを外す

・ 可用性と耐久性 スタンバイインスタンスを作成しないでください

・ コンピューティングリソース EC2 コンピューティングリソースに接続しない
・ ネットワークタイプ IPv4
・ Virtual Private Cloud (VPC) Default VPC
・ DB サブネットグループ Default VPC

・ VPC セキュリティグループ (ファイアウォール) 新規作成
・ 新しい VPC セキュリティグループ名 RDS-SG (分かればなんでも良い)

・ データベース認証 パスワード認証
・ モニタリング 拡張モニタリングの有効化 のチェックを外す

・ 追加設定 「自動バックアップを有効にします」のチェックを外す

最後にオレンジ色の「データベースの作成」を押せば作成出来ます。

待ちます (長い)

こうなればOKです

RDSへ接続する

エンドポイントを確認します。

以下のコマンドで接続します。

mysql -h エンドポイント -u マスターユーザー名 -p

Enter password と表示された後 マスターパスワードを入力してスクショのように入れたらおkです

データベースとテーブルを作る

データベースを作成しテーブルを作ります

CREATE DATABASE test;
use test;
CREATE TABLE body (id int AUTO_INCREMENT, body VARCHAR(100), INDEX(id) );
		    

Query OKと表示されたら問題ないです。

データをINSERTする

INSERT INTO body (body) VALUES ('<br>good aws');

Query OKと表示されたら問題ないです。

SELECT して確認する

SELECT * FROM body;

正しくデータが入っていれば問題ないです。

LambdaからRDSへ接続できるようにする

デフォルトではコンソールマネージャーからインスタンスを作成した際の
指定IPからのアクセスのみ許可しており
同じAWSサービスのLambdaからさえもアクセス出来ません。
なので通信を許可する設定を行います。

まずセキュリティーグループ名をクリックしてセキュリティーグループの画面を開きます。
またここのセキュリティーグループ名は後で必要になるので覚えておきます。
数分後にこのページに戻ってくるのでセキュリティーグループの画面は別タブ推奨

インバウンドルールを編集をクリックします。

ルールーを追加をクリックして
・ タイプ Mysql/Aurora
・ ソース カスタム
・ さっき覚えたセキュリティーグループを入力

オレンジ色の「ルールを保存」を押します。

こんな感じの画面がでたら成功です。

Lambdaの画面へ戻り

今回作った関数を選択し

アクセス制限からロール名をクリックします。

「ポリシーをアタッチ」をクリックします。

検索窓に 「AWSLambdaVPCAccessExecutionRole」と検索してEnterキーを押すと
「AWSLambdaVPCAccessExecutionRole」が出てくるのでチェックをつけて
「ポリシーをアタッチ」をクリックします。

こんな感じの画面になっていたら成功です。

自分が作ったLambda関数の画面に戻り今度は
設定 VPCを選びます。

VPC、サブネット、セキュリティーグループはRDSに画面に戻り ネットワーク欄に表示されているそれぞれの情報を入力します。


入力が完了したらオレンジ色の「保存」を押します

こんな感じの表示になったらOKです

サンプルコードをLambadで動かす

今回のサンプルコードはこれです。

import json
import pymysql

def lambda_handler(event, context):
  connection = pymysql.connect(
      host='goodaws.ap-northeast-1.rds.amazonaws.com',
      user='admin',
      passwd='114514',
      db='test')
  cursor = connection.cursor()
  
  cursor.execute("SELECT * FROM body")
  
  html = """
    <html>
    <head>
        <title> Hello </title>
    </head>
    <body>
        Hello AWS
        {str1}
    </body>
    </html>
  """
  strs = str()
  for i in cursor.fetchall():
    print(i)
    strs += i[1]
  
  
  html = html.replace('{str1}', strs)
  #https://analytics-note.xyz/aws/lambda-function-urls/
  return {
      "headers": {
          "Content-Type": "text/html;charset=utf-8",
      },
      "statusCode": 200,
      "body": html
  }

前回と内容は大まかには同じです。
(タイトルをDBから取ってくる機能が無くなってたり モジュールがpymysqlになってたりしますが
そこは気にしないでください)

「コード」をクリックしてエディターを開きます。

すでに書いてあるサンプルコードを CTAL + A で全範囲選択した後
back spaceで消します。
その後サンプルコードをコピーして貼り付けます。

ソースコードを書き換えた後は必ず「Deploy」を押してください。

ハードコードされた値を書き換える

以下の値を書き換えます。

host= エンドポイント
user= マスターユーザー名
passwd= マスターパスワード


connection = pymysql.connect(
    host='goodaws.ap-northeast-1.rds.amazonaws.com',
    user='admin',
    passwd='114514',
    db='test')
cursor = connection.cursor()

ブラウザからアクセスする(失敗編)

「Deploy」を押したら「関数URL」をクリックしてブラウザで開きます。


出ない!
出ないんですね これが出ないんだなぁー

ログから原因を調べる

Pythonを理解しているみなさんならなんとなくエラー原因は気づいていると思いますが
ログを見る練習だと思って🤫

モニタリング → View CloudWatch logs をクリックします。

一番上のログを押します。

こんな感じでいろいろ書かれています。
それぞれクリックすると詳細なログが見れます。

とりあえずERRORと書いている物をクリックしてみます。

どうやらpymysqlモジュールが無いのが原因のようです。

モジュールをダウンロードする

Lambdaではpipは使えないのでモジュールのインストールは少し面倒です。
場合によっては使えません[1]

まずわかりやすい場所に適当にフォルダを作ります

SHIFTを押しながら右クリックで「PowerShellウィンドウをここで開く」を選択します。

以下のコマンドを実行します。

pip install pymysql -t ./

こんな感じの画面になったら成功です。

送る → 圧縮... でzipにします。

モジュールをアップロードする

Lambdaの画面に戻ります。

レイヤー → 「レイヤーの作成」をクリックします。

・ 名前 pymysql
・ .zipファイルからアップロード
・ アップロード クリックして作成したzipファイルを選択する
・ 互換性のあるランタイム - オプション Python3.9

オレンジ色の「作成」をクリック

こんな感じの画面になったら成功です。

再度今回作った関数を選択し

スクロールして「レイヤーの追加」をクリックします。

・ レイヤーソース カスタムレイヤー
・ pymysql
・ バージョン 1
次にオレンジ色の「追加」を押します。

こんな感じの画面になったら成功です。

ブラウザからアクセスする(成功編)

「関数URL」をクリックしてブラウザで開きます。


出たー!出た! 出たぁ〜

脚注
  1. dockerとか使えばどうにでもなりますが話が長くなるので割愛 ↩︎

Discussion