Blogical

AWS/Salesforceを中心に様々な情報を配信していきます(/・ω・)/

SAM 入門

こんにちは、ロジカル・アーツの井川です。

今日は Lambda などを作成する際に使う、SAMについてまとめていきます。

SAMとは?

Serverless Application Model の略で、サーバーレスアプリケーションの開発及びデプロイを行うフレームワークです。 全てはYAMLで書くことができます。SAM のシンプルな YAML ファイルを定義することで、複雑な CloudFormation を容易に生成することができます。

SAM の特徴

  • CloudFormation からのリソース(例えばOutputs/Mappings/Parameters/Resourcesなど)をサポートします。
  • AWSにデプロイする際に使用するコマンドは二つだけです。
  • SAMはCodeDeployよりLambda関数へデプロイできます。
  • SAMはLambda/API Gateway/DynamoDBの実行を助けることができます。SAMを使えばローカルでデプロイしてテストすることが可能です。

SAM Recipe

  • Transform Header indicates it's SAM template:
    • Transform: 'AWS::Serverless-2016-10-31'
    • アプリケーションのテンプレートを CloudFormation の形式に変換します。
  • Code(例)
    • AWS::Serverless::Function -> Lambda を作成します。
    • AWS::Serverless::Api -> API Gateway を作成します。
    • AWS::Serverless::SimpleTable -> DynamoDB を作成します。

ハンズオン

前提条件

  • Amazon Linux2 AMI を使用した Cloud9 環境
  • SAM インストール済み(手順に関しては下記参照)

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-install-linux.html

プロジェクトの作成

SAM を実際にインストールしたら、まず行うことはプロジェクトの作成だと思います。 SAM では sam init コマンドにより、作成することが出来ます。コマンドを入力すると、下記のように幾つか質問され、雛形を作成します。

$ sam init


        SAM CLI now collects telemetry to better understand customer needs.

        You can OPT OUT and disable telemetry collection by setting the
        environment variable SAM_CLI_TELEMETRY=0 in your shell.
        Thanks for your help!

        Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.html

Which template source would you like to use? // どのテンプレートタイプを使われたいですか?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: Choice: 1 // 今回はAWS側で既に用意されているテンプレートを使用します

Which runtime would you like to use? // どのランタイムを使用されたいですか? 
        1 - nodejs12.x
        2 - python3.8
        3 - ruby2.5
        4 - go1.x
        5 - java11
        6 - dotnetcore2.1
        7 - nodejs10.x
        8 - python3.7
        9 - python3.6
        10 - python2.7
        11 - java8
        12 - dotnetcore2.0
        13 - dotnetcore1.0
Runtime: 1 // nodejs12.x

Project name [sam-app]: 

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: nodejs12.x
Dependency Manager: npm
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./sam-app/README.md

一通り入力が終わると上記のようにアプリケーションを新たに生成してくれます。

ディレクトリ構成

今回デプロイするプロジェクトのディレクトリ構成はこのようになっています。 f:id:logicalarts:20200212113001p:plain

template.yaml

上記のディレクトリにあるファイルの中で、リソースを定義していくファイルが template.yaml になります。

今回の template.yaml は以下の通りです。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources: // 作成するリソースを決定します
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs12.x
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get

Outputs:  // 結果を生成します
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

Build & Deploy

Build で YAML ファイルをコンパイルして、実行ファイルを新たに生成したのち、実際に実行(デプロイ)していきましょう。コマンドは下記の通りです。

$ sam build
$ sam deploy --guided

結果

エラー等発生しなければ、最終的にコマンドラインに以下が表示されるかと思います。

...
...
Stack sam-app outputs:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OutputKey-Description                                                                                                              OutputValue                                                                                                                      
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
HelloWorldFunctionIamRole - Implicit IAM Role created for Hello World function                                                     arn:aws:iam::xxxxxxxxxxxx:role/sam-app-HelloWorldFunctionRole-xxxxxxxxxxxx                                                        
HelloWorldApi - API Gateway endpoint URL for Prod stage for Hello World function                                                   https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/                                                          
HelloWorldFunction - Hello World Lambda Function ARN                                                                               arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxx:function:sam-app-HelloWorldFunction-xxxxxxxxxxxx                                     
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

上記は Outputs で指定した項目がきちんと表示されていますね。

実際にAWSのコンソール画面でも確認してみましょう。 AWSコンソール->CloudFormation->App名 にて確認できます。

f:id:logicalarts:20200212114211p:plain

ステータスが無事 CREATE_COMPLETE になっています。

削除

ハンズオンの最後は、お掃除していきましょう。

$ aws cloudformation delete-stack --stack-name sam-app --region ap-northeast-1   

きちんと削除されたか確認します。

f:id:logicalarts:20200212122840p:plain

ステータスが DELETE_COMPLETE になっていますね。ハンズオンは以上となります。

ポリシーテンプレート

ポリシーテンプレートとは、Lambda関数を使用するにあたって必要となるアクセス許可範囲を定義しているテンプレートのことです。

  • 様々なテンプレートのリストは以下サイトに載っています。

ポリシーテンプレートの一覧

よく使われるポリシー例

  • S3ReadPolicy: S3への読み取り許可を与える
  • SQSPollerPolicy: SQSキューにポーリングする許可を与える
  • DynamoDBCrudPolicy: CRUD = 作成、読み取り、更新、削除

下記は実際の SQSPollerPolicy を使った Lambda関数の定義テンプレート です。Policies のところに SQSPollerPolicy とあるのが見てわかるかと思います。Policies に記載するだけでSQSを使えるように SAM が自動的に変換を行ってくれます。とても便利なので上記サイトを使って定義することをお勧めします。

MyFunction:
  Type: 'AWS::Serverless::Function'
  Properties:
    CodeUri: ${codeuri}
    Handler: hello.handler
    Runtime: python2.7
    Policies:
      - SQSPollerPolicy:
        QueueName:
          !GetAtt MyQueue.QueueName

まとめ

今回は、サーバーレスアプリケーションのプロビジョニング、デプロイ、テストを容易にしてくれる SAM についてまとめてみましたがいかがでしたでしょうか。 お役に立てれば幸いです。

参考サイト

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-policy-template-list.html

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html