AWS SAMでデプロイしてみる

記事タイトルとURLをコピーする

技術課の森です。 そろそろre:Inventですね。 今年は休暇をいただいて参加しますので、見かけられましたら、一声かけてくださいね。

はじめに

今回はAWS SAMを使ってデプロイしてみるところを試してみます。 簡単な構成での作りですので、一度お試ししてもらえればと思います。

準備編

AWS CLIをインストール/初期設定

まずは、AWS CLIをインストールします。 インストールが終わったら、AWS CLIの設定を行っていきます。

S3バケットを作成

デプロイする時に利用するS3バケットを作成します。 今回は、「s3-awssam-samplebucket」とします。

フォルダ構成

取り決めはないのですが、ざっくり以下の感じでフォルダ構成を作成します。

awssam
 ├ src
 | └ app.py
 └ template.yml
ファイル 説明
awssam/src/app.py Lambdaのコードを書きます
awssam/template.yml SAMのテンプレートファイル ここにはAPI Gateway/Lambdaの情報だけを書きます

ファイルの内容

awssam/src/app.py

ここには通常のLambdaコードを書きます。好きなコードを書いて頂ければいいので、ここは割愛します。

awssam/template.yml

このファイルはデプロイする時にメインとなるファイルになります。

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: 'A serverless application that replicate all objects in S3 bucket to Google Cloud Storage.'

Globals:
  Function:
    Runtime: python3.6
    Timeout: 300
    MemorySize: 256

Resources:
  HTTPResponseFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./src
      Handler: app.main
      FunctionName: HTTPAccess
      Role: 
        Fn::GetAtt:
          - SampleLambdaRole
          - Arn
 
  HTTPResponsePermission:
    Type: "AWS::Lambda::Permission"
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref HTTPResponseFunction
      Principal: apigateway.amazonaws.com
 
  HTTPResponseAPI:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: "2.0"
        info:
          title: awssam-apigateway
        schemes:
          - https
        paths:
          /http:
            get:
              summary: "top page"
              description: "http response [top page html]"
              produces:
              - "application/json"
              x-amazon-apigateway-integration:
                  responses:
                    default:
                      statusCode: "200"
                  uri:
                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HTTPResponseFunction.Arn}/invocations
                  passthroughBehavior: "when_no_match"
                  httpMethod: "GET"
                  type: "aws_proxy"
        x-amazon-apigateway-policy:
          Version: "2012-10-17"
          Statement:
          - Effect: Allow
            Principal: "*"
            Action: execute-api:Invoke
            Resource:
              - "execute-api:/*"
            Condition:
              IpAddress:
                aws:SourceIp:
                  - "x.x.x.x/32"
  SampleLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSNSFullAccess
      RoleName: SampleLambdaRole
  NotifySNSTopic:
    Type: 'AWS::SNS::Topic'
    Properties:
      DisplayName: 'AccessNotify'
      TopicName: 'http-access-notify'
      Subscription: 
        -
          Endpoint: mailaddress
          Protocol: email

Globals にPython3.6で、タイムアウト300秒、メモリサイズを256MBで定義、 Resources にはいくつかのAWSリソースを入れてます。 今回は、Lambda/API Gateway/IAM Role/SNSを作っています。 ちなみに、API GatewayはIPアドレス制限をしてみてます。

デプロイ

ここまで用意できたら、後はコマンドを実行して、デプロイします。 カレントディレクトリを「awssam」フォルダとします。

$ aws cloudformation package --template-file template.yml --output-template-file output.yml --s3bucket s3-awssam-samplebucket
$ aws cloudformation deploy --template-file output.yml --stack-name CFnSTACKName --capabilities CAPABILITY_NAMED_IAM

これで、デプロイまで完了です。

さいごに

結構簡単に作り込みもAWSリソースもつくれますし、AWSリソースはCloudFormationテンプレートの書き方でリソースが作れるので、すごく便利ですね。 次回はtemplate.ymlを分けて書いてみることで、Lambda関連の設定とAWSリソースの設定に分離しながら開発できるやり方を書いてみようと思います。