LoginSignup
2
1

More than 1 year has passed since last update.

LambdaでVPC内にあるEC2にmysqldumpを実行しS3にアップロードする

Last updated at Posted at 2021-09-12

やりたいこと

AWSのLambdaを使って、EC2上のMySQLのdumpを取得後、S3にアップロードする。

ポイント

VPC内にあるEC2とVPCの外にあるS3のこの両方にアクセスが必要:writing_hand:
というのがハマりポイントでした。
(これまでLambdaを使ったことなかったのであまりわかってなく、簡単にいけるだろうと思って、何も考えずにやってそれ以外の箇所でも結構ハマりました)

構成図

最終的にはこのようになります。

image.png

手順

1.Lambda Functionを作る

コンソールからLambdaを選択肢、Create Functionで作る。
- Runtimeは、今回Node.jsを選択します。(ここはお好みで)
- Roleは今回新しくLambda用に作成する形にしています。
image.png

2.Lambda スクリプトを実装する

2-1.スクリプト実装

index.js
'use strict';

const aws = require('aws-sdk');
const mysqldump = require('mysqldump');
const fs = require('fs');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
require("date-utils");

var date = new Date();
var timeStamp = date.toFormat('YYYYMMDDHH24MISS');
const dumpFileName = 'dump_' + timeStamp + '.sql';
const dumpPath = '/tmp/' + dumpFileName;

exports.handler = async (event, context) => {

    console.log("start mysqldump");
    console.log('dumpFileName:' + dumpFileName);

    const resultDump = await mysqldump({
    connection: {
        host: process.env.DBHOST,
        user: process.env.DBUSER,
        password: process.env.DBPASS,
        database: process.env.DBNAME,
    },
    dumpToFile: dumpPath,  // Lambda上のサーバにdumpファイルを一時的に置く場所
    });

    console.log("start s3 upload"); 
    var params = {
        Bucket: process.env.BUCKETNAME,
        Key: process.env.BUCKETKEY + dumpFileName,
        Body: fs.readFileSync(dumpPath)
    };

    var resultPutS3 = await s3.putObject(params).promise();
    console.log(resultPutS3);
}

2-2.環境変数設定

上記スクリプト内で process.env.xxxとなっていた箇所です。
Configuration → Enviroment variablesから設定できます。
※Dateのタイムゾーンは日本にしておきたいため、TZでセットしています。(ここは自身の環境に合わせてTZをセットすると良いと思います)

image.png

実行してみる

Codeから、Deployを実施したのち、Testを選択すると実行できます。
image.png

結果

Runtime.ImportModuleError が発生します :sweat:

原因

awsのライブラリ以外は、ローカルからアップロードする必要があるため:writing_hand:
(Lambda初心者の私はこれを知らなかったため、最初はなぜエラーなのかわかりませんでした。。)

2-3. スクリプトに必要なライブラリをアップロード

2-3-1.ローカルでスクリプトとライブラリをZIPで固めたものを作成する

Lambda上のファイルのコピーをlocalに作成します。

-rw-rw-r--@ 1 yukiyoshimura  admin  1090  9 12 14:19 index.js
[yukiyoshimura sample]$ 

aws以外のライブラリをnpmでダウンロードします。

npm install mysqldump
npm install date-utils

zipで固める

[yukiyoshimura sample]$ zip -r ../sample.zip ./

2-3-2.lambdaへアップロードする

以下からアップロードします
image.png
アップロード後
node_modulesディレクトリに必要なライブラリが入った状態でlambdaコンソール上で確認できればOK⬇︎
image.png

再び実行してみる

Time out するけど、 Runtime.ImportModuleError が解消されていれば一旦OKです。

3.LambdaがEC2にアクセスできるようにする

3-1. Lambdaに紐づけているroleに権限を付与する

Configuration → permissions
image.png

以下をセットしておきます。
AWSLambdaVPCAccessExecutionRole
AmazonS3FullAccess
image.png

3-2. lambdaをVPCに登録する

Configuration → VPCを選択
image.png

  • VPCは、アクセスしたいEC2のVPCと同じものをセットします。
  • Subnetは、Lambda用にPrivate Subnetを作ったのでそれをセットしました。
  • Security groupsは、デフォルトのものをそのままセットします。(インバウンドなし、アウトバウンドAll) image.png

4.EC2に対してmysqldumpができるようにする

EC2に関連付けしているSecurity groupのインバウンドに以下を追加する。
Sourceのところは、今回、LambdaでセットしたSecurity Groupと同じものをセットしました。
image.png

5.VPCに登録したlambdaからS3にアクセスできるようにする

S3アクセス用のVPC Endpointの作成

VPC → Endpoints → Create Endpoint
image.png

S3のエンドポイントを作成します。今回は、Gatewayで作成しています。
VPCは、EC2と同じもの。
routetablesは、Lambdaでセットしたsubnetが紐づいているものを指定する。
https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/vpce-gateway.html
image.png

endpointを作成すると、指定したroutetablesにS3へのendpointが追加されます。
image.png

その他

lambdaのタイムアウトはデフォルト3秒なので10秒くらいにしておくと良い

ネットワークのエラーでタイムアウトなのか、処理時間でのタイムアウトなのか見分けがつかない時がありました。
今回のdumpしてからS3へのアップロードだと3秒では終わらなかったので10秒にしました。

Configuration → General configuraton から変更できます。
image.png

MySQLに外から繋ぐため、外部からの接続を許可しておく必要があります

この辺りを参考に。
自分はlambda接続用のユーザを作成しました。
https://qiita.com/yoshiokaCB/items/df4ae185be7cbc4f03ac

まとめ

VPC内へのアクセスと外のアクセスが必要だったため、色々設定が必要でしたが、何とかできました。
VPC Endopointを利用する以外にもNATゲートウェイを使う方法もあるようです。

参考にしたページ
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-vpc.html
https://devlog.arksystems.co.jp/2018/04/04/4807/

2
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
2
1