lambdaからlightsailのmysqlに接続する
目的
golangでsamプロジェクトを作成しています。
lambdaを使用し、DBにRDSを採用する予定でしたが、個人開発でRDSを使用するのはお財布に優しくないです。
検証環境にはlightsailにmysqlをインストールしたものを使用し、本番環境には必要であればRDSを使用する形で実装し、コストを抑えようと考えました。
Lightsailインスタンスの準備
こちらのページへアクセスし、lightsailインスタンスを立ち上げます。
OSにはAmazon Linux2023を選択しました。
インスタンスが立ち上がったのを確認したら、インスタンスを選択し、ネットワーキングタブを開き、静的IPをアタッチします。
Amazon Linux2023へのmysqlインストール
インスタンスに接続し、下記コマンドを実行します。
sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
sudo yum install mysql-community-server
この状態では、まだmysqlは立ち上がりません。
free -h
total used free shared buff/cache available
Mem: 407Mi 209Mi 109Mi 0.0Ki 88Mi 187Mi
Swap: 0B 0B 0B
mysqlが立ち上がらない原因がメモリ不足によるものだと考えられるため、swap領域を作成します。
# swapファイルの作成
sudo fallocate -l 1G /swapfile
# 権限の設定とスワップ領域化
sudo chmod 600 /swapfile
sudo mkswap /swapfile
# swapの永続化
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
この状態で、mysqlを起動し直すと正常に起動すると思います。
# 起動状態確認
sudo systemctl status mysqld
# 再起動
sudo systemctl restart mysqld
mysqlに接続します。
まず、初期パスワードを確認します。
sudo less /var/log/mysqld.log
以下のように記載のある部分がパスワードとなります。
(パスワード部分は、「xxxxxxxxx」でマスクしています)
[Note] [MY-010454] [Server] A temporary password is generated for root@localhost: xxxxxxxxx
mysqlにアクセスします。
mysql -u root -p
# 先ほど取得したパスワードを入力します
Enter password:
初期パスワードの状態で、操作しようとすると、パスワードを変更するよう怒られるため、設定しましょう。
初期状態のパスワードポリシーは下記のようになっています。
show variables like 'validate_password%';
+-------------------------------------------------+--------+
| Variable_name | Value |
+-------------------------------------------------+--------+
| validate_password.changed_characters_percentage | 0 |
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 8 |
| validate_password.mixed_case_count | 1 |
| validate_password.number_count | 1 |
| validate_password.policy | MEDIUM |
| validate_password.special_char_count | 1 |
+-------------------------------------------------+--------+
今回、パスワードポリシーについて詳しく触れませんが、記号を含み、大文字小文字を含み、数字を含む8文字以上のパスワードであれば、問題ないです。
パスワードを「@Password123」とし、設定します。
ALTER USER 'root'@'localhost' IDENTIFIED BY '@Password123';
次に外部からアクセスする際のユーザを作成します。
CREATE USER 'root'@'%' identified by '@Password123';
GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
これで設定は完了です。
DBとの疎通確認
lambdaの処理は下記のようにし、疎通確認をしました。
接続情報は自身のものに置き換えてください。
package main
import (
"database/sql"
"fmt"
"log"
"strings"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
_ "github.com/go-sql-driver/mysql"
)
func handler(r events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
host := "LightsailStaticIp"
database := "YourDatabase"
username := "YourUsername"
password := "YoutPassword"
dataSource := fmt.Sprintf("%s:%s@(%s)/%s?parseTime=true", username, password, host, database)
var db *sql.DB
var err error
db, err = sql.Open("mysql", dataSource)
if err != nil {
fmt.Println(err)
}
rows, err := db.Query("show tables")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var tableNames []string
for rows.Next() {
var tableName string
err := rows.Scan(&tableName)
if err != nil {
log.Fatal(err)
}
tableNames = append(tableNames, tableName)
}
return events.APIGatewayProxyResponse{
Body: strings.Join(tableNames, ","),
StatusCode: 200,
}, nil
}
func main() {
lambda.Start(handler)
}