AWS Toolkit for Visual Studio CodeでVSCodeからAWS SAMアプリをデプロイする

# はじめに
AWSでサーバーレスアプリをサクッと作る場合は、AWS SAM CLI等を使ってコマンドラインから構築することもできますが、AWS Toolkit for Visual Studio Codeを使って普段のエディタからも同じことができます。
Node.js、Java、Python、Goに対応しています。
さらにAWS Toolkitを使うとローカルでのデバッグ、テストも容易になります:relaxed:。
多少SAMコマンドも紹介しますが、AWS Toolkitを使って簡単なアプリ（API Gateway + Lambda）をデプロイするところまでやってみます。

# AWS SAMとは
https://aws.amazon.com/jp/serverless/sam/faqs/
>AWS サーバーレスアプリケーションモデル (AWS SAM) は、サーバーレスアプリケーション構築用のオープンソースフレームワークです。迅速に記述可能な構文で関数、API、データベース、イベントソースマッピングを表現できます。リソースごとにわずか数行で、任意のアプリケーションを定義して YAML を使用してモデリングできます。

SAMテンプレートとはCloudFormationの拡張版です。
JSON、YAMLフォーマットで、AWSのサーバーレスリソースを記載します。
専用のコマンドラインツールが用意されていますが、デプロイする時はCloudFormationに対してデプロイされます。

SAMに対応しているAWSリソースはこちら
https://docs.aws.amazon.com/ja_jp/serverlessrepo/latest/devguide/using-aws-sam.html#supported-resources-for-serverlessrepo


# AWS Toolkit for Visual Studio Codeとは
https://aws.amazon.com/jp/visualstudiocode/
>AWS Toolkit for Visual Studio Code は、Visual Studio Code 用のオープンソースプラグインで、アマゾン ウェブ サービス上でのアプリケーションの作成、デバッグ、デプロイを容易にします。AWS Toolkit for Visual Studio Code を使用すると、AWS 上での Visual Studio Code を使用したアプリケーションの構築をより迅速に開始でき、生産性が向上します。このツールキットは、使用開始のサポート、ステップ実行によるデバッグ、および IDE からのデプロイを含む、サーバーレスアプリケーションの統合開発環境を提供します。

# 準備（環境構築）
・Mac、Windows、Linuxのいずれかを用意します。
・[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/toolkit-for-vscode/latest/userguide/setup-toolkit.html)に従ってAWS CLI、AWS SAM、Dockerもインストールします。
・[Visual Studio Code](https://code.visualstudio.com/)をインストールします。
・VS CodeのExtensions (拡張機能)で使用する言語のランタイムSDK（Node.js、Java、Python、Go）とAWS Toolkit for Visual Studio Codeをインストールします。
・AWSアカウントと認証情報（IAMユーザーのアクセスキーシークレットキー）を取得して、AWS CLIにセットアップしておきます。
・SAMテンプレートやLambdaソースコードをアップロードするためのS3バケットを作成しておきます。

# 手順
・VS CodeにAWS認証情報を設定
・アプリケーションの雛形作成
・実装
・ローカルデバッグ
・ローカル実行
・ローカルテスト
・テンプレート検証
・デプロイ

### VS CodeにAWS認証情報を設定
VS Codeを開き、左ペインにAWS Toolkitアイコンが追加されていることを確認します。
メニューから「Connect to AWS」を選択し、使用する認証情報のプロファイルを指定します。
<img width="544" alt="スクリーンショット 2019-12-09 17.51.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/4fd0a05f-715a-6247-a643-bfa12be8a592.png">

### アプリケーションの雛形作成
メニューから「Create new SAM Application」を選択し、ランタイム、ワークフォルダ、アプリ名を入力します。
Lambda Functionのソースコード、テストコード、SAMテンプレート（template.yaml）、READMEが自動生成されます。
ここからカスタマイズしていきます。
<img width="1612" alt="スクリーンショット 2019-12-09 18.06.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/157e6681-a0a2-a8a7-45e5-d2de14c15ec3.png">

### 実装
app.pyを開くと「Run Locally」「Debug Locally」「Configure」が表示されます。
デフォルトのコメントアウトを外します。（実行環境のIPアドレスを取得するロジックを追加します）
<img width="501" alt="スクリーンショット 2019-12-09 18.11.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/d2a06d03-2e01-a4a5-6a34-d146ce26143e.png">

### ローカル実行
ここでDockerを起動しておく必要があります。
app.pyを開き、ブレークポイントを指定して「Run Locally」を選択します。
コンテナが起動し、しばらくすると結果が返ります。
実装したLambdaのコード（app.py）をDocker上で実行できました。
<img width="729" alt="スクリーンショット 2019-12-09 18.33.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/d4f3efac-998f-7d77-8cd7-e94de61000fc.png">

### ローカルデバッグ
次にデバッグしてみます。
app.pyを開き、ブレークポイントを指定して「Debug Locally」を選択します。
このように簡単にLambdaをデバックできます。
<img width="589" alt="スクリーンショット 2019-12-09 18.15.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/0302b009-dfe5-e528-1375-40d9ab0567c3.png">
「Configure」を選択して、パラメータのeventを編集することもできます。
<img width="429" alt="スクリーンショット 2019-12-09 18.19.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/0db749fe-8fc9-5846-e76f-b093b0fc20ff.png">

### ローカルテスト
今回はPythonを選択したのでpipでpytestをインストールしておきます。
```pip install pytest```
以下コマンドをプロジェクト直下のターミナルから実行します。
```python -m pytest tests/ -v```
<img width="690" alt="スクリーンショット 2019-12-09 18.45.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/cf473bb2-d435-3bca-0a47-2d6ac8d11590.png">

### テンプレート検証
テストが終わったら、SAMテンプレート（template.yaml）の構文をコマンドで検証します。
ターミナルから下記コマンドを実行します。
```sam validate```
構文に誤りがあると怒られます。

### デプロイ
最後にデプロイします。
メニューから「Deploy SAM Application」を選択し、SAMテンプレートファイル名（template.yaml）、リージョン（ap-northeast-1）、準備したS3バケット名、CloudFormationスタック名を指定します。
するとデプロイが始まります。

```
Starting SAM Application deployment...
Building SAM Application...
Packaging SAM Application to S3 Bucket: ${S3バケット名} with profile: saml
Deploying SAM Application to CloudFormation Stack: sam-app with profile: saml
Successfully deployed SAM Application to CloudFormation Stack: sam-app with profile: saml
```

おめでとうございます。デプロイ成功です。
念の為、出力されたリソースもCloudFormationから取得してみます。
```aws cloudformation describe-stacks --stack-name sam-app --output text```
成功していれば、IAM Role、Lambda Function、API Gatewayのリソースが取得できます。

最後にデプロイされたLambdaを実行してみましょう。
メニューからCloudFormaionの下にデプロイされたLambdaが表示されますので右クリックして「Invoke on AWS」を選択。
下のようにパラメータを設定して「Invoke」で実行して結果を確認します。
<img width="1213" alt="スクリーンショット 2019-12-09 19.07.52.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532452/bf388635-7dcf-d111-5500-44f22d0f69be.jpeg">

#まとめ
いかがでしたでしょうか。
個人の開発環境としては十分ですね。

AWS Toolkitを使うとコマンドラインに抵抗がある方でも簡単にSAMを使ってデプロイできます。
SAMのメリットはCloudFormationと同様にインフラをコード化することです。
SAMを使えばサーバーレスのアプリを簡単にコード化できるので、チーム開発でも捗りますね。
テストとデプロイのステップをパイプラインに組み込めば、簡単にCI/CD化も可能です。
AWS CDKもサポートしているようなので機会があればそちらもやってみたいと思います。