LoginSignup
6
4

More than 3 years have passed since last update.

Amplify FuctionからStorageのファイルを操作する

Posted at

はじめに

この記事はAmplify Functionから、Amplify Storageのファイルを操作する方法を共有するためのものです。

対象とする読者

  • AWSを使ったことがある
  • AmplifyのGetting startedを完了した
  • Amplifyに含まれている個別のサービスを使ったことがない

対象とする環境

この記事では、JavaScriptベースのWebアプリケーションを対象とします。モバイルアプリケーションは対象としません。

必須となるnpmモジュールは以下の通りです。

▼package.json

"dependencies": {
  "aws-amplify": "^3.3.6"
}

パッケージのバージョンを確認してください

この記事では2020/12/04時点でのAmplifyを前提にしています。Amplifyは活発に開発が行われているため、導入手順が大きく変更されている場合があります。記事を読む前に、お手元の環境を確認してください。

先に結論だけ

FunctionにStorageへのアクセス権限を設定すれば、FunctionのLambda関数内からS3ストレージとして読み書きできます。しかしAmplifyが設定するアクセス権限に制限があるため、一部の命令は実行できません。

Amplifyの各サービスについての解説

まず、今回の記事で対象となる各サービスを解説します。

Amplify

Amplifyとは、モバイル/Webアプリケーションの開発に必要なAWSサービスのパッケージです。アプリケーションに必要となるAPI/ユーザー認証/ホスティング/ユーザー分析…といった機能がパッケージされています。

Amplify Function

Amplify Functionはサーバーレスでプログラムを実行するサービスです。AWS EC2のように仮想マシンが立ち上がっているわけではありません。何らかのトリガーによって呼び出された時だけ、事前に設定したプログラムが動きます。

FunctionサービスはAWS Lambdaで構成されています。

Amplify Storage

Amplify Storageはアプリケーションに統合されたオンラインストレージです。データベースには向かないメディアファイルを格納できます。たとえばユーザーがアップロードした写真を任意のユーザーにシェアするといった使い方ができます。

StorageサービスはAmazon S3で構成されています。

手順

Amplify FunctionとStorageを連携させる手順を解説します。amplify initコマンドを実行し、空のAmplifyアプリケーションが作成されている時点から手順を開始します。

Storage : 新規Storageを作成する

amplify add storageコマンドで新規ストレージを追加します。サービスの種類はコンテンツを選びます。

% amplify add storage      
? Please select from one of the below mentioned services: Content (Images, audio, video, etc.)
? You need to add auth (Amazon Cognito) to your project in order to add storage for user files. Do you want to add auth now? Yes

StorageにはAuthサービスが必須なので、まだセットアップされていない場合はAmplifyから追加を求められます。

Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito. 

 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Email
 Do you want to configure advanced settings? No, I am done.
Successfully added auth resource <Auth名> locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Authのセットアップが完了すると、そのままStorageの作成が続きます。

? Please provide a friendly name for your resource that will be used to label this category in the project: <ストレージ名>
? Please provide bucket name: <S3バケット名>
? Who should have access: Auth users only
? What kind of access do you want for Authenticated users? create/update, read, delete
? Do you want to add a Lambda Trigger for your S3 Bucket? No
Successfully added resource <ストレージ名> locally

If a user is part of a user pool group, run "amplify update storage" to enable IAM group policies for CRUD operations
Some next steps:
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud

Function : 新規Functionを作成する

まずamplify add functionコマンドで、Functionを追加します。

▼ログ

$ amplify add function
Scanning for plugins...
Plugin scan successful
? Select which capability you want to add: Lambda function (serverless function)
? Provide an AWS Lambda function name: <任意のFunction名>
? Choose the runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello World

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? Yes
? Do you want to access other resources in this project from your Lambda function? Yes
? Select the category storage
? Storage has 5 resources in this project. Select the one you would like your Lambda to access 
❯◉ <ストレージ名>
^^^^^^^^^^^^^^^^^^^

? Do you want to configure advanced settings?(詳細設定をしますか?)でYesを選択します。アクセス権限の追加について聞かれますので、操作したいバケットへのアクセスを許可します。

❗下線で強調した部分は複数選択可能なチェックボックスです。スペースキーで選択、リターンで決定という操作方法です。なにもチェックを行わないままリターンを押すと操作がキャンセルされたと解釈して処理が進みます。ご注意ください。

Functionのindex.jsにS3バケット名を格納した環境変数が追加されます。STORAGE_<ストレージ名>_BUCKETNAMEがバケット名です。

▼amplify/backend/function/"Function名"/src/index.js

/* Amplify Params - DO NOT EDIT
    ENV
    REGION
    STORAGE_<ストレージ名>_BUCKETNAME
Amplify Params - DO NOT EDIT */

既存のFunctionにStorageへのアクセス権限を追加する場合はamplify update functionコマンドを使います。Function一覧が表示されますので、その中から権限を追加するFunctionを選択してください。

Function : 関数を実装する

Functionを実装します。

▼amplify/backend/function/"Function名"/src/index.js

/* Amplify Params - DO NOT EDIT
    ENV
    REGION
    STORAGE_<ストレージ名>_BUCKETNAME
Amplify Params - DO NOT EDIT */

const AWS = require("aws-sdk");
const s3 = new AWS.S3();

/**
 * Storageにオブジェクトを追加する。
 * @return {Promise<*>}
 */
const putObjectToStorage = async () => {
    const testObj = {
        test: "test string",
    };
    return await s3
        .putObject({
            Bucket: process.env.STORAGE_<ストレージ名>_BUCKETNAME,
            Key: "file.json",
            Body: JSON.stringify(testObj),
            ContentType: "application/json",
        })
        .promise();
};

exports.handler = async (event) => {
    const result = await putObjectToStorage();
    const response = {
        statusCode: 200,
        body: JSON.stringify(result),
    };
    return response;
};

レスポンスに、生成されたS3オブジェクトのエンティティタグが出力されれば成功です。

Amplify Functionでは実行できない操作

Amplifyによって生成されるLambda用IAMロールは以下のようになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::<バケット名>/*"
            ],
            "Effect": "Allow"
        }
    ]
}

このロールで許可されない処理は実行できません。

ACL操作

Functionに割り当てられる権限には、ACLの操作権限がありません。そのためPutObjectAclのようなACL操作を伴う処理はできません。

ListObjects

2020/12/13現在、FunctionからStorageバケットのオブジェクトリストを取得できません。Functionへの権限割り当てに問題があるようです。
参考 : Issue #5528

以上、ありがとうございました。

6
4
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
6
4