LoginSignup
18
10

More than 5 years have passed since last update.

Serverless Frameworkでやったことをまとめてみた

Last updated at Posted at 2016-12-08

Serverless Framework v1系 (v1.2.1)を触ってみたので、やったことのメモ。(特にresourceまわり

インストール方法など基本的な使用方法は以下の記事が詳しいです。

やったこと

S3バケットを作る

webサイトのホスティングが目的だったので、WebsiteConfigurationを指定しています。
特にハマりどころはありませんでした。

serverless.yml
resources:
  Resources:
    MyBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: my-bucket
        AccessControl: PublicRead
        WebsiteConfiguration:
          IndexDocument: index.html

参考

DynamoDB

テーブル作成

こちらもCloudFormationのルール通りで問題ありません。

serverless.yml
resources:
  Resources:
    MyTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: MyTable
        AttributeDefinitions:
          -
            AttributeName: Id
            AttributeType: S
        KeySchema:
          -
            AttributeName: Id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

参考

DynamoDB Streamsとトリガーの管理

Streamの作成

StreamSpecificationを追加することでストリームを作成できます。

serverless.yml
resources:
  Resources:
    MyTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: MyTable
        AttributeDefinitions:
          -
            AttributeName: Id
            AttributeType: S
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        # ここを追加
        StreamSpecification:
          StreamViewType: NEW_IMAGE

トリガーの設定

トリガーはfunctionのevent.streamに作成したストリームのarnを指定します。

functions:
  streamTest:
    handler: handler.hello
    events:
      - stream:
          arn: arn:aws:dynamodb:us-east-1:999999999999:table/MyTable/stream/2016-12-01T07:09:53.720

arnを直書きだと変更が入った場合に面倒ですね・・。
ということで以下の用に関数Fn::GetAttを使う形に書き換えてみます。

functions:
  streamTest:
    handler: handler.hello
    events:
      - stream:
          arn:
            "Fn::GetAtt":
              - MyTable
              - Arn

ですが、実行すると以下のようなエラーが発生

  Type Error ---------------------------------------------

     EventSourceArn.split is not a function

どうやらバグにより動作しないようです。
Kinesis Streamも同様の理由により関数による指定ができません。
現在はarnを直書きするしかないようです。

既にPRが出ているようなので対応を待ちましょう。

参考

ApiGatewayの認証設定

カスタム認証

functions:
  # 認証用関数を定義
  authFunc:
    handler: handler.auth

  hello:
    handler: handler.hello
    events:
      - http:
          path: hogehoge
          method: get
          # 認証用の関数を指定
          authorizer: authFunc

カスタム認証の関数の実装については省略します。

参考

IAM認証

リソース名はApiGatewayMethodV1MyFuncGetの部分は対象APIのLogicalIDを指定する必要があります。
function側の指定は特に必要ありません。

serverless.yml
resources:
  Resources:
    ApiGatewayMethodV1MyFuncGet: # 対象のLogicalIDを指定
      Type: AWS::ApiGateway::Method
      Properties:
        HttpMethod: GET
        AuthorizationType: AWS_IAM

参考

vpcリソースへのアクセス

以下の記事が参考になりますが、1点ハマりどころがありました。

以下の内容でデプロイ時にエラーが発生するので困っていましたが、
どうやら 初回デプロイ時 にvpcの記述があるとエラーが発生するようです。

serverless.yml
service: sls-sample

provider:
  name: aws
  runtime: nodejs4.3
  cfLogs: true

  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
      Resource:
        - "*"

functions:
  hello:
    handler: handler.hello
    vpc:
      securityGroupIds:
        - sg-xxxxxx
      subnetIds:
        - subnet-xxxxxx
    events:
      - http:
          path: hogehoge
          method: get
          cors: true

エラー内容

An error occurred while provisioning your stack: HelloLambdaFunction
- Your access has been denied by EC2, please make sure
your function execution role have permission to CreateNetworkInterface.
EC2 Error Code: UnauthorizedOperation. EC2 Error Message:
You are not authorized to perform this operation..

以下の用に一度vpc設定部分をコメントアウトしてデプロイ後、コメントアウト解除で再デプロイすることで解決しました。

serverless.yml
service: sls-sample

provider:
  name: aws
  runtime: nodejs4.3
  cfLogs: true

  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
      Resource:
        - "*"

functions:
  hello:
    handler:handler.hello
    # ここを一度コメントアウト
    # vpc:
    #   securityGroupIds:
    #     - sg-xxxxxx
    #   subnetIds:
    #     - subnet-xxxxxx
    events:
      - http:
          path: hogehoge
          method: get
          cors: true

※ v1.2.1で確認していましたが、最新のv1.3.0で修正されたようです

参考

その他ハマったところ

以下の内容でデプロイを実行するとエラーが発生します。

serverless.yml
service: sls-sample

provider:
  name: aws
  runtime: nodejs4.3
  cfLogs: true

function:
  foo:
    handler: handler.foo
  foobar:
    handler: handler.foobar

エラー内容

  Serverless Error ---------------------------------------

     An error occurred while provisioning your stack: IamPolicyLambdaExecution
     - Template error: LogGroup /aws/lambda/sls-sample-dev-foo
     doesn't exist.

発生条件と解決方法

バグが報告されていました。
どうやら、定義したfunction名が他のfunction名に含まれる(前方一致)場合にエラーが発生するようです。

例えば以下のようにするとエラーは発生しません。

serverless.yml
provider:
  name: sls-sample
  runtime: nodejs4.3
  cfLogs: true

function:
  foo:
    handler: handler.foo
  # 先頭に'x'を追加
  xfoobar:
    handler: handler.foobar

できなかったこと

  • API Gatewayのモデル作成及びマッピング

現バージョンでは対応してないようです。pluginがありましたが
v1系は未対応のようです。
今回はaws-cli叩くスクリプトを書いて対応しましたが、もっと他にいい方があるぞという方は教えていただけるとうれしいです。


投稿直前に新たなpluginが公開されていることに気づきました。
こちらは今度試してみようと思います。

18
10
1

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
18
10