LoginSignup
22
19

More than 5 years have passed since last update.

Serverless Frameworkに入門してみた

Last updated at Posted at 2016-09-26

最近巷ではServerlessなるものが流行っていると聞き、
これは役に立ちそうだと思ったので少し触ってみました。

入門ということで、APIゲートウェイでリクエストを受けてS3からテキストを落としてS3内の別の場所に上げ直すという単純かつ無意味なことをしています。

環境構築

Serverlessのインストール

Serverlessを使うにはnpmでインストールします。
よって、先んじてNode.jsを入れる必要があるのですが、そちらは割愛。

npm install serverless -g

-gオプションはつけない主義なのですが、ローカルインストールだとかえって色々めんどくさそうなので断腸の思いでグローバルインストール

2016/09/26時点での最新バージョンは1.0.0-rc.2です。
以下、このバージョンでのコマンドで作業を進めますが、わりと頻繁にコマンドの体系が変わってるみたいなので注意してください。

プロジェクト作成

新規作成時のコマンドはこんな感じ。
serverless crete --template as-nodejs --path ./serverless-test
今回はnodejsを採用。pythonで実装するなら--template aws-pythonになります。

うまくいったら↓のファイルが出来上がります。

serverless-test
|- event.json
|- handler.json
|- serverless.yml

実装

バケットポリシー設定

S3にアクセスするので、バケットポリシーを設定しておきます。
バケットポリシーの設定を忘れて「IAMロールに権限与えてるのにアクセスできねぇぞ!」となるのはあるあるですね。

AWSのコンソールからS3->バケット選択-> Edit bucket policyと進みます。
バケットポリシーのjsonを自前で書くのはしんどいのでポリシージェネレーターを使用して、
今回使用するバケットのputObjectとgetObjectを許可するポリシーを作ります。

policy.json
{
  "Id": "Policy1474861813220",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1474857263263",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::my-bucket-name/*",
      "Principal": {"AWS": "arn:aws:iam::my-account-id:root"}
    }
  ]
}

参考にする場合、my-bucket-nameとmy-account-idは適宜読み替えてください。
「別にどこからアクセスされても構わん!」という勇者はPrincipal:"*"でもOKです。

serverless.ymlの編集

設定関係はserverless.ymlに記述します。記述する内容としては

  • どのリージョンに置くか
  • どんな権限を与えるか
  • 実行のトリガーは何か
  • etc...

って感じです。
そのほかはこのへんを参考に。

今回はS3のputObjectとgetObjectの権限を与えるとともに、APIゲートウェイからの呼び出しも設定します。

serverless.yml
service: serverless-test 
provider:
  name: aws
  runtime: nodejs4.3
  stage: dev
  region: us-east-1
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:getObject"
        - "s3:putObject"
      Resource: "arn:aws:s3:::my-bucket-name/*"

functions:
  transfer:
    handler: handler.transfer
    memorySize: 256
    timeout: 30
    events:
      - http:
          path: transfer
          method: get

serverless createコマンドで生成された直後だとdefaultsという項目があって、
その下にstageとかregionとかがありましたが、後にデプロイするときに「defaultsは非推奨やねん。providerの下に置いてや」と警告されたのでそうしてます。

providerが実行環境に関する設定で、functionsが各ファンクションのトリガーの設定という感じかと思います。

今回はAPIゲートウェイで/transferにGETメソッドでアクセスするとファンクションが走ります。

Lambdaファンクション実装

それではLambdaのファンクションを実装します。
前述のとおり、S3に置いたテキストファイルを落としてきて、それを同じバケット内の別の場所に上げ直します。

テストということでオブジェクトのキーは決め打ちです。

コールバック地獄の入り口に立っていますが、ご容赦を。
(真面目にやるならPromiseとか使うべきだろうなぁ...)

handler.js
'use strict';

const AWS = require('aws-sdk');

module.exports.transfer = (event, context, callback) => {

    const s3 = new AWS.S3();
    const BUCKET = "my-bucket-name";
    s3.getObject({Bucket: BUCKET, Key: 'serverless-test/test.txt'}, (err, data) => {

        if(err !== null){
            return callback(err, {message: err.stack});
        }

        let buf = data.Body;

        s3.putObject({
            Bucket: BUCKET,
            Key: 'serverless-test/output.txt',
            Body: buf
        }, (putErr, putData) => {
            callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', putData });
        });

    });


};

実行

まずはローカルで作成したコードをAWSにデプロイします。
プロジェクトルートでseverless deploy!

成功したらコマンドライン上にAPIゲートウェイのエンドポイントとかの情報が表示されます。

これだけでLambdaファンクションのアップロードとAPIゲートウェイの設定が済むなんて...!

AWSコンソールのAPIゲートウェイのところからテストすることもできますが、
serverless invokeコマンドで手元からすぐに実行できます。

serverless invoke --function transfer
で実行、とりあえずエラーはなさそうだ!

serverless-test.JPG

アップロードもできてるぞ!

感想

自前でやると面倒だったLambdaとAPIゲートウェイの連携がサクッとできるのはいい感じです。
ただ、IAMのポリシーの設定とかそっちの方で学習コストはそれなりにかかるのかなという印象です。
それでも自前でサーバーを持たずにAPIを手早く作れるというのは大きなメリットかと思います。
あとはServerlessの仕様が安定する日を待つばかりです。

22
19
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
22
19