LoginSignup
1
0

More than 3 years have passed since last update.

AWSハンズオン実践メモ 〜AWS SAM を使ってテンプレートからサーバーレスな環境を構築する〜

Posted at

はじめに

前回、AWS公式のハンズオンシリーズの中から、翻訳 Web API の構築を通して、サーバーレスアーキテクチャの基本を学ぶハンズオンを実施しました。
参考AWSハンズオン実践メモ 〜サーバーレスアーキテクチャで翻訳 Web API を構築する〜

今回は、前回のハンズオンで構築した翻訳 Web API をAWS Serverless Application Model (AWS SAM)を用いてテンプレートから構築します。

AWS Serverless Application Model (AWS SAM)とは、サーバーレスアプリケーション構築用のオープンソースフレームワークです。簡単に言うと、サーバレスな構成を作ることに特化した Cloudformation のテンプレートになります。

本記事は自身のハンズオン学習メモとして投稿します。

目次

ハンズオンの目的

  • AWS Serverless Application Model (AWS SAM)を用いて、サーバーレス構成を自動構築する

前回の Serverless #1 で構築した翻訳 Web API を AWS Serverless Application Model (AWS SAM) を用いてテンプレートから構築します。前回のハンズオンでは全ての工程を手作業で(マネージメントコンソール上で)構築していきました。今回のハンズオンではこの構築作業をテンプレート化し、作成したテンプレートから AWS リソースを構築していきます。テンプレート化することで、そのテンプレートをバージョン管理できるようになる、チーム内でレビューがしやすくなる、といった利点があり、プロダクト開発をより効率的に進めることができます。

20200709.png
(https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/ より引用)

本編

Cloud9 のセットアップ+Cloud9 で簡単な Lambda 関数を作成する

  • Cloud9で環境を作成
  • Cloud9からLambdaを作成&編集

SAM で Lambda 関数を作成する①

AM を利用するための事前準備を行い、Lambda 関数の設定情報を SAM テンプレートに記載していく。

  • translate-function.pyを作成
translate-function.py
import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):

    logger.info(event)

    return {
        'statusCode': 200,
        'body': json.dumps('Hello Hands on world!')
    }
  • template.yamlを作成
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
  TranslateLambda:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: translate-function-2
      CodeUri: ./translate-function
      Handler: translate-function.lambda_handler
      Runtime: python3.7
      Timeout: 5
      MemorySize: 256
  • 作成したファイルをパッケージング
aws cloudformation package \
     --template-file template.yaml \
     --s3-bucket 20200714handsonserverless \
     --output-template-file packaged-template.yaml

このコマンドで、S3 にファイルがアップロードされ、そのファイルのUri が --template-file で指定したテンプレートに書き足され、--output-template-file で指定したファイル名で出力される。

  • デプロイ
aws cloudformation deploy \
     --template-file ./packaged-template.yaml \
     --stack-name hands-on-serverless-2 \
     --capabilities CAPABILITY_IAM

パッケージで書き出したテンプレートファイルを元に、AWS CLI の CloudFormation の deployコマンドを叩く。これで、テンプレートに記述されている通りのリソースが構築される。

SAM で Lambda 関数を作成する②

SAM テンプレートファイルをアップデートし、Lambda 関数から別の AWS サービスを呼び出せるよう IAM 設定を修正。

  • translate-function.pyを編集
translate-function.py
import json
import boto3

translate = boto3.client('translate')

def lambda_handler(event, context):

    input_text = "こんにちは"

    response = translate.translate_text(
        Text=input_text,
        SourceLanguageCode='ja',
        TargetLanguageCode='en'
    )

    output_text = response.get('TranslatedText')

    return {
        'statusCode': 200,
        'body': json.dumps({
            'output_text': output_text
        })
    }
  • template.yamlを編集(Policies: - TranslateFullAccessを追加)
  • 作成したファイルをパッケージング(先程と同様)
  • デプロイ(先程と同様)

SAM で API Gateway のリソースを作成し、Lambda 関数と連携させる

API Gateway リソースを作成する際の設定を SAM テンプレートに記載し、外部からリクエストを受け付けられる Web API を構築する。

  • translate-function.pyを編集
translate-function.py
import json
import boto3

translate = boto3.client(service_name='translate')

def lambda_handler(event, context):

    input_text = event['queryStringParameters']['input_text']

    response = translate.translate_text(
        Text=input_text,
        SourceLanguageCode="ja",
        TargetLanguageCode="en"
    )

    output_text = response.get('TranslatedText')

    return {
        'statusCode': 200,
        'body': json.dumps({
            'output_text': output_text
        }),
        'isBase64Encoded': False,
        'headers': {}
    }
  • template.yamlを編集
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
  TranslateLambda:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: translate-function-2
      CodeUri: ./translate-function
      Handler: translate-function.lambda_handler
      Runtime: python3.7
      Timeout: 5
      MemorySize: 256
      Policies:
        - TranslateFullAccess
      Events:
        GetApi:
          Type: Api
          Properties:
            Path: /translate
            Method: get
            RestApiId: !Ref TranslateAPI
  TranslateAPI:
    Type: AWS::Serverless::Api
    Properties:
      Name: translate-api-2
      StageName: dev
      EndpointConfiguration: REGIONAL
  • 作成したファイルをパッケージング(先程と同様)
  • デプロイ(先程と同様)

以下のようにクエリ部分にリクエストを入力し送信すると、翻訳結果が返却される。

20200714_translate.png

SAM で DynamoDB TBL を作成し、Lambda 関数を連携させる

DynamoDB テーブルを作成する際の設定情報を SAM テンプレートに記載する。また、Lambda 関数側の記載も修正し、DynamoDB に翻訳リクエストの履歴情報を書き込めるようにする。

  • translate-function.pyを編集
translate-function.py
import json
import boto3
import datetime

translate = boto3.client(service_name='translate')

dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history-2')

def lambda_handler(event, context):

    input_text = event['queryStringParameters']['input_text']

    response = translate.translate_text(
        Text=input_text,
        SourceLanguageCode="ja",
        TargetLanguageCode="en"
    )

    output_text = response.get('TranslatedText')

    dynamodb_translate_history_tbl.put_item(
      Item = {
        "timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
        "input": input_text,
        "output": output_text
      }
    )

    return {
        'statusCode': 200,
        'body': json.dumps({
            'output_text': output_text
        }),
        'isBase64Encoded': False,
        'headers': {}
    }
  • template.yamlを編集
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
  TranslateLambda:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: translate-function-2
      CodeUri: ./translate-function
      Handler: translate-function.lambda_handler
      Runtime: python3.7
      Timeout: 5
      MemorySize: 256
      Policies:
        - TranslateFullAccess
        - AmazonDynamoDBFullAccess
      Events:
        GetApi:
          Type: Api
          Properties:
            Path: /translate
            Method: get
            RestApiId: !Ref TranslateAPI
  TranslateAPI:
    Type: AWS::Serverless::Api
    Properties:
      Name: translate-api-2
      StageName: dev
      EndpointConfiguration: REGIONAL
  TranslateDynamoDbTbl:
    Type: AWS::Serverless::SimpleTable
    Properties:
      TableName: translate-history-2
      PrimaryKey:
        Name: timestamp
        Type: String
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1
  • 作成したファイルをパッケージング(先程と同様)
  • デプロイ(先程と同様)

以下のように翻訳結果がdynamoDBに蓄積される。

20200714_dynamodb.png

作成した AWS リソースの削除

CloudFormationのスタックを削除すると関連するリソースが全て削除される。

おわりに

今回はSAMを利用し、IaaCでサーバーレスアーキテクチャを構築した。
プロジェクトにおいてAWSで設計・構築する際はCloudFormationを使っていく事になると思うので、記法や管理方法についても学習したい。

参考

[新ツール] AWS Serverless Application Model (AWS SAM) を使ってサーバーレスアプリケーションを構築する

1
0
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
1
0