はじめてのサーバーレス ~ サーバーレスな会員制サイトを作ってみよう ~ 第 3 回

2021-02-02
How to be a Developer

亀田 治伸

今回でこのハンズオンシリーズも 3 回目となります。シナリオで使用している AWS Cloud9 から Lambda を起動する手順が、昨年 11 月に変更となり、今から新規で第一回目の作業を行う方は少し画面や手順などが変更となっています。この記事の内容と異なる環境で作業されている場合、最新版のシナリオは こちら にありますので、ご参考ください。

第 3 回 (今回)

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »

毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。 


1. Cognito による認証と API Gateway を組み合わせる

1-1. API Gateway に認証の設定を追加

AWS マネジメントコンソールで [API Gateway] を開き、GET メソッド実行の設定画面を開きます。

[メソッドリクエスト] をクリックします。(ステージではなく、リソースを指していることを確認してください)

クリックすると拡大します

[認可] の右側にある鉛筆ボタンをクリックします。

クリックすると拡大します

プルダウンから [AWS_IAM] を選択して、右側のチェックボタンをクリックして確定します。

クリックすると拡大します

画面上部の [← メソッドの実行] をクリックして、前の画面に戻ります。

クリックすると拡大します

GETメソッド呼び出しの ARN が表示されています。後の手順で使用するためメモしておいてください。

クリックすると拡大します

POSTメソッド実行の設定画面を開きます。
[メソッドリクエスト] をクリックします。

クリックすると拡大します

[認可] の右側にある鉛筆ボタンをクリックします。

クリックすると拡大します

プルダウンから [AWS_IAM] を選択して、右側のチェックボタンをクリックして確定します。

クリックすると拡大します

画面上部の [← メソッドの実行] をクリックして、前の画面に戻ります。

クリックすると拡大します

POSTメソッド呼び出しのARNが表示されています。後の手順で使用するためメモしておいてください。

クリックすると拡大します

リソースのツリー階層から [/] をクリックして選択します。
[アクション] プルダウンから [APIのデプロイ] を選択します。

クリックすると拡大します

[デプロイされるステージ] [demo] を選択して、[デプロイ] をクリックします。

クリックすると拡大します

デプロイが行われました。

クリックすると拡大します

1-2. IAMロールにポリシーを追加

AWS マネジメントコンソールで [IAMポリシー] の画面を開きます。
[ポリシーの作成] をクリックします。

クリックすると拡大します

[サービス] をクリックして展開します。

クリックすると拡大します

検索欄に [executeapi] と入力します。
表示された [ExecuteAPI] をクリックします

クリックすると拡大します

[アクション] を展開して、[書き込み]-[Invoke] にチェックを入れます。

クリックすると拡大します

[ExecuteAPI execute-api-generalのARNの指定] 欄に、前節で確認した「GETメソッド呼び出しのARN」を入力します。

[追加] をクリックします。

クリックすると拡大します

GET メソッド呼び出しの ARN が追加されたことを確認します。
続けて [ARN の追加] をクリックします。

クリックすると拡大します

[ExecuteAPI execute-api-general の ARN の指定] 欄に、前節で確認した「POST メソッド呼び出しの ARN」を入力します。[追加] をクリックします。

クリックすると拡大します

POST メソッド呼び出しの ARN が追加されたことを確認します。

[ポリシーの確認] をクリックします。

クリックすると拡大します

[名前] 欄に [YYYYMMDDserverlessAPIGatewayGetAndPostPolicy] と入力します。(YYYYMMDD は本日の日付)

[ポリシーの作成] をクリックします。

クリックすると拡大します

GET メソッドおよび POST メソッドを呼び出す権限を定義したポリシー [YYYYMMDDserverlessAPIGatewayGetAndPostPolicy] が作成されました。

作成されたポリシーをクリックして定義内容を確認します。

クリックすると拡大します

IAM ポリシーの定義内容を JSON 形式で表示します。
以下のような定義内容となっていることを確認します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": "execute-api:Invoke",
      "Resource": [
        "arn:aws:execute-api:ap-northeast-1:123456789012:nf3kgecnj4/*/GET/items",
        "arn:aws:execute-api:ap-northeast-1:123456789012:nf3kgecnj4/*/POST/items"
      ]
    }
  ]
}

もう 1 つ IAM ポリシーを作成します。

[ポリシーの作成] をクリックします。

クリックすると拡大します

前の手順と同様にしてポリシーの設定を行います。

  • サービス : [ExecuteAPI] を選択
  • アクション : [書き込み]-[Invoke] を選択
  • リソース : 「GET メソッド呼び出しの ARN」のみを指定 (POST メソッドは指定しません)

[ポリシーの確認] をクリックします。

クリックすると拡大します

[名前] 欄に [YYYYMMDDserverlessAPIGatewayGetOnlyPolicy] と入力します。(YYYYMMDD は本日の日付)

[ポリシーの作成] をクリックします。

クリックすると拡大します

GET メソッドのみを呼び出す権限を定義したポリシー [YYYYMMDDserverlessAPIGatewayGetOnlyPolicy] が作成されました。

作成されたポリシーをクリックして定義内容を確認します。

クリックすると拡大します

IAM ポリシーの定義内容を JSON 形式で表示します。
以下のような定義内容となっていることを確認します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VisualEditor0",
      "Effect": "Allow",
      "Action": "execute-api:Invoke",
      "Resource": [
        "arn:aws:execute-api:ap-northeast-1:123456789012:nf3kgecnj4/*/GET/items"
      ]
    }
  ]
}

AWS マネジメントコンソールで [IAM ロール] の画面を開きます。

検索ボックスに [Cognito] と入力して、Cognito ID プールに紐付くロールを表示します。

[Cognito_YYYYMMDDserverlessAuth_Role] (認証された ID 用のロール) をクリックします。

クリックすると拡大します

[ポリシーをアタッチします] をクリックします。

クリックすると拡大します

ポリシーの一覧から [YYYYMMDDserverlessAPIGatewayGetAndPostPolicy] にチェックを入れます。

[ポリシーのアタッチ] をクリックします。

クリックすると拡大します

ポリシーがアタッチされたことを確認します。

クリックすると拡大します

[IAM ロール] の画面に戻ります。[Cognito_YYYYMMDDserverlessUnauth_Role] (認証されていない ID 用のロール) をクリックします。

クリックすると拡大します

[ポリシーをアタッチします] をクリックします。

クリックすると拡大します

ポリシーの一覧から [YYYYMMDDserverlessAPIGatewayGetOnlyPolicy] にチェックを入れます。

[ポリシーのアタッチ] をクリックします。

クリックすると拡大します

ポリシーがアタッチされたことを確認します。

クリックすると拡大します

1-3. Web ブラウザからの動作確認

[webpage] フォルダの [login.html][mypage.html][apigateway.js] を適当な名前にリネームします。[login.html-][mypage.html-][apigateway.js-]

[443] のフォルダから以下のファイルを [webpage] フォルダにコピーします。

  • [apigateway.js]
  • [login.html]
  • [mypage.html]

この時点で、[webpage] フォルダ配下の構成は以下のようになっているはずです。

[website]
┣ [img] … アイコン等の画像ファイル
┣ [lib] … 各種ライブラリ/SDK (必要なものを格納済み、ただしapigClient.jsを除く)
┃  ┣ [apigateway]
┃  ┃  ┣ [lib]
┃  ┃  ┗ apigClient.js … API Gatewayアクセスクライアントのクラス定義
┃  ┣ [awssdk]
┃  ┗ [cognito]
┣ [style] … CSSファイル
┣ apigateway.js … API Gateway処理のJavaScriptコード (Cognito認証処理を追加)
┣ cognito.js    … Cognitoへアクセスを行う処理を記述したJavaScriptコード
┣ config.js     … CognitoのID情報等を記述したファイル
┣ login.html    … Webブラウザで最初に表示するページ (API Gatewayの項目を追加)
┗ mypage.html   … ログイン処理が行われた後に遷移するWebページ (同上)

その他のファイルは存在していても邪魔にはならないので無視します。

[webpage] フォルダ直下の [login.html] をWebブラウザで開きます。

画面を下にスクロールしていくと、Cognito のテスト項目の下に API Gateway のテスト項目が追加されています。

まず、ログインしていない状態で API Gateway のテストを実施します。ログイン状態となっている場合、Sign Out のボタンを押してください。セッションが切れます。

クリックすると拡大します

GET メソッドの実行を試みます。正常に実行できることを確認します。

クリックすると拡大します

POST メソッドの実行を試みます。
権限が無いため、ステータスコード [403] が返ってきます。

クリックすると拡大します

登録済みのユーザーでサインインを行います。
[My Page] に遷移した後、同様に API Gateway のテストを実施します。

GET メソッドの実行を試みます。正常に実行できることを確認します。

クリックすると拡大します

POST メソッドの実行を試みます。正常に実行できることを確認します。

クリックすると拡大します


2. ラボ 2 : Amplify を使ってサーバーレスアプリケーションを構築する

本ラボでは、AWS が提供する Web アプリケーション・モバイルアプリケーション構築の統合フレームワークである AWS Amplify を使用して、サーバーレスアプリケーションを構築します。

Amplify では、大きく以下の3つの機能が提供されます。

  • Amplify CLI :
    アプリケーションを構成する各種リソースを対話形式で設定して構築することができる、コマンドラインユーザーインターフェイス
  • Amplify Library :
    Amplify を使ったアプリケーションを構築する際に、クライアント側のアプリケーション (Web、モバイル) に組み込んで用いる SDK / ライブラリー
  • Amplify Console :
    GitHub や AWS CodeCommit と統合された CI/DI 機能や、マネージドなアプリケーションホスティング機能を提供

ラボ 2 では、ラボ 1 で使用した AWS サービス「Amazon DynamoDB」「AWS Lambda」「Amazon API Gateway」「Amazon Cognito」を引き続き使用して、サーバーレスアプリケーションを構築していきます。

2-1. Amplify を使用する準備を行う

2-1-1. Cloud9 環境のディスク容量拡張

ラボ 1 で作成した Cloud9 環境は、ユーザーが利用可能なディスク領域の容量が「10 GB」となっています。

これから実施するラボ 2 ではディスク容量が不足する可能性がありますので、予めディスク容量を拡張しておきます。

ハンズオン資料のフォルダに、以下のファイルがあります。

[resize.sh]

このファイルを Cloud9 上にアップロードします。

Cloud9 の画面左側に表示されているディレクトリツリーから、ルートディレクトリ  (「YYYYMMDDserverless - /home/ec2-user/environment」と表示されています) をクリックして選択状態にします。

クリックすると拡大します

画面上部のメニューから [File]-[Upload Local Files...] を選択します。

クリックすると拡大します

下図のウィンドウが表示されますので、アップロードするファイル (resize.sh) をウィンドウ内にドラッグ & ドロップします。

もしくは、[Select files] をクリックしてアップロード対象ファイルを指定しても構いません。

クリックすると拡大します

lsコマンドを実行して、ファイルがアップロードされたことを確認します。

$ ls -l
total 8
-rw-r--r-- 1 ec2-user ec2-user  569 Aug 28 05:46 README.md
-rw-r--r-- 1 ec2-user ec2-user 1304 Sep  1 12:28 resize.sh

ディスク容量を「20GB」に拡張するために、以下のコマンドを実行します。

$ sh resize.sh 20

df コマンドを実行して、/dev/xvda1 のサイズが 20GB に拡張されたことを確認します。

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
devtmpfs          493872      60    493812   1% /dev
tmpfs             504564       0    504564   0% /dev/shm
/dev/xvda1      20509288 9630940  10778100  48% /

2-1-2. 前提環境の確認

Cloud9 の画面下部にある [Terminal] ウィンドウを使用してコマンドを実行します。
画面が狭い場合は、境界線をドラッグして画面を大きくして頂いて構いません。

クリックすると拡大します

Amplify CLI をインストールするには、以下の前提条件を満たしておく必要があります。

  • Node.js : バージョン 10.x 以降
  • npm : バージョン 6.x 以降

Cloud9 にはこれらのツールが最初から導入されていますが、念のためにバージョンを確認しておきましょう。(“-” は文字コードの関係でコピペでは動作しないケースがありますので手打ちしてください。)

$ node –-version
v10.22.0

$ npm –-version
6.14.6

Cloud9 を作成したタイミングによっては上記と異なるバージョンになっている場合もありますが、Amplify CLI の前提条件を満たしていれば問題ありません。

2-1-3. Amplify CLI のインストール

Amplify CLI は「npm」を使用してインストールします。
以下の通りコマンドを実行します。

$ npm install -g @aws-amplify/cli

Amplify CLI のインストールが行われます。
「Successfully installed the Amplify CLI」と出力されればインストール成功です。

Amplify CLI が実行できることを確認します。
以下の通りコマンドを実行して、バージョンが表示されれば OK です。(”-“ がコピペでは動作しないので手打ちしてください)

$ amplify –version
Scanning for plugins...
Plugin scan successful
4.29.2

2-1-4. AWS 認証情報の設定

Amplify CLI でコマンドを実行するためには、IAM ユーザーの認証情報が必要になります。
今回は、Amplifi CLI の実行時に AWS CLI のプロファイルを指定する方法を採用します。

Cloud9 上で AWS CLI のプロファイルを作成するために、以下の手順を実行します。

以下の通りコマンドを実行します。

$ aws configure

アクセスキー ID、シークレットアクセスキー、リージョンの確認を求められますので、何も入力せずに Enter キーを押します。

AWS Access Key ID [****************XXXX]: 
AWS Secret Access Key [****************XXXX]: 
Default region name [ap-northeast-1]: 

「Default output format」に対して [json] と入力して Enter キーを押します。

Default output format [None]: json

これで AWS CLI のプロファイル「default」が Cloud9 上に保存されました。

このタイミングで次のようなダイアログが表示される場合があります。
その際は [Force update] をクリックしてください。

註)PC や Mac で Amplify CLI を利用する場合は、AWS CLI のプロファイルを指定する方法の他に、IAM ユーザーのアクセスキーを Amplify CLI に直接設定する方法もあります。
詳しい手順はこちらを参照してください。

クリックすると拡大します

2-2. REST API を使った Web アプリケーションを作成する

2-2-1. React アプリケーションの作成

以下のコマンドを実行します。(YYYYMMDD は本日の日付)

$ npx create-react-app YYYYMMDDamplify

作成したプロジェクトのディレクトリに移動します。

$ cd YYYYMMDDamplify

React を使った Web アプリケーションが動作することをテストします。
以下のコマンドを実行してアプリケーションを起動します。

$ cd YYYYMMDDamplify
$ npm start

アプリケーションが起動すると、以下のように表示されます。

Compiled successfully!

You can now view 20200901amplify in the browser.

  Local:            http://localhost:8080
  On Your Network:  http://172.XX.XX.XX:8080

Note that the development build is not optimized.
To create a production build, use npm run build.

起動したアプリケーションに接続を行ってみます。

アプリケーションは Cloud9 上で起動していますので、Web ブラウザのアドレスバーに「http://localhost:8080」と入力して接続を試みても、接続することはできません。
そこで、Cloud9 の「Preview」機能を使うことでアプリケーションに接続します。

画面上部の [Preview] をクリックして [Preview Running Application] を選択します。

クリックすると拡大します

ウィンドウ内に React サンプルアプリケーションの画面が表示されれば動作確認 OK です。

クリックすると拡大します

画面を大きく表示したい場合はこちらの図のボタンをクリックすると、別ウィンドウでアプリケーションの画面が開きます。

クリックすると拡大します

動作確認が終わりましたら、ターミナルの画面 (「npm start」を実行したウィンドウ) で [Ctrl]+[C] を入力して、アプリケーションを停止します。

アプリケーションを停止すると、プレビューが表示できなくなります。(すぐに表示が消えることはありませんが、プレビュー画面をリロードすると「Oops! No application seems to be running here!」と表示されることが分かると思います)

2-2-2. Amplifyプロジェクトの初期化

以下のコマンドを実行します。

$ amplify init

ここからは、対話形式で Amplify プロジェクトの初期化の設定を行っていきます。
最初に、プロジェクトの名前の指定を求められます。

現在のディレクトリの名前が「デフォルト値」として表示されていることを確認して、何も入力せずに Enter キーを押します。

? Enter a name for the project (20200901amplify)

※ このようにデフォルト値から変更しない場合は、何も入力せずに Enter キーを押します

環境の名前を入力します。

デフォルト値として「dev」が表示されていますが、今回は [demo] と入力して Enter キーを押します。

? Enter a name for the environment (dev) demo

※ デフォルト値から変更する場合は、キーボードから値を入力して Enter キーを押します

Amplify CLI で使用するエディタを指定します。
カーソルキーの上下で [Vim] を選択して Enter キーを押します。

? Choose your default editor (Use arrow keys)
 Visual Studio Code 
  Atom Editor 
  Sublime Text 
  IntelliJ IDEA 
❯ Vim (via Terminal, Mac OS only) 
  Emacs (via Terminal, Mac OS only) 
  None

※ 選択肢から選択する場合は、カーソルキーの上下で選択して Enter キーを押します

構築するアプリケーションの種類を指定します。
[javascript] を選択して Enter キーを押します。

? Choose your default editor (Use arrow keys)
 Visual Studio Code 
  Atom Editor 
  Sublime Text 
  IntelliJ IDEA 
❯ Vim (via Terminal, Mac OS only) 
  Emacs (via Terminal, Mac OS only) 
  None

JavaScript で使用するフレームワークを指定します。
[react] を選択して Enter キーを押します。

? What javascript framework are you using (Use arrow keys)
  angular 
  ember 
  ionic 
❯ react 
  react-native 
  vue 
  none

プロジェクトのビルド、実行に関していくつかの指定を求められます。
全てデフォルト値のままで構いませんので、何も入力せずに Enter キーを押します。

? Source Directory Path: (src) 
? Distribution Directory Path: (build) 
? Build Command: (npm run-script build) 
? Start Command: (npm run-script start)

AWS CLI のプロファイルを使用するかどうか聞いてきます。
[y] を入力して Enter キーを押します。

? Do you want to use an AWS profile? (Y/n) y

ここで「Setup new user?」などと聞かれた場合は、AWS CLI のプロファイルが Amplify CLI から認識されていない可能性があります。前節の手順を見直してください。

使用する AWS CLI のプロファイルを指定します。
[default] を選択して Enter キーを押します。

? Please choose the profile you want to use (Use arrow keys)
❯ default

全ての項目の指定が終わりましたので、初期化の処理が始まります。

初期化の処理が終わるまで数分程度かかりますので、終わるまで待ちます。(画面上では Amplify の初期化に伴って関連する AWS リソースを作成する CloudFormation が実行されている状況が確認できると思います)

初期化の処理が正常に終わると、以下のメッセージが表示されます。

Your project has been successfully initialized and connected to the cloud!

2-2-3. API リソースの追加

Amplify CLI では、アプリケーションを構成する要素を「リソース」と呼びます。

最初に、Amplify プロジェクトの中核となる「API」リソースを作成します。
「API」リソースには AWS AppSync を使用する「GraphQL」と、Amazon API Gateway を使用する「REST」のいずれかを選択することができますが、今回は「REST」を使用します。

また、「API」リソースを作成する過程で、API のバックエンドとなる Lambda 関数を構成する「Function」リソース、データストアとなる DynamoDB を構成する「Storage」リソースも併せて作成します。

以下のコマンドを実行します。

$ amplify add api

作成する API の種類を選択します。
[REST] を選択して Enter キーを押します。

? Please select from one of the below mentioned services: (Use arrow keys)
 GraphQL 
❯ REST

作成する API の種類を選択します。
[REST] を選択して Enter キーを押します。

? Please select from one of the below mentioned services: (Use arrow keys)
 GraphQL 
❯ REST

「API リソース」の名前を指定します。[YYYYMMDDamplify] と入力して Enter キーを押します。(YYYYMMDD は本日の日付)

? Provide a friendly name for your resource to be used as a label for this category in the project: (apiXXXXXXXX) YYYYMMDDamplify

「API リソース」の名前を指定します。[YYYYMMDDamplify] と入力して Enter キーを押します。(YYYYMMDD は本日の日付)

? Provide a path (e.g., /book/{isbn}): (/items)

ここからは「Function」リソースに関する設定を行います。
Lambda 関数を新規に作成しますので、[Create a new Lambda function] を選択して Enter キーを押します。

? Choose a Lambda source (Use arrow keys)
❯ Create a new Lambda function

「Function」リソースの名前を指定します。
[YYYYMMDDamplify] と入力して Enter キーを押します。(YYYYMMDD は本日の日付)

? Provide a friendly name for your resource to be used as a label for this category in the project: (20200901amplifyXXXXXXXX) YYYYMMDDamplify

「Function」リソースの名前を指定します。
[YYYYMMDDamplify] と入力して Enter キーを押します。(YYYYMMDD は本日の日付)

? Provide a friendly name for your resource to be used as a label for this category in the project: (20200901amplifyXXXXXXXX) YYYYMMDDamplify

Lambda 関数の名前を指定します。
デフォルト値 [YYYYMMDDamplify] のまま Enter キーを押します。

? Provide the AWS Lambda function name: (20200901amplify)

Lambda 関数で使用するランタイムを指定します。
[NodeJS] を選択して Enter キーを押します。

? Choose the runtime that you want to use: (Use arrow keys)
  .NET Core 3.1 
  Go 
  Java 
❯ NodeJS 
  Python

使用する Lambda 関数のテンプレートを指定します。
[CRUD function for DynamoDB] を選択して Enter キーを押します。

? Choose the function template that you want to use: (Use arrow keys)
❯ CRUD function for DynamoDB (Integration with API Gateway) 
Hello World 
  Lambda trigger 
  Serverless ExpressJS function (Integration with API Gateway)

ここからは「Storage」リソースに関する設定を行います。
DynamoDB テーブルを新規に作成しますので、[Create a new DynamoDB table] を選択して Enter キーを押します。

? Choose a DynamoDB data source option (Use arrow keys)
 Use DynamoDB table configured in the current Amplify project 
❯ Create a new DynamoDB table

「Storage」リソースの名前を指定します。[YYYYMMDDamplify] と入力して Enter キーを押します。(YYYYMMDD は本日の日付)

? Please provide a friendly name for your resource that will be used to label this category in the project: (dynamoXXXXXXXX) YYYYMMDDamplify

DynamoDB テーブルの名前を指定します。
デフォルト値 [YYYYMMDDamplify] のまま Enter キーを押します。

? Please provide table name: (20200901amplify)

DynamoDB の最初の列 (属性) を指定します。
[Artist] と入力して Enter キーを押します。

? What would you like to name this column: Artist

属性のデータ型を指定します。
[string] を選択して Enter キーを押します。

? Please choose the data type: (Use arrow keys)
❯ string 
  number 
  binary 
  boolean 
  list 
  map 
  null 
(Move up and down to reveal more choices)

更に列 (属性) を追加するか聞かれますので、[y] を入力して Enter キーを押します。

? Would you like to add another column? (Y/n) y

DynamoDB の 2 番目の列 (属性) を指定します。
[Title] と入力して Enter キーを押します。

? What would you like to name this column: Title

属性のデータ型を指定します。
[string] を選択して Enter キーを押します。

? Please choose the data type: (Use arrow keys)
❯ string 
  number 
  binary 
  boolean 
  list 
  map 
  null 
(Move up and down to reveal more choices)

更に列 (属性) を追加するか聞かれますので、[n] を入力して Enter キーを押します。

? Would you like to add another column? (Y/n) n

パーティションキーに設定する属性を指定します。
[Artist] を選択して Enter キーを押します。

? Please choose partition key for the table: (Use arrow keys)
❯ Artist 
  Title

ソートキーを設定するか聞かれますので、[y] を入力して Enter キーを押します。

? Do you want to add a sort key to your table? (Y/n) y

ソートキーに設定する属性を指定します。
[Title] を選択して Enter キーを押します。

? Please choose sort key for the table: (Use arrow keys)
❯ Title

グローバルセカンダリインデックスを設定するか聞かれますので、[n] を入力して Enter キーを押します。

? Do you want to add global secondary indexes to your table? (Y/n) n

DynamoDB に Lambda トリガーを設定するか聞かれますので、[n] を入力して Enter キーを押します。

? Do you want to add a Lambda Trigger for your Table? (y/N) n

「Storage」リソースの設定が一通り終わりましたので、ここからは「Function」リソースの設定に戻ります。

Lambda 関数からアクセスするリソースを更に追加するか聞かれますので、[n] を入力して Enter キーを押します。

? Do you want to access other resources in this project from your Lambda function? (Y/n) n

Lambda 関数を繰り返しスケジュール実行するか聞かれますので、[n] を入力してEnterキーを押します。

? Do you want to invoke this function on a recurring schedule? (y/N) n

Lambda レイヤーの設定を行うか聞かれますので、[n] を入力して Enter キーを押します。

? Do you want to configure Lambda layers for this function? (y/N) n

Lambda 関数の内容を編集することができますが、今回は作成されたテンプレートをそのまま使いますので、[n] を入力して Enter キーを押します。

? Do you want to edit the local lambda function now? (Y/n) n

「Function」リソースの設定が一通り終わりましたので、最後に「API」リソースの設定に戻ります。

API へのアクセスを制限するかどうか聞かれますので、[n] を入力して Enter キーを押します。(Cognito を使ったアクセス制限は次のステップで行います)

? Restrict API access (Y/n) n

API にパスを追加するか聞かれますので、[n] を入力して Enter キーを押します。

? Do you want to add another path? (y/N) n

リソースの追加が正常に行われると、以下のメッセージが表示されます。

? Do you want to add another path? (y/N) n

2-2-4. API リソースのデプロイ

前の手順で Amplify プロジェクトに「リソース」を追加しました。
この時点では、リソースはPC (今回は Cloud9) のローカル上に Amplify プロジェクトの定義情報として存在しているのみです。
定義情報に基いて AWS 環境に実際にリソースを構築するには「デプロイ」操作を行います。

以下のコマンドを実行します。

$ amplify push

現在 Amplify プロジェクトに定義されている「リソース」の一覧とステータスが表示されます。
Operation 欄に表示されている「Create」は「定義が作成されたが、まだデプロイされていない」状態であることを示します。

これらのリソースを AWS 環境へデプロイするために、[y] を入力して Enter キーを押します。

✔ Successfully pulled backend environment demo from the cloud.

Current Environment: demo

| Category | Resource name   | Operation | Provider plugin   |
| -------- | --------------- | --------- | ----------------- |
| Storage  | 20200901amplify | Create    | awscloudformation |
| Function | 20200901amplify | Create    | awscloudformation |
| Api      | 20200901amplify | Create    | awscloudformation |

? Are you sure you want to continue? (Y/n) y

AWS 環境へのデプロイ処理が始まります。
デプロイ処理が終わるまで数分程度かかりますので、終わるまで待ちます。(画面上では AWS の各リソースを作成する CloudFormation が実行されている様子が確認できると思います)

デプロイ処理が成功すると、以下のメッセージが表示されます。

✔ All resources are updated in the cloud

デプロイによって、以下の AWS リソースが作成されています。
作成された各リソースは既に設定も行われており、特に内容を確認したり変更したりする必要はありませんが、時間のある方は作成されたリソースの内容を確認するとよいでしょう。

  • API Gateway REST API
    • YYYYMMDDamplify
  • Lambda 関数
    • YYYYMMDDamplify-demo
  • IAM ロール (Lambda実行ロール)
    • YYYYMMDDamplifyLambdaRoleXXXXXXXX-demo
  • DynamoDB テーブル
    • YYYYMMDDamplify-demo

2-2-5. Amplify Library のインストール

「Amplify Library」は、Amplify を使ったアプリケーションを構築する際に、クライアント側のアプリケーション (Web、モバイル) に組み込んで用いる SDK / ライブラリーです。
Webクライアントアプリケーション向けには、JavaScript 用の SDK に加えて「React」「Vue」「Angular」などの JavaScript フレームワーク用の UI コンポーネントが提供されており、UI コンポーネントを利用することでアプリケーションにリッチな UI を容易に実装することができます。

今回は、Amplify プロジェクトに「JavaScript 向けの Amplify Library」と「React 向けの UI コンポーネント」をインストールして利用可能にします。

以下のコマンドを実行します。

$ npm install aws-amplify @aws-amplify/ui-react

エラーが発生することなくインストールが完了することを確認します。

2-2-6. Web クライアントアプリケーションの構成

[src] フォルダに以下のファイルがあります。

  • [ApiGet.js]
  • [ApiPost.js]
  • [App.css]
  • [App.js]
  • [aws-logo.png]
  • [config.js]

こられのファイルを Amplifi プロジェクトの [YYYYMMDDamplify]-[src] フォルダの直下にコピーします。

画面左側のディレクトリツリーから [(ルートディレクトリ)]-[YYYYMMDDamplify]-[src] の階層を展開し、[src] ディレクトリをクリックして選択状態にします。

クリックすると拡大します

画面上部のメニューから [File]-[Upload Local Files...] を選択します。

クリックすると拡大します

こちらのウィンドウが表示されます。
アップロード先ディレクトリが「/YYYYMMDDamplify/src」であることを確認します。

アップロードするファイル群をウィンドウ内にドラッグ&ドロップします。
もしくは、[Select files] をクリックしてアップロード対象ファイルを指定しても構いません。

クリックすると拡大します

[App.css][App.js] の 2 ファイルは、アップロード先に既に同名ファイルが存在していますので上書きの確認を求められます。[Overwrite All] をクリックして上書きします。

クリックすると拡大します

lsコマンドを実行して、ファイルがアップロードされたことを確認します。

$ ls -l src
total 56
-rw-r--r-- 1 ec2-user ec2-user 2626 Sep  1 13:07 ApiGet.js
-rw-r--r-- 1 ec2-user ec2-user 2293 Sep  1 13:07 ApiPost.js
-rw-rw-r-- 1 ec2-user ec2-user 1350 Sep  1 13:07 App.css
-rw-rw-r-- 1 ec2-user ec2-user 1003 Sep  1 13:07 App.js
-rw-rw-r-- 1 ec2-user ec2-user  280 Sep  1 12:51 App.test.js
-rw-rw-r-- 1 ec2-user ec2-user  654 Sep  1 13:01 aws-exports.js
-rw-r--r-- 1 ec2-user ec2-user 2724 Sep  1 13:07 aws-logo.png
-rw-r--r-- 1 ec2-user ec2-user  160 Sep  1 13:07 config.js
-rw-rw-r-- 1 ec2-user ec2-user  366 Sep  1 12:51 index.css
-rw-rw-r-- 1 ec2-user ec2-user  503 Sep  1 12:51 index.js
-rw-rw-r-- 1 ec2-user ec2-user 2671 Sep  1 12:51 logo.svg
-rw-rw-r-- 1 ec2-user ec2-user 5086 Sep  1 12:51 serviceWorker.js
-rw-rw-r-- 1 ec2-user ec2-user  255 Sep  1 12:51 setupTests.js

リソース名を記述した設定ファイルを編集します。
画面左側のディレクトリツリーから [src] ディレクトリ直下のファイル [config] を右クリックして、[Open] を選択します。(vi コマンドを使用して編集しても構いません)

クリックすると拡大します

API 名を実際に作成した名前に書き換えて、ファイルを保存します。
(パス名は、ここまでの手順通りに実施していれば変更する必要はありません)

// TODO: 作成したREST APIの名前およびパスに書き換えてください
export const apiName = 'YYYYMMDDamplify';
export const basePath = '/items';

2-2-7. Web クライアントアプリケーションの動作確認

以下のコマンドを実行します。

$ npm start

アプリケーションが起動すると、以下のように表示されます。(数分間かかるので待ちます)

Compiled successfully!

You can now view 20200901amplify in the browser.

  Local:            http://localhost:8080
  On Your Network:  http://172.XX.XX.XX:8080

Note that the development build is not optimized.
To create a production build, use npm run build.

画面上部の [Preview] をクリックして [Preview Running Application] を選択します。

クリックすると拡大します

こちらの図のように Web クライアントアプリケーションが正常に表示されることを確認します。

クリックすると拡大します

「GET メソッド」「POST メソッド」がそれぞれ正常に動作することを確認します。
(まず「POST メソッド」を実行してデータを登録してから、「GET メソッド」を実行するとよいでしょう)

クリックすると拡大します

2-3. Cognitoによる認証をWebプリケーションへ追加する

2-3-1. Auth リソースの追加

作成した Web アプリケーションへ Cognito による認証機能を追加します。
Amplify プロジェクトに認証機能を提供する「Auth」リソースを追加します。

Ctl + c で実行を停止します。

以下のコマンドを実行します。

$ amplify add auth

設定をどのように行うのかを指定します。
[Default configuration] を選択して Enter キーを押します。

Do you want to use the default authentication and security configuration? (Use arrow keys)
❯ Default configuration 
  Default configuration with Social Provider (Federation) 
  Manual configuration 
  I want to learn more.

サインインに用いる項目を指定します。
[Username] を選択して Enter キーを押します。

How do you want users to be able to sign in? (Use arrow keys)
❯ Username 
  Email 
  Phone Number 
  Email or Phone Number 
  I want to learn more.

詳細な設定を行うかどうか聞かれます。
今回は標準の設定を用いますので、[No, I am done.] を選択して Enter キーを押します。

Do you want to configure advanced settings? (Use arrow keys)
❯ No, I am done. 
  Yes, I want to make some additional changes.

リソースの追加が正常に行われると、以下のメッセージが表示されます。

Successfully added auth resource 20200901amplifyXXXXXXXX locally

2-3-2. API リソースの更新

「Auth」リソースによる認証機能を追加しましたので、前節で作成した「API」リソースを認証に対応させる必要があります。
作成済みのリソースの設定を変更するには「amplify update」コマンドを使用します。

以下のコマンドを実行します。

$ amplify update api

変更対象の API の種類を指定します。
[REST] を選択して Enter キーを押します。

? Please select from one of the below mentioned services: (Use arrow keys)
  GraphQL 
❯ REST

変更対象の API リソースを指定します。
[YYYYMMDDamplify] を選択して Enter キーを押します。

? Please select the REST API you would want to update (Use arrow keys)
❯ 20200901amplify

変更の内容を指定します。
既存の API パスの設定を変更しますので、[Update path] を選択して Enter キーを押します。

? What would you like to do (Use arrow keys)
  Add another path 
❯ Update path 
  Remove path

変更対象の API パスを指定します。
[/items] を選択して Enter キーを押します。

? Please select the path you would want to edit (Use arrow keys)
❯ /items

変更後のパス名を指定します。
パス名は変更しないため、何も入力せずに Enter キーを押します。

? Provide a path (e.g., /book/{isbn}): (/items)

Lambda 関数を新たに作成するのか、既存のものを使用するのか指定します。
既存の Lambda 関数を使用するため、[Use a Lambda function already added in the current Amplify project] を選択して Enter キーを押します。

? Choose a Lambda source (Use arrow keys)
  Create a new Lambda function 
❯ Use a Lambda function already added in the current Amplify project

使用する Lambda 関数を指定します。
[YYYYMMDDamplify] を選択して Enter キーを押します。

? Choose the Lambda function to invoke by this path (Use arrow keys)
❯ 20200901amplify

API へのアクセスを制限するかどうかを指定します。
Cognito 認証と連係したアクセス制限を行うため、[y] を入力して Enter キーを押します。

? Restrict API access (Y/n) y

認証されたユーザーのみにアクセスを許可するのか、ゲストユーザーにもアクセスを許可するのかを指定します。

今回は認証されたユーザーのみにアクセスを許可するため、[Authenticated users only] を選択して Enter キーを押します。

? Who should have access? (Use arrow keys)
❯ Authenticated users only 
  Authenticated and Guest users

認証されたユーザーに対してどのAPI操作を許可するのかを指定します。
[create][read][update][delete] の全てを選択状態にして、Enter キーを押します。

? What kind of access do you want for Authenticated users? (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ create
 ◉ read
 ◉ update
 ◉ delete

※ 複数の項目を選択する場面では、カーソルキーの上下で項目を選択してスペースキーを押すことで選択状態にします (もう一度スペースキーを押すと選択状態が解除されます)
選択が終わりましたら Enter キーを押します。

リソースの更新に成功すると、以下のメッセージが表示されます。

Successfully updated resource

2-3-3. Auth リソースおよび API リソースのデプロイ

前節と同様に、Amplify プロジェクト上にリソースを追加した後は、AWS 環境に実際にリソースを構築するために「デプロイ」操作を行います。
また、作成済みの「API」リソースの更新についても、更新内容を AWS 環境に反映するために「デプロイ」操作を行う必要があります。

以下のコマンドを実行します。

$ amplify push

現在 Amplify プロジェクトに定義されている「リソース」の一覧とステータスが表示されます。
「Auth」リソースの Operation 欄が「Create」と表示されています。
また、「Api」リソースの Operation 欄は「Update」と表示されており、これは「定義が更新されたが、まだデプロイされていない」状態であることを示します。

これらのリソースを AWS 環境へデプロイするために、[y] を入力して Enter キーを押します。

✔ Successfully pulled backend environment demo from the cloud.

Current Environment: demo

| Category | Resource name           | Operation | Provider plugin   |
| -------- | ----------------------- | --------- | ----------------- |
| Auth     | 20200901amplifyXXXXXXXX | Create    | awscloudformation |
| Api      | 20200901amplify         | Update    | awscloudformation |
| Storage  | 20200901amplify         | No Change | awscloudformation |
| Function | 20200901amplify         | No Change | awscloudformation |

? Are you sure you want to continue? (Y/n) y

AWS 環境へのデプロイ処理が始まります。
デプロイ処理が終わるまで数分程度かかりますので、終わるまで待ちます。(画面上では AWS の各リソースを作成する CloudFormation が実行されている状況が確認できると思います)

デプロイ処理が成功すると、以下のメッセージが表示されます。

✔ All resources are updated in the cloud

デプロイによって、以下の AWS リソースが作成されています。
作成された各リソースは既に設定も行われており、特に内容を確認したり変更したりする必要はありませんが、時間のある方は作成されたリソースの内容を確認するとよいでしょう。

  • Cognito ユーザープール
    • YYYYMMDDamplifyXXXXXXXX_userpool_XXXXXXXX-demo
  • Cognito ID プール
    • YYYYMMDDamplifyXXXXXXXX_identitypool_XXXXXXXX__demo
  • IAMロール
    • snsXXXXXXXXXXXXX-demo
    • upClientLambdaRoleXXXXXXXXXXXXX-demo
  • Lambda関数
    • amplify-YYYYMMDDamplify-demo-UserPoolClientLambda-XXXXXXXXXXXXX

また、以下の既存の AWS リソースに対して変更が行われています。
大きな変更点は「API Gateway REST API」に対して「AWS_IAM」の認可設定が追加されていることです。

  • API Gateway REST API
    • YYYYMMDDamplify
  • Lambda関数
    • YYYYMMDDamplify-demo
  • IAMロール(認証されたユーザーに割り当てられるIAMロール)
    • amplify-YYYYMMDDamplify-demo-XXXXX-authRole

「認証されたユーザーに割り当てられる IAM ロール」については、ここまで説明していませんでしたが、実は最初の「Amplify プロジェクトの初期化 (amplify init)」の際に既に作成されています。(同時に「認証されていないユーザーに割り当てられる IAM ロール」も作成されています)

「API」リソースに対してアクセス制限を設定したことにより、これらの IAM ロールに対して API Gateway REST API の呼び出し許可を与えるポリシーが登録されています。

2-3-4. Web クライアントアプリケーションの構成

API を認証に対応させるために、JavaScript ファイル [App.js] の内容を修正します。
Cloud9 のエディタ、または vi コマンドを使って、[src] ディレクトリ直下の [App.js] ファイルを開きます。

修正箇所は 3 点あります。
まず、ファイル冒頭の「import」の記述群に以下の行を追加します。

import React from 'react';
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';

最終行によって、認証を行う 2 つのコンポーネントをインポートします。

次に、ファイルの 16 行目付近にある「<div className=”App>」の行の次に、以下の行を追加します。

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <AmplifySignOut />
        <header className="App-header">

この行によって、画面に「サインアウト」ボタンのコンポーネントを配置します。

最後に、ファイルの最終行にある以下の行を、下記のように修正します。

export default App;


export default withAuthenticator(App);

この行によって、アプリケーションに「サインアップ」「サインイン」などの認証機能を提供するコンポーネントを適用します。全ての修正が終わりましたら、ファイルを保存します。

2-3-5. Web クライアントアプリケーションの動作確認

以下のコマンドを実行します。

$ npm start

アプリケーションが起動すると、以下のように表示されます。(数分間かかりますので待ちます)

Compiled successfully!

You can now view 20200901amplify in the browser.

  Local:            http://localhost:8080
  On Your Network:  http://172.XX.XX.XX:8080

Note that the development build is not optimized.
To create a production build, use npm run build.

画面上部の [Preview] をクリックして [Preview Running Application] を選択します。

下図のように Web クライアントアプリケーションが正常に表示されることを確認します。

クリックすると拡大します

まず、 [Create account] をクリックしてサインアップを行います。

クリックすると拡大します

ユーザー名、パスワード、メールアドレスを入力して [CREATE ACCOUNT] をクリックします。(電話番号の欄は未入力で構いません)

クリックすると拡大します

メールで確認コードが送られてきますので、入力して [CONFIRM] をクリックします。

クリックすると拡大します

自動的にサインインが行われて、API テストの画面が表示されます。
「GETメソッド」「POSTメソッド」が実行可能なことを確認します。

画面上部の [SIGN OUT] をクリックすると、サインアウトが行われ、最初のサインイン画面に戻ります。

クリックすると拡大します

このように、JavaScript に 3 行ほど追加するのみで、サインアップ・サインイン等のフォームやコードを記述することなく、アプリケーションに認証機能を追加することができました。

今回は「認証されたユーザー」のみに API のアクセス権限を与えていますが、ラボ 1 のように「認証されたユーザー」「認証されていないユーザー」それぞれに異なるアクセス権限を与えることも可能です。
その場合は、今回より少し複雑なコードを記述する必要があります。

2-4. Amplifyアプリケーションをホスティングする

ここまでの手順では、作成した Amplify アプリケーションをローカル環境 (Cloud9) で実行してきましたが、本番運用では公開 Web サイトとして公開する必要があります。

「Amplify Console」のマネージドなホスティング機能を使うと、S3 静的ウェブホスティングや CloudFront といったホスティング環境を自分で用意することなく、簡単に Amplify アプリケーションを公開することができます。

(なお、Amplify Console にはホスティング機能の他にも、GitHub や AWS CodeCommit と統合可能な CI/DI 機能がありますが、今回は利用しません)

2-4-1. ホスティングの設定

Ctl + c で停止します。cd でディレクトリを environment から yyyymmddamplify に移動します。

以下のコマンドを実行します。

$ amplify add hosting

ホスティングの方式を指定します。
今回は Amplify Console が提供するマネージドなホスティング機能を利用しますので、[Hosting with Amplify Console] を選択して Enter キーを押します。

? Select the plugin module to execute (Use arrow keys)
❯ Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
  Amazon CloudFront and S3

CI/CD の方式を指定します。
今回は Git ベースの CI/CD 機能を利用しませんので、[Manual deployment] を選択して Enter キーを押します。

? Choose a type (Use arrow keys)
  Continuous deployment (Git-based deployments) 
❯ Manual deployment 
  Learn more

ホスティングの設定が正常に行われると、以下のメッセージが表示されます。

You can now publish your app using the following command:

Command: amplify publish

2-4-2. アプリケーションの公開

以下のコマンドを実行します。

$ amplify publish

リソースの「デプロイ」を行う時と同様に、以下のような画面が表示されます。
ホスティングの設定は「リソース」として扱われており、Operation 欄が「Create」と表示されています。

ホスティング環境を公開するために、[y] を入力して Enter キーを押します。

✔ Successfully pulled backend environment demo from the cloud.

Current Environment: demo

| Category | Resource name           | Operation | Provider plugin   |
| -------- | ----------------------- | --------- | ----------------- |
| Hosting  | amplifyhosting          | Create    | awscloudformation |
| Storage  | 20200901amplify         | No Change | awscloudformation |
| Function | 20200901amplify         | No Change | awscloudformation |
| Api      | 20200901amplify         | No Change | awscloudformation |
| Auth     | 20200901amplifyXXXXXXXX | No Change | awscloudformation |

? Are you sure you want to continue? (Y/n) y

ホスティング環境を公開する処理が始まります。
処理が終わるまで数分程度かかりますので、終わるまで待ちます。

処理が成功すると、以下のメッセージが表示されます。
公開サイトの URL が表示されていることを確認します。

✔ Successfully pulled backend environment demo from the cloud.

Current Environment: demo

| Category | Resource name           | Operation | Provider plugin   |
| -------- | ----------------------- | --------- | ----------------- |
| Hosting  | amplifyhosting          | Create    | awscloudformation |
| Storage  | 20200901amplify         | No Change | awscloudformation |
| Function | 20200901amplify         | No Change | awscloudformation |
| Api      | 20200901amplify         | No Change | awscloudformation |
| Auth     | 20200901amplifyXXXXXXXX | No Change | awscloudformation |

? Are you sure you want to continue? (Y/n) y
✔ Deployment complete!
https://demo.XXXXXXXXXXXXXX.amplifyapp.com

PC の Web ブラウザで、表示された公開サイトの URL へアクセスします。
アプリケーションの画面が表示されることを確認します。
また、サインインや API の操作を行い、ローカル環境と同様に操作できることを確認します。

クリックすると拡大します


3. 後片付け

下記、後片付けを行います。
この作業まで完了していない場合、継続して課金が発生しますので、必ず実施してください。

  • 準備
    • Cloud9環境の削除
      • [YYYYMMDDserverless]

  • ラボ1:サーバーレスアプリケーションを step-by-step で構築する
    • Cognito IDプールの削除
      • [YYYYMMDDserverless]
    • Cognitoユーザープールの削除
      • [YYYYMMDDserverless]
    • API Gateway(API)の削除
      • [YYYYMMDDserverless]
    • Lambda関数の削除
      • [YYYYMMDDserverlessRead]
      • [YYYYMMDDserverlessWrite]
    • DynamoDBテーブルの削除
      • [YYYYMMDDserverless]
    • IAMロールの削除
      • [YYYYMMDDserverlessLambdaRole]
      • [Cognito_YYYYMMDDserverlessAuth_Role]
      • [Cognito_YYYYMMDDserverlessUnauth_Role]
    • IAMポリシーの削除
      • [YYYYMMDDserverlessLambdaPolicy]
      • [YYYYMMDDserverlessAPIGatewayGetAndPostPolicy]
      • [YYYYMMDDserverlessAPIGatewayGetOnlyPolicy]

  • ラボ 2:Amplify を使ってサーバーレスアプリケーションを構築する
    • Amplify プロジェクトを削除するコマンドを実行することで、AWS 環境にデプロイしたリソースを全て削除することができます。
      Amplifyプロジェクトのディレクトリに移動して、以下のコマンドを実行します。
$ amplify delete

後片付けは以上です。


4. まとめ

いかがでしたでしょうか ?
サーバーレスの動作イメージをつかむのに、少しでもこの記事が役に立てば幸いです!


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

プロフィール

亀田 治伸
アマゾン ウェブ サービス ジャパン合同会社 エバンジェリスト

兵庫県伊丹市出身。米国州立南イリノイ大学卒業。
認証系独立 ASP 、動画・音楽配信システム構築、決済代行事業者を経て現職。ユーザー視点に立ったわかりやすい AWS のサービス解説を心掛ける。
AWS のどんなサービスでも 1 分づつ資料なしで説明することができる、という特技を持つ自称【AWSマニア】

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する