AWS SAMテンプレートのWeb Backendを試す。

はじめに

サーバレスアプリケーショ作ることになり、SAM使おうと思い色々調べていたのですが、 大体がHello Worldであり、DBまでできるものを見たかったので、 同じくSAMのテンプレートで選べるWeb Backendを作ってみました。

SAMの環境構築

基本的にはAWSのガイドを見て進めれば出来ると思います。

Mac
macOS への AWS SAM CLI のインストール - AWS サーバーレスアプリケーションモデル

Win
Windows での AWS SAM CLI のインストール - AWS サーバーレスアプリケーションモデル

  1. AWS アカウントの作成
  2. IAM アクセス許可の設定
  3. Docker をインストールします。注意 Dockerは、アプリケーションをローカルでテストするための前提条件です。
  4. Homebrew をインストールします。
  5. AWS SAM CLI のインストール

1〜4は割愛します。

ステップ 5. AWS SAM CLI のインストール

インストール

$ brew tap aws/tap
$ brew install aws-sam-cli

インストールできたか確認

$ sam --version
SAM CLI, version 1.1.0

初回確認は意外と待ちました。(5秒位)

今回の流れでは不要ですが、アップグレードする場合

$ brew upgrade aws-sam-cli

Web Backendの作成

Hello Worldですが全体の流れは大体同じです。
チュートリアル Hello World アプリケーションの導入 - AWS サーバーレスアプリケーションモデル

ステップ 1. サンプルのダウンロード AWS SAM アプリケーション

sam init

*途中入力を求められます。

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

*1を選択

Which runtime would you like to use?
        1 - nodejs12.x
        2 - python3.8
        3 - ruby2.7
        4 - go1.x
        5 - java11
        6 - dotnetcore3.1
        7 - nodejs10.x
        8 - python3.7
        9 - python3.6
        10 - python2.7
        11 - ruby2.5
        12 - java8.al2
        13 - java8
        14 - dotnetcore2.1
Runtime: 1

* 1 - nodejs12.xを選択

Project name [sam-app]:   ただエンターを押せばsam-appでディレクトリが作られます。

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

AWS quick start application templates:
        1 - Hello World Example
        2 - Step Functions Sample App (Stock Trader)
        3 - Quick Start: From Scratch
        4 - Quick Start: Scheduled Events
        5 - Quick Start: S3
        6 - Quick Start: SNS
        7 - Quick Start: SQS
        8 - Quick Start: Web Backend
Template selection: 8

*Web Backendなので8を選択します。


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

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

ステップ 2. アプリケーションの構築

$ cd sam-app
$ sam build

Building function 'getAllItemsFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Building function 'getByIdFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Building function 'putItemFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided

ステップ 3. アプリケーションをAWSクラウドにデプロイする

sam deploy --guided

デプロイするためには色々と権限が必要です。
awsのcredentialによっては権限不足でエラーになるので適宜必要な権限を付与してあげてください。
私の場合は下記の権限を追加してデプロイ出来るようになりました。

ローカル実行時に「profileを指定することで」任意のcredentialを利用可能です。
使っているcredentialを変えたくない場合は、 ~/.aws/credentialsに定義した上でsamのコマンドを実行しましょう。 下記はローカルで動作させるためのコマンド

sam local start-api --env-vars env.json --profile default --debug
IAM
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:PassRole",
                "iam:DetachRolePolicy",
                "iam:TagRole",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:UpdateRole",
                "iam:PutRolePolicy"
            ],
            "Resource": "*"
        }
    ]
}
Cloudformation
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStackSet",
                "cloudformation:CreateChangeSet",
                "cloudformation:DescribeChangeSet",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:DeleteChangeSet",
                "cloudformation:DescribeStacks"
            ],
           "Resource": "*"
        }
    ]
}
API_Gateway
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "apigateway:DELETE",
                "apigateway:SetWebACL",
                "apigateway:PUT",
                "apigateway:PATCH",
                "apigateway:POST",
                "apigateway:GET"
            ],
            "Resource": "*"
        }
    ]
}
Lambda
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:AddPermission",
                "lambda:GetFunction",
                "lambda:GetFunctionConfiguration",
                "lambda:DeleteFunction",
                "lambda:RemovePermission"
            ],
            "Resource": "*"
        }
    ]
}
S3
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutBucketTagging",
                "s3:PutBucketPolicy",
                "s3:CreateBucket",
                "s3:DeleteBucketPolicy",
                "s3:DeleteBucket",
                "s3:PutBucketVersioning"
            ],
            "Resource": "*"
        }
    ]
}
DynamoDB
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "dynamodb:CreateTable",
                "dynamodb:DescribeTable"
            ],
            "Resource": "*"
        }
    ]
}

クリーンアップ

このチュートリアルを実行して作成した AWS リソースが不要になった場合は、
デプロイした AWS CloudFormation スタックを削除することでリソースを削除できます。

コンソールかコマンド実行のいずれか。

AWSコンソールからCloudformationのページへ行き、スタックよりsam-appを削除
  1. AWS マネジメントコンソール にサインインして、https://console.aws.amazon.com/cloudformationAWS CloudFormation コンソールを開きます。
  2. 左のナビゲーションペインで [スタック] を選択します。
  3. スタックのリストで、[sam-app] (または作成したスタックの名前) を選択します。
  4. [削除] を選択します。
・コマンド実行
aws cloudformation delete-stack --stack-name sam-app --region ap-northeast-1

※スタックの削除を行うには下記権限が別途必要

 cloudformation:DeleteStack

SAMでデプロイしたcredentialで出来上がったアプリケーションの確認をしようとすると色々権限なくて止まる。
ちゃんとやるならSAM作成とアプリ開発でポリシー分けるのがよさげです。

全部かちょっと怪しいですが、途中で追加した権限

"iam:PutRolePolicy",
"iam:GetRolePolicy"
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:DeleteTable"
"s3:DeleteBucket",
"s3:PutBucketVersioning"