1
0

More than 3 years have passed since last update.

【AWS】Amazon EFSを作成して、EC2とLambdaから使用する

Posted at

Amazon EFSを作成し、EC2にマウント、Lambdaからアクセスできるようにしてみました。

前提条件

  • VPC、EFS、EC2は同一リージョンに作成する(今回は東京リージョンを使用)
  • LambdaはEFSに到達できるVPCに接続する必要がある
  • プライベートサブネットが作成済みの状態から開始する
  • EC2へSSH接続を行うためのキーペアが作成済みの状態から開始する

この記事のゴール

  • Amazon EFSを作成し、LambdaからEFS内のファイルを操作する
  • EC2にEFSをマウントし、EFS内のファイルを操作する

以下の構成をイメージしています。
aws.png

この記事で扱わないこと

  • VPCの作成方法
  • パブリックサブネット、プライベートサブネットの作成・設定方法
  • EC2インスタンスへのSSH接続方法

必要なもの

  • IAMユーザ

環境情報

# AWSリージョン
東京(ap-northeast-1)

# EC2
AMI:Amazon Linux 2 AMI (HVM), SSD Volume Type

# Lambda
ランタイム:Java 11(Corretto)

手順

AWSコンソールにて作成、設定してみる
 ① セキュリティグループの作成
 ② EFSの作成
 ③ EC2の作成
 ④ Lambdaの作成
 ⑤ EC2から接続
 ⑥ Lambdaから接続

AWSコンソールにて作成、設定してみる

① セキュリティグループの作成

(参考)公式ユーザーガイド - EFSリソースの使用 - セキュリティグループの作成

EC2用のセキュリティグループ

01_EC2sg_in.jpg
02_EC2sg_out.jpg

Lambda用セキュリティグループ

Lambdaにはデフォルトのセキュリティグループを使用するため作成しません。

EFS用セキュリティグループ

EC2用セキュリティグループと、Lambda用セキュリティグループからのインバウンドアクセスを許可します。
03_EFSsg_in.jpg
04_EFSsg_out.jpg

② EFSの作成

(参考)公式ユーザーガイド - EFS リソースの使用 - ファイルシステムの作成
EFSコンソールで「カスタマイズ」を選択してファイルシステムを作成します。
05_EFS_create-customize.jpg

ファイルシステム設定

要件に応じて適宜設定します。
06_EFS_filesystem.jpg

ネットワークアクセス設定

  • VPC:Lambdaを接続するVPCを選択します。(今回はデフォルトVPCを使用)
  • アベイラビリティーゾーン:デフォルトではリージョンの各アベイラビリティーゾーンが選択されています。不要なアベイラビリティゾーンがある場合は削除します。
  • サブネットID:Lambdaを作成するサブネットを選択します。(今回はプライベートサブネットを使用)
  • セキュリティグループ:①で作成したEFS用セキュリティグループを選択します。

06_EFS_network.jpg

ファイルシステムポリシー

EFSファイルシステムへ接続する際に、IAMロールを使用して、読み取り専用アクセス、書き込みアクセス、ルートアクセスなどを許可することができます。
今回はすべてのクライアントへのフルアクセスを許可するため、デフォルトのまま変更しません。
07_EFS_policy.jpg

アクセスポイントの作成

LambdaからEFSへアクセスするために必要なアクセスポイントを作成します。
Lambdaからアクセスする際のユーザIDや、EFSで最初にルートディレクトリパスを作成する際のアクセス権限などを指定できます。
※今回はLambdaからアクセスする際のユーザIDをec2-userとするため、ユーザーID 1000 としていますが、公式ユーザーガイドなどでは 1001 を指定しています。
08_EFS_accesspoint.png

③ EC2の作成

①で作成したEC2用セキュリティグループを適用したEC2インスタンスを作成します。
09_EC2-1a.jpg
今回、キーペアは既存のキーペアを選択します。
10_EC2_keypair.jpg

④ Lambdaの作成

(参考)公式ユーザーガイド - Lambda 関数のファイルシステムアクセスの設定
(参考)公式ユーザーガイド - VPC 内のリソースにアクセスするための Lambda 関数の設定

VPCに接続したLambdaを作成します。
今回は、セキュリティグループにはデフォルトセキュリティグループを指定し、プライベートサブネットを使用しています。
11_Lambda_vpc.jpg
実行ロールに以下のポリシーをアタッチします。

  • AWSLambdaVPCAccessExecutionRole(VPCに接続するため)
  • AmazonElasticFileSystemClientReadWriteAccess(ファイルシステムに接続するため)

13_Lambda_role.jpg
「ファイルシステムの追加」から、②で作成したEFSファイルシステム、アクセスポイントを指定します。
また、Lambda関数からファイルシステムにアクセスする際に使用する /mnt/で始まるローカルマウントパスを設定します。
12_Lambda_filesystem.png

⑤ EC2から接続

EFS マウントヘルパーを使用してEFS ファイルシステムをマウントします。

amazon-efs-utils パッケージのインストール

(参考)公式ユーザーガイド - Amazon Linux で amazon-efs-utils パッケージをインストールする

EC2インスタンスにSSH接続し、以下コマンドでamazon-efs-utilsパッケージをインストールします。
※Amazon Linux以外のLinuxディストリビューションの場合はこちらを参照

コマンド
sudo yum install -y amazon-efs-utils
実行結果(抜粋)
Installed:
  amazon-efs-utils.noarch 0:1.28.2-1.amzn2

Dependency Installed:
  stunnel.x86_64 0:4.56-6.amzn2.0.3

Complete!

EFSをマウント

(参考)公式ユーザーガイド - EFS マウントヘルパーを使用してマウントする

EFSをマウントするディレクトリを作成します。

コマンド
sudo mkdir /mnt/efs

マウント前のファイルシステムを確認します。

コマンド
df -h
実行結果
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        482M     0  482M   0% /dev
tmpfs           492M     0  492M   0% /dev/shm
tmpfs           492M  456K  492M   1% /run
tmpfs           492M     0  492M   0% /sys/fs/cgroup
/dev/xvda1      8.0G  1.4G  6.7G  18% /
tmpfs            99M     0   99M   0% /run/user/0
tmpfs            99M     0   99M   0% /run/user/1000

EFSコンソールにてファイルシステムIDを確認します。
14_EFS_filesystemID.jpg
ファイルシステムをマウントします。

形式
sudo mount -t efs [ファイルシステムID]:/ [ESをマウントするディレクトリ]
コマンド
sudo mount -t efs fs-00945420:/ /mnt/efs

マウント後のファイルシステムを確認します。

コマンド
df -h
実行結果
Filesystem                                      Size  Used Avail Use% Mounted on
devtmpfs                                        482M     0  482M   0% /dev
tmpfs                                           492M     0  492M   0% /dev/shm
tmpfs                                           492M  460K  492M   1% /run
tmpfs                                           492M     0  492M   0% /sys/fs/cgroup
/dev/xvda1                                      8.0G  1.4G  6.7G  18% /
tmpfs                                            99M     0   99M   0% /run/user/0
tmpfs                                            99M     0   99M   0% /run/user/1000
fs-00945420.efs.ap-northeast-1.amazonaws.com:/  8.0E     0  8.0E   0% /mnt/efs

fs-00945420.efs.ap-northeast-1.amazonaws.com:/ が出現し、/mnt/efs にマウントが行えたことが確認できました。

⑥ Lambdaから接続

Lambdaからファイルシステムにファイルを作成し、文字列を書き込み、書き込んだ文字列を読み込みしてみます。

以下のコードを使用します。

Lambda関数のコード
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class EfsTestHandler implements RequestHandler<ScheduledEvent, String> {

    private static final Logger logger = LogManager.getLogger(EfsTestHandler.class);

    @Override
    public String handleRequest(ScheduledEvent event, Context context) {

        // ファイル名
        String filepath = "/mnt/data/LambdaSample.txt";
        // 書き込む文字列
        String str = "This was written from Lambda.";

        File file = new File(filepath);
        // ファイル書き込み
        FileWriter fileWriter;
        try {
            fileWriter = new FileWriter(file);
            file.setExecutable(true);
            fileWriter.write(str);

            fileWriter.close();

        } catch (IOException e) {
            e.printStackTrace();
            return "Error";
        }

        // ファイル読み込み
        FileReader reader;
        try {
            reader = new FileReader(file);
            BufferedReader br = new BufferedReader(reader);

            String readStr = "";
            while ((readStr = br.readLine()) != null) {
                logger.info(readStr);
            }

            br.close();
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
            return "Error";
        } catch (IOException e) {
            e.printStackTrace();
            return "Error";
        }

        return "Complete";
    }
}

Lambda関数をテスト実行します。
ファイルシステムへの接続が成功していれば、実行結果にCompleteと表示され、ログにThis was written from Lambda.と出力されます。
15_Lambda_execute.jpg
Lambdaからファイルシステムへのファイル書き込み、書き込んだファイルの読み込みが行えることが確認できました。

Lambdaから書き込んだファイルを、EC2からも確認してみます。

コマンド
ll /mnt/efs/data
実行結果
-rwxrw-r-- 1 ec2-user ec2-user 29 Feb 14 05:39 LambdaSample.txt

/mnt/efs/data配下に、Lambdaから作成したファイルが存在することが確認できました。
※Lambdaからはアクセスポイントを使用してファイルシステムに接続しているため、Lambda関数内で/mnt/dataと指定することにより、実体としてはEFSの/dataにアクセスしています。

ファイルの中身を確認してみます。

コマンド
cat /mnt/efs/data/LambdaSample.tx
実行結果
This was written from Lambda.

Lambdaから書き込んだ文字列が確認できました。

おわりに

設定、接続はあっけなく完了しました。
しかし、アクセスポイント作成時のPOSIXユーザIDを何にするのが適切か、など
各設定値について把握しきれず、学習が必要です。

CloudFormationを使用しての設定手順や、マウント失敗談、EC2やLambdaからファイル削除しようとしたら失敗した話も記載予定でしたが、長くなったため別記事へ記載したいと思います。

参考

AWS Web Serviceブログ

公式ユーザーガイド

参考にさせていただいた記事

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