kakakakakku blog

Weekly Tech Blog : Keep on Learning 👍

CircleCI 2.0 + Apex で Lambda をデプロイする

Lambda をデプロイする場合,最近だと Serverless Framework もしくは AWS Serverless Application Model を使う場面が多いけど,他の AWS サービスに依存せず Lambda だけをデプロイしたい場合には Apex も積極的に使っている.要件がシンプルな場合に特に便利で,過去にも事例を記事にしている.

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

CircleCI 1.0 + Apex

今までは「CircleCI 1.0 + Apex」という組み合わせで Lambda をデプロイしていた.特に難しいことはなく,以下のようなシンプルな circle.yml を作成して,CircleCI 上で毎回 Apex をインストールしていた.ただし,8月末に CircleCI 1.0 のサポートが終了するため,そろそろ移行を考える必要があった.

machine:
  timezone: Asia/Tokyo

dependencies:
  post:
    - curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sudo sh
    - apex version

deployment:
  master:
    branch: master
    commands:
      - apex deploy

Dockerized Apex

CircleCI 2.0 は Docker コンテナを使ってジョブを実行するため,Apex のコンテナが必要になる.ただし Apex 公式では提供されていなく,あまり良さそうなものもなかったため,今回 Alpine ベースで軽量な Dockerized Apex を作成した.バージョンは v1.0.0-rc2 と v0.16.0 をサポートしている.Docker イメージは kakakakakku/apex - Docker Hub に公開した.

github.com

CircleCI 2.0 + Apex

「CircleCI 2.0 + Apex」の場合は CircleCI 2.0 の記法で .circleci/config.yml を作成して,Dockerized Apex を使えば,今まで通り Lambda をデプロイできる.Docker コンテナを使うことにより,実行時間の短縮にも繋がり,メリットもある.

version: 2

jobs:
  deploy:
    docker:
      - image: kakakakakku/apex
    steps:
      - checkout
      - run: apex version
      - run: apex deploy

workflows:
  version: 2
  apex:
    jobs:
      - deploy

CircleCI の Environment Variables で,以下の環境変数を設定するのを忘れずに!

  • AWS_REGION
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

f:id:kakku22:20180508090052p:plain

(検証環境でデプロイをしてみた結果)

まとめ

  • CircleCI 2.0 + Apex でも Lambda をデプロイすることができた
  • CircleCI 2.0 のために Dockerized Apex を作成した

関連記事

CircleCI 2.0 の新機能「ワークフロー機能」の紹介を前に書いたから合わせて読んでもらえると!

kakakakakku.hatenablog.com

Lambda / Kinesis / DynamoDB / X-Ray などを組み合わせた実装を学べる「サーバーレスアプリケーション開発ガイド」を読んだ

今月発売されたばかりの「サーバーレスアプリケーション開発ガイド」を読んだので,書評をまとめたいと思う.著者の西谷さん,献本ありがとうございます!

Amazon Web Servicesを使ったサーバーレスアプリケーション開発ガイド

Amazon Web Servicesを使ったサーバーレスアプリケーション開発ガイド

  • 作者:西谷 圭介
  • 発売日: 2018/03/16
  • メディア: 単行本(ソフトカバー)

なお,サポートページからソースコードをダウンロードできる.コマンドもソースコードもそこそこ量があるため,写経せずに試したいという人はダウンロードして使うと良いかと.

book.mynavi.jp

概要

「サーバレスとは何か?」という解説からはじまり,実際に数種類の「サーバレスアプリケーション」を実装しながら理解を深めていく流れになっている.特に,多くの AWS サービスを組み合わせて学べる点が素晴らしく,例えば X-Ray などは,僕もまだ試したことがなかったので,今回学ぶことができた.実装する「サーバレスアプリケーション」ごとに,組み合わせる AWS サービスをザッと挙げる.こんなにある!

  • Amazon CloudWatch のアラームをトリガーに自動処理をする
    • Kinesis
    • CloudWatch
    • SNS
    • Lambda
  • Web サイトの状態を定期的にチェックする
    • Lambda
    • CloudWatch Events
  • Amazon Kinesis を使って Twitter のデータを受け取る
    • EC2
    • Kinesis
    • Lambda
    • DynamoDB
  • 写真投稿サイト
    • API Gateway
    • Lambda
    • DynamoDB
    • Rekognition
    • S3
    • Cognito
    • CloudFormation
    • Serverless Application Model (AWS SAM)
  • デリバリプロセスの自動化
    • CloudFormation
    • Serverless Application Model (AWS SAM)
    • CodeBuild
    • CodePipeline
  • トラブルシューティング
    • CloudWatch
    • CloudWatch Logs
    • X-Ray

本書の特徴は「ほぼ全てのオペレーションを AWS CLI で行う」という点だと思う.管理コンソールのデザインが変わっても AWS CLI のオペレーションは大幅に変わらないというメリットがあるし,オペレーションを積極的に Infrastructure as Code にするという意味でも AWS CLI をベースに学べるのはメリットだと思う.ただし,管理コンソールを意識しなくなるため,ちょっとでも気を抜くと「今,何をしてるんだっけ?」と方向性を見失ってしまう場面があった.このあたりはトレードオフだし,西谷さんのブログ記事にも意図が詳細に書かれている.

keisuke69.hatenablog.jp

Kinesis リシャーディング

まず「Amazon CloudWatch のアラームをトリガーに自動処理をする」を実際に試してみた.アーキテクチャは以下のようになっていて,Kinesis のデータストリームに閾値以上のレコードが登録された場合に,自動的にリシャーディングを行う.

f:id:kakku22:20180326204618p:plain

Kinesis にレコードを登録するために,以下の put-records.py を使った(データストリーム名は sample となる).AWS CLI は量が多くなってしまうため,本書を読んでもらえればと!

import boto3
import datetime
import time
import uuid

kinesis = boto3.client('kinesis')
stream_name = 'sample'

partition_key = str(uuid.uuid4())
data = datetime.datetime.utcnow().strftime('%s')

for i in range(15):
    kinesis.put_record(
        StreamName=stream_name,
        Data=data,
        PartitionKey=partition_key,
    )

作成した Lambda 関数の構成は,以下のようになっている.

f:id:kakku22:20180326204947p:plain

実際にリシャーディングを行った結果が以下となる.ちゃんと OpenShardCount の値が 1 → 2 に変わっている.

# Before
$ aws kinesis describe-stream-summary --stream-name sample
{
    "StreamDescriptionSummary": {
        "OpenShardCount": 1,
        "EncryptionType": "NONE",
        "StreamStatus": "ACTIVE",
        "StreamName": "sample",
        "StreamARN": "arn:aws:kinesis:ap-northeast-1:111111111111:stream/sample",
        "EnhancedMonitoring": [
            {
                "ShardLevelMetrics": []
            }
        ],
        "StreamCreationTimestamp": 1521993626.0,
        "RetentionPeriodHours": 24
    }
}

# Put
$ python put-records.py

# After
$ aws kinesis describe-stream-summary --stream-name sample
{
    "StreamDescriptionSummary": {
        "OpenShardCount": 2,
        "EncryptionType": "NONE",
        "StreamStatus": "ACTIVE",
        "StreamName": "sample",
        "StreamARN": "arn:aws:kinesis:ap-northeast-1:111111111111:stream/sample",
        "EnhancedMonitoring": [
            {
                "ShardLevelMetrics": []
            }
        ],
        "StreamCreationTimestamp": 1521993626.0,
        "RetentionPeriodHours": 24
    }
}

X-Ray

トラブルシューティングの事例として紹介されている X-Ray も実際に試してみた.設定は特に難しくなく,Lambda のトレースモードを有効にして,あとは X-Ray の結果を見るだけだった.X-Ray は今まで使ったことがなかったので,実際に処理内部のトレース結果が見れて良かった.

$ aws lambda update-function-configuration \
--function-name s3-get-object --tracing-config Mode=Active

f:id:kakku22:20180326205003p:plain

まとめ

  • 「サーバーレスアプリケーション開発ガイド」を読んだ
  • AWS サービスを組み合わせて数種類のアプリケーションを実装できた
  • Lambda だけじゃなく Kinesis / DynamoDB / AWS SAM などに興味があるなら読むべき
  • 本書のメインコンテンツとも言える「写真投稿サイト」は Vue.js で実装されていてフロントエンドの勉強にもなった
    • 途中まで写経してたけど,量が多くて,途中からソースコードをダウンロードして進めた

関連記事

去年に読んだ「サーバーレスシングルページアプリケーション」と似ている部分も多かった.ただし,フロントエンドは jQuery → Vue.js になっているし,組み合わせる AWS サービスも多いし,今から読むなら「サーバーレスアプリケーション開発ガイド」かなぁーと.

kakakakakku.hatenablog.com

同じく去年に読んだ「実践 AWS Lambda」も関連書籍と言える.もし AWS CLI メインで改版されるなら,もう1度読む!

kakakakakku.hatenablog.com

CROSS 2017 : Serverless Ninja Warriors でパネルディスカッションに参加してきた

今日 9/8 に横浜で開催された CROSS 2017 で,パネルディスカッションに参加してきた.テーマは Serverless Ninja Warriors で,サーバレスのガチ勢に囲まれて緊張したけど,楽しかったし,モチベーションも高まった.ありがとうございました!

2017.cross-party.com

資料

自己紹介として,簡単な資料を作成して最初に話をした.SpeakerDeck にアップロードするほどでもないため,そのまま画像で貼ってしまう.

話した内容としては,ザッと以下のような感じ.僕のポジションとしては「非ガチ勢」だったので,サーバレスに興味があるけど試したことがない人や,Lambda を管理コンソールで実装していて運用に困っている人などの参考になれば良いなと思っていた.

  • 個人的なサーバレスの定義は「FaaS の特性(ある意味で制約とも言える)を活かしたアーキテクチャ全般」と考えている(今のところ…)
  • サーバレスに限らず,スモールスタートを意識してチームに成功体験を作ると,導入障壁が下がる
    • そのために社内ツール系は最適
    • デプロイ/テストなど,ラストマイルも意識するとプロダクションレディな知見が得られる
  • CircleCI + Apex の組み合わせは非常に便利
    • Apex は複数ファンクションの管理も,複数環境へのデプロイもできる
    • ローカル環境は python-lambda-local を使っている

f:id:kakku22:20170908175225j:plain

f:id:kakku22:20170908175347j:plain

f:id:kakku22:20170908175406j:plain

質疑応答など

「CloudWatch Events など,Lambda 以外の AWS リソースはどのように管理しているのか?」という質問があり,ここは現状だと管理コンソールでポチポチしている.サービス全体で CloudFormation を導入するべきだと思うし,Apex + Terraform の構成にしても良いけど,現時点では既存のリソースへの影響が怖くて対応できていないという感じ.やらなきゃ!

「環境ごとにどのようにデプロイしているのか?」という質問もあり,これは Apex の Multiple Environments 機能を使っている.さらに Lambda の環境変数を Multiple Environments の定義ファイルに書けるため,それで invoke する Lambda の ARN などを管理している.あと IAM でも厳格にリソースを制限している.詳細は以下の記事を参照してもらえればと!

kakakakakku.hatenablog.com

補足など

ローカル環境の話が全体的にあまり無かったけど,僕は python-lambda-local を使っている.詳しくは以下の記事に!

kakakakakku.hatenablog.com

今日は話すタイミングが無かったけど,Apex の話をすると「Go 動くんでしょ?」とよく聞かれたりする.前に発表した資料の後半にまとめているけど,結局は Node.js の子プロセスで Go バイナリを動かして,プロセス間通信をしているだけなので,絶対に必要なら検討しても良いけど,AWS 公式でサポートされるまで待っても良いのでは?というのが個人的な判断かな.

kakakakakku.hatenablog.com

今回紹介したアーキテクチャは CloudWatch Events で Lambda を起動して SQS からメッセージを取得するため,ポーリング系の処理になっている.現時点では SQS のキュー操作は Lambda のイベントになっていないため,イベントドリブンにはなっていないけど,公式サポートが入ると嬉しいなとは思う.

会場で感じたこと

会場の各ホールが分離されていないため,隣のセッションの声がガンガン入ってきたり,マイクで音を拾えないと後ろの席まで届かなかったり,大規模カンファレンスの会場としては適していないのではないかなと思った.パネルディスカッションの序盤でそれに気付いたため,僕はかなり大きな声で話すようにした.

まとめ

今回パネルディスカッションに参加させてもらえて非常に刺激的だった.サーバレスとは何か?という疑問を自分なりに考え直せたことも良かったし,なによりも,パネルディスカッションに一緒に参加した皆さんの技術レベルが本当に高く,ディスカッションをするだけでも楽しかった.モチベーションも高まったし,もっともっと攻めて行かないとなと感じた.本当にありがとうございました!

Lambda (Python) をローカル環境で実行できる python-lambda-local を試した

Lambda (Python) のローカル環境を整えるため,python-lambda-local を試した.python-lambda-local を使うと,Python コードを Lambda にデプロイすることなく動作確認ができるようになる.Apex を使っていれば apex invoke でお手軽に実行することもできるけど,やはり Lambda に依存せず,単独で実行したいという要件はある.Lambda のローカル環境は誰に聞いても困っている印象がある.

github.com

前提

インストールは pip を実行するだけで良い.また,今回紹介するディレクトリ構成は Apex で Lambda をデプロイする前提にしている.

$ pip install python-lambda-local

BluePrint : hello-world-python

まずは AWS に依存せず,Python ライブラリにも依存せず,単体で実行できるコードとして,BluePrint の hello-world-python を試した.ディレクトリ構成は以下のようになっている.

.
├── event.json
├── functions
│   └── myfunc
│       └── main.py
└── project.json

myfunc/main.py は以下のようなコードにした.シンプルにイベントを受けて,表示するだけの実装にしている.

import json

print('Loading function')

def lambda_handler(event, context):
    print("function = myfunc, value1 = " + event['key1'])
    print("function = myfunc, value2 = " + event['key2'])
    print("function = myfunc, value3 = " + event['key3'])

ここで python-lambda-local で実行すると以下のようになる.オプションとしては --function でハンドラを指定して,-t でタイムアウトを指定する.あとは Python コードとイベントを指定する.

$ python-lambda-local --function lambda_handler --timeout 5 functions/myfunc/main.py event.json
Loading function
[root - INFO - 2017-07-30 16:16:36,272] Event: {u'key3': u'value3', u'key2': u'value2', u'key1': u'value1'}
[root - INFO - 2017-07-30 16:16:36,273] START RequestId: 9e683e91-821f-4680-b8e2-bcf37c7eb44f
function = myfunc, value1 = value1
function = myfunc, value2 = value2
function = myfunc, value3 = value3
[root - INFO - 2017-07-30 16:16:36,273] END RequestId: 9e683e91-821f-4680-b8e2-bcf37c7eb44f
[root - INFO - 2017-07-30 16:16:36,274] RESULT:
None
[root - INFO - 2017-07-30 16:16:36,274] REPORT RequestId: 9e683e91-821f-4680-b8e2-bcf37c7eb44f    Duration: 0.38 ms

簡単に動いた!

BluePrint : s3-get-object-python

次は AWS に依存していて,Python ライブラリにも依存するコードとして,BluePrint の s3-get-object-python を試した.ディレクトリ構成は以下のようになっている.

.
├── event.json
├── functions
│   └── myfunc
│       ├── main.py
│       ├── requirements.txt
│       └── (ライブラリいろいろ)
└── project.json

myfunc/main.py は以下のようなコードにした.S3 Put のイベントを受けて,Put されたファイルの Content-Type を表示している.なお,S3 Put のイベントは量が多いため,割愛するが,公式ドキュメントにちゃんと載っている.

docs.aws.amazon.com

from __future__ import print_function

import json
import urllib
import boto3

print('Loading function')

s3 = boto3.client('s3')

def lambda_handler(event, context):

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8'))
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

ここで python-lambda-local で実行すると以下のようになる.

$ python-lambda-local --function lambda_handler --library functions/myfunc --timeout 5 functions/myfunc/main.py event.json

[root - INFO - 2017-07-30 23:14:18,203] START RequestId: 07669e19-37af-4640-ae65-859dadd758ed
[botocore.vendored.requests.packages.urllib3.connectionpool - INFO - 2017-07-30 23:14:18,214] Starting new HTTPS connection (1): s3-ap-northeast-1.amazonaws.com
CONTENT TYPE: text/plain
[root - INFO - 2017-07-30 23:14:18,721] END RequestId: 07669e19-37af-4640-ae65-859dadd758ed
[root - INFO - 2017-07-30 23:14:18,722] RESULT:
text/plain
[root - INFO - 2017-07-30 23:14:18,722] REPORT RequestId: 07669e19-37af-4640-ae65-859dadd758ed    Duration: 517.71 ms

問題なく動いた!

気を付けるポイント

python-lambda-local を使ってみて,数点気を付けるポイントがあった.

1. /lib ではなくルートディレクトリにライブラリをインストールする

公式ドキュメントにも書いてある通り,pip で Python ライブラリをインストールする場合,Lambda の場合はルートディレクトリに配置する必要がある.よって,python-lambda-local のドキュメントにあるような /lib ディレクトリを用意するのではなく,main.py と同じルートディレクトリにそのままインストールする必要がある.具体的には以下のようなコマンドになる.

$ pip install --requirement functions/myfunc/requirements.txt --target functions/myfunc

docs.aws.amazon.com

2. requirements.txt に boto3 を明示する必要がある

次も公式ドキュメントに書いてある内容だが,Lambda にはデフォルトで Boto 3 がインストールされているため,わざわざ requirements.txt に書く必要がないようになっている.ただし,ローカル環境で実行する場合には必要なので,結果的に書く必要があった.今回は以下のファイルを用意した.

urllib
boto3

まとめ

  • Lambda (Python) のローカル環境を整えるために python-lambda-local を試してみた
  • 簡単に使えたし AWS サービスとの接続もできたため一般的なユースケースは網羅できそう
  • ライブラリのインストールディレクトリなど少し気を付けるポイントはある

関連記事

Apex を使って複数環境にデプロイする方法は前にまとめてある.Apex ユーザーには参考になる内容だと思う.

kakakakakku.hatenablog.com

AWS をフル活用して「サーバレス」な SPA を実装できる「サーバーレスシングルページアプリケーション」を読んだ

6月末に O'Reilly から出版された「サーバーレスシングルページアプリケーション」を読んだ.ただ読むだけじゃ理解度が浅くなってしまうかもしれないなと感じて,今回は全ての実装を写経してみた.そのため少し時間はかかってしまったけど,フロントエンドには苦手意識があったし,今まで SPA の実装もしたことがなかったので,前半部分は特にワクワクしながら楽しめた.今回,監訳者の id:yoshidashingo にご献本を頂き,本当に感謝しかありません.ありがとうございます!と同時に,ガッツリ読もうと意気込んだタイミングで仕事に忙殺されてしまったりして,書評のタイミングが遅れてしまったのはすみません!

どんなものを実装したのか?

まず最初に,本書でどんなものを実装したのか?を紹介したいと思う.本書の表紙に描かれてるようなダッシュボードサイトではなく(最初はちょっと期待してしまった笑),LearnJS という名前の「JavaScript プログラミングパズル」を実装する.僕が実際に実装したアプリケーションのキャプチャを以下に載せておく.

f:id:kakku22:20170716152327p:plain f:id:kakku22:20170716152335p:plain

ちゃんと SPA になっていて,ハッシュイベントの変更をトリガーして次のページが表示される.app.js で以下のようなルーティングを定義するため,実際に遷移する URL は /#problem-1 や /#profile になる.今までは Rails など一般的なウェブアプリケーションの経験が多かったので,実際に自分で実装した SPA が動くと「おおおー!」という感動があった.

var routes = {
  '#problem': learnjs.problemView,
  '#profile': learnjs.profileView,
  '#': learnjs.landingView,
  '': learnjs.landingView
};

実際に以下の公式アプリケーションをすぐに試せる.

技術スタック

本書のサブタイトルにもある通り,AWS を活用して「サーバレス」を実現している.具体的には S3 からアプリケーションを配信し,Google のソーシャルログインには Cognito を使う.さらに自分の解答を DynamoDB に保存し,既に正解している問題ページを表示したときには,その解答を初期表示できるようになっている.また API Gateway + Lambda から DynamoDB に接続してエンドポイントを提供するところも解説されている.

SPA の部分は,React や Vue.js などではなく jQuery 2.1 を使う.非同期処理が必要な部分は jQuery.Deferred を使う. JavaScript のテストには Jasmine + Spy を使って,テストがしにくい部分もモックでテストできるようになっている.

素晴らしかったこと

デプロイファースト

LearnJS の雛形を GitHub から取得して,ローカル起動が確認できたら,すぐに S3 に本番デプロイしよう!という流れから始まる.これは本当に素晴らしいと思う.僕が好きな「ThoughtWorks アンソロジー」に書かれている「ラストマイル」の話と同じで,デプロイなど運用系のタスクを最後まで残しておくと,潜在的な問題が最後に露見するというものだ.本書では最初にいきなりデプロイをして,その後も章ごとに必ずデプロイをする.ローカルで動いているものが,全く同じように S3 でも動くのは,当たり前だけど非常に重要だと思う.同時にそれを支えるのは,便利スクリプト sspa なので,ここも参考になった.

github.com

テストファースト

最初からテストファーストで進んでいくため,例えば learnjs.showView 関数を実行したときの期待値を先にテストコードとして実装し,エラーを確認し,次に関数を実装し,テストが通ることを確認する.まさに TDD を体験できるのも本書の良さだと思う.今回特に写経をしながら進めたため,ミスによって動かなくなったケースが多くあった.そういうときにも,テストを実行して,期待値と合わない部分を特定することによってミスの発見を効率化できたので,実体験としてもテストファーストの恩恵を受けることができた.

f:id:kakku22:20170716152459p:plain

ハッシュイベント

今回実装した SPA のキモはハッシュイベントだったと思う.window.location.hash に変更があったときに window.onhashchange でトリガーして,ルーティングに飛ばした.また2章ではブラウザバックしても何も動かなかった部分が,3章でエイリアスルートを追加することによって動くようになった.このあたりを知れたのも個人的には大きかった.

リファクタリング

本書ではとにかく「小さく作る」ことが重要視されているため,例えば,最初は /#problem-1 ためだけの実装をして,動作確認が終わったら問題番号の部分をパラメータ化して /#problem-* に対応するルーティングを実装していく.他にも Correct! と Incorrect! の表示を作って動作確認をしてからフェードインの効果を追加するなど,リファクタリングを繰り返し行なっていく.この流れも参考になる.よく仕事でも「過剰に汎用化しすぎて使えない」ものがあったりして,改めて「小さく作る」ことを意識したいとも思った.

Cognito

実は今まで Cognito を使ったことがなく,今回初体験だった.今回は Google+ API を使った IdP 接続を実装した.とにかく簡単に実現できたし,この部分をフルマネージドにできるのも効果的だなと思った.本書では使うことはなかったが,Cognito User Pools も検証してみたい.今まで機会がなく使ったことがなかった Cognito に少しでも触れられたのも良かった.

API Gateway + Lambda + DynamoDB

個人的には使ったことがあり,解説の部分はある程度流し読みをしたが,「サーバレスの概念は理解しているが,実際に実装したことがない」という人にとっては最高のテーマだと思う.無料枠もあるし,まず試してみるのが良いのではないかと思う.1点 sspa スクリプトが API Gateway に対応していなく,手動で /popularAnswers の POST リソースを作るところはちょっと笑った.

セキュリティとスケールアップ

最後にはセキュリティで気を付けるべき点と,スケールアップの方法,そして CloudWatch を使ってモニタリングをする話も紹介されていて非常に手厚かった.今回実装したアプリケーションが完璧ではなく,現実問題では様々な考慮が必要であることが伝わる.S3 のアクセスログを分析する部分は,今なら Athena でクエリを投げればもっとリッチな体験ができるし,サーバレスだと思うけど,原著の発売日が2016年6月なので,まだ発表されていなかった.

aws.amazon.com

ハマったこと

CSS の記述が一部書かれてなく,思った通りのデザインにならなかった.そこは実際に公式ページを Chrome DevTools で解析して調べた.具体的には以下なので,ここは気を付けてもらえればと.

3ç« 

ツールバーを実装するときに,以下の CSS を追加しないと,LearnJS のフォントサイズが大きくならなかった.また,そのために margin-top を 30px から 60px に修正する必要もあり,ここは本書に書いてあるものの,コードとしては書かれてなく,見落としてしまった.

.text-lg {
  font-size: 32px;
}

4ç« 

Cognito 連携をしたときにナビバーにログイン済のメールアドレスを表示するが,そこで使う以下の CSS を追加しないと,デザインが微妙に崩れてしまった.

.navbar-padding-lg {
  padding-top: 12px;
  display: inline-block;
}

正誤表

O'Reilly から正誤表が公開されていて,現時点だと1点だけある.今後増える可能性もあるので,見ておくと良さそう.この「マイナスが抜けてる」件は,写経していると「変だな?」とすぐ感じたので,特に困ることはなかった.

www.oreilly.co.jp

ソースコード一覧

今回は答えを見ずに頑張って写経することを目標にしていたので,1度もダウンロードすることはなかったけど,公式のソースコード一覧が公開されている.どうしても困った!という場合は見てみるのが良いのではないかと思う.

pragprog.com

エディタ

2章までは vim で写経をしていたけど,ミスが連発したり,app.js がもっと大きくなる気配を感じたので,途中からは使い慣れた RubyMine で写経をした.フォーマットもできるし,コードジャンプもできるし,シンタックスチェックもできるし,圧倒的に効率が良くなった.もし写経をするなら,エディタを用意してから取り組むのが良いと思う.

まとめ

  • 本書を写経しながら SPA を実装することができた
  • S3 / Cognito / DynamoDB / API Gateway / Lambda などを組み合わせることで,本当に「サーバレス」で実現できた
  • 写経 + 動かなくてデバッグした時間も含めると,約6.5時間(13 ポモドーロ)で終わった

関連記事

監訳お疲れさまでした!素晴らしかったです!

yoshidashingo.hatenablog.com

API Gateway + Lambda をもっと深く学ぶなら同じく6月に出版された「実践 AWS Lambda」がオススメ!

kakakakakku.hatenablog.com