AWSのみを使ってサーバレス環境をつくる

# そろそろぼくもSPA
当方、へっぽこエンジニアですが、モダンな開発に興味があるのと仕事で必要に迫られて、モダンなSPAを作ってみようと思います。PWAでサービスワーカー的なこともやりたい。
大きな方針は、「AWSを使い倒す」という点です。極力マネージドサービスを使いたい。ブラウザで開発したい。コードを書きたくない。そういうわけで、関連するサービスが広く浅く出てきます。
ちなみに、Cloud9っていうIDEを使いたいがためにシンガポールリージョンにしました。

# AWS CodeStar
出発点はここです。CodeStarは、AWSが提供する、開発環境設定をいろいろやってくれる子らしい。
開始しようとしたら、IAMロールつくるよと言われた。OKします。
<img width="618" alt="スクリーンショット 2018-09-07 17.14.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/19e3af0d-7a26-3442-3eca-48f334ae427e.png">

テンプレートがいっぱい出てくる。作りたいのはウェブアプリケーションで、サーバレスでやりたい。Goわかんない。というわけでNode.js+Lambda一択です。
<img width="330" alt="スクリーンショット 2018-09-07 17.18.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/59b9da20-b388-e161-dc4a-00a20ae3a5c9.png">


リポジトリは、GitHubとCodeCommitから選べますがここはCodeCommitにしてみます。5人まで無料らしいよ。
<img width="848" alt="スクリーンショット 2018-09-07 17.19.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/c2ba5b3c-8099-1968-3763-1ab399a33ea8.png">


プロジェクトの詳細の確認として、こんな図がでてきました。全部AWS!わーい。
<img width="1098" alt="スクリーンショット 2018-09-07 17.21.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/1133d914-1982-117d-216f-5cc9298e2a70.png">


ユーザが必要らしい。ふーん。
<img width="727" alt="スクリーンショット 2018-09-07 17.27.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/3637c369-f509-bcf1-d704-63ac1cd45f14.png">


コードは何で書きますか？ Cloud9にしてみます。
<img width="1192" alt="スクリーンショット 2018-09-07 17.27.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/26a57eac-a530-069e-6ad3-4a2cf48495be.png">


むむ、EC2？と思いますがこれはCloud9の実行環境の選択です。ケチってt2.nanoにします。自分のPCにいろいろ入れるのめんどいですし、これは良い仕組み。
<img width="776" alt="スクリーンショット 2018-09-07 17.31.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/bcbd9ba0-4497-917d-8764-789e3d1a26ab.png">


プロジェクト作成完了！
<img width="1432" alt="スクリーンショット 2018-09-07 17.46.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/e193960e-c1ed-5bf5-a144-a0e8bb4599fd.png">

作成されたリソースはこちら。めっちゃできてる。
<img width="1285" alt="スクリーンショット 2018-09-07 18.49.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/c605c97e-64de-f2a2-2c4f-636ad22ad115.png">


この時点で、すでに「〜-app」っていうS3バケットにサンプルのHTMLファイルなどが置かれています。
さらに、そのバケットのpublic/index.htmlを表示するためだけのLambda関数が作成されており、
そのLambda関数を公開するためのエンドポイントがAPIGatewayで作成されています。
APIGatewayのエンドポイントURLはCodeStarのダッシュボードにありますので、アクセスしてみましょう。
<img width="1440" alt="スクリーンショット 2018-09-07 18.34.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/bbccb902-2af8-a627-3220-33be585f8c02.png">
これは、S3でpublic/index.htmlを開いても全く同じものが見れますが、違うのはAPIGatewayのエンドポイントではHTMLしか公開されてない、という点です。S3の方は、パスを書き換えて別フォルダに格納されている画像とかを参照することが出来ますが、エンドポイントではそれはできません。

このようにLambdaを介するメリットはよく理解できていません。S3直接公開よりもそのほうがいいことはなんだろう？

さて、なにはともあれ、 「コーディングの開始」をクリックするとおもむろにCloud9が立ち上がります。シームレス感すごい。
<img width="1440" alt="スクリーンショット 2018-09-07 17.48.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/171479/1da57326-367c-e28a-88ab-09abf341b62c.png">



# コミットからデプロイまで
アプリはなにもいじってないけれど、フレームワークをインストールしたので本番環境に反映してみましょう。
どうやればよいのだ？ CodeCommit、CodeBuild、CodePipelineやらいろいろあってよくわからん！

##  簡単だった
gitでリモートリポジトリにpushするだけで、自動的に変更がS3にまで反映されます。
（masterを直接やっちゃってるけど、本来はbranch切った方がいいです）

```console
$ cd ~/environment/spa-test
$ git add .
$ git commit -m "hoge"
$ git push
```
簡単すぎじゃない？と思いましたが、これがCodePipelineの威力みたいですね。

1. Cloud9で編集、commit、push
2. CodeCommitのmasterの変更をCloudWatchが自動検知しトリガー
3. CodeBuildでビルド
4. CloudFormationでデプロイ

これをやってくれるわけです。CodeStarが、自動的に設定してくれていたのです。
ソースをよく見ると、buildspec.ymlというファイルがあります。これはCodeBuildの設定ファイルです。この中には、"aws s3 cp --recursive ほげほげ"という記述があります。これがCodeBuildの設定ファイルで、デプロイ時にS3にファイルをコピーしろ、という設定なわけですね。

```yaml:buildspec.yml
version: 0.2

phases:
  install:
    commands:
      # Install dependencies needed for running tests
      - npm install

      # Upgrade AWS CLI to the latest version
      - pip install --upgrade awscli
  pre_build:
    commands:
      # Discover and run unit tests in the 'tests' directory
      - npm test
  build:
    commands:
      # Use AWS SAM to package the application by using AWS CloudFormation
      - aws s3 cp --recursive public/ s3://$WEBSITE_S3_BUCKET/public/ --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
      - sed -i -e "s|assets/|$WEBSITE_S3_PREFIX/public/assets/|g" public/index.html
      - aws cloudformation package --template template.yml --s3-bucket $S3_BUCKET --output-template template-export.yml

artifacts:
  type: zip
  files:
    - template-export.yml

```
その他、sed のところで相対パスをS3の絶対パスに書き換えたりしています。前述したようにAPIGatewayのエンドポイントではindex.htmlしか公開されてないですから、画像などを参照するためにはこれが必要ですね。

CloudFormationのデプロイでは、Lambda関数のデプロイが行われます。ここでは設定ファイル template.yml が使われます。

#続く
環境設定は概ね出来ました。
今度はアプリの中身の話をしたいです。