twitter bot を AWS SAM を使用してデプロイする

twitter に定期的に投稿する bot を作成し、AWS Serverless Application Model(AWS SAM) を使用して AWS にデプロイします。


## SAM をインストール

公式サイトからインストールします。

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html

**tool kit for vscode をインストール**
``tool kit`` を vs code にインストールをすると、 sam のデバッグを助けてくれます。

https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html

## 前提

手元の環境が windows 10 ですので、 windows 環境での構築を前提にします。

- os: windows 10
- docker がインストールされている
- aws アカウントが作成されている

## 環境構築

lambda のランタイムに python 3.8 を使用するので、開発環境にも python 3.8 を用意します。

**pyenv インストール**
pyenv を使用して python 3.8 をインストールするので、まずは pyenv をインストールします。

https://github.com/pyenv-win/pyenv-win

pyenv がインストールできたら、pyenv がサポートしているバージョンリストを確認します。

```
> pyenv install -l
...
3.8.9
3.8.10-win32
3.8.10
3.9.0a1-win32
3.9.0a1
...
```

バージョンリストの中から任意のバージョンをインストールします。

```
> pyenv install 3.8.10
```

python 3.8 をローカルバージョンとして設定します。

```
> pyenv local 3.8.10
> python --version
Python 3.8.10
```

### 仮想環境作成
venv で仮想環境を構築します。

```
> python -m venv .venv
```

仮想環境を有効化

```
# windows の場合
> .\.venv\Scripts\Activate.ps1
```

## Write your code


### サンプルアプリケーションをダウンロード

``sam init`` を実行し ``AWS Quick Start Templates`` を選択するとサンプルアプリケーションが作成されます。

```
> sam init
```

### モジュールインストール

プログラムに必要なモジュールをインストールします。

```
(.venv)> pip install tweepy
```

### コード

qiita へ投稿した記事の中から 1 件ランダムに取得して tweete へ投稿するプログラムをつくります。プログラムについては別の記事にしましたのでそちらをご覧ください。

https://qiita.com/kiyo27/items/3db780252adcfd563a5f

### Event の設定

アプリケーションを lambda に配置し、その lambda を定期的に実行する CloudWatch Event の設定を ``template.yaml`` に記載します。

```yaml:template.yaml
Resources:
  TwitterBotFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: twitter_bot_function
      Handler: twitter_bot/app.lambda_handler
      Runtime: python3.8
      Events:
        TwitterBot:
          Type: Schedule
          Properties:
            Schedule: rate(60 minutes)
            Name: twitter-bot-wake-up
            Enabled: True
```

**リファレンス:**
https://github.com/aws/serverless-application-model/blob/master/versions/2016-10-31.md#schedule

## デバッグ

``launch.json`` に設定情報を記載し ``F5`` を押してデバッグを実行します。ブレークポイントを設定してデバッグが行えるようになります。

**リファレンス:**
https://docs.aws.amazon.com/ja_jp/toolkit-for-vscode/latest/userguide/serverless-apps-run-debug-config-ref.html

```json:launch.json
{
    "configurations": [
        {
            "type": "aws-sam",
            "request": "direct-invoke",
            "name": "twitter_bot_function:twitter_bot/app.lambda_handler (python3.8)",
            "invokeTarget": {
                "target": "code",
                "projectRoot": "${workspaceFolder}/twitter_bot_function",
                "lambdaHandler": "twitter_bot/app.lambda_handler"
            },
            "lambda": {
                "runtime": "python3.8",
                "payload": {},
                "environmentVariables": {}
            }
        }
    ]
}
```

### lambda をローカルで実行

``sam local invoke`` コマンドを使用すると、 lambda をローカルで実行できます。``sam local invoke`` コマンドを使用すると sam は　``sam build`` コマンドでビルドされたテンプレートファイルを参照しに行くので、ローカルデバッグを実行する前に ``sam build`` を実行しておきます。

```
> sam build
```

ビルドが完了したらデバッグコマンドを実行します。

```
> sam local invoke
```

**オプション:**
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html

## デプロイ

パッケージを一覧を ``requirements.txt`` に出力します。

```
> pip freeze > requirements.txt
```

``template.yaml`` の内容を検証

```
> sam validate
```

sam アプリケーションをデプロイします。

```
# アプリケーションをビルド
> sam build

# CloudFormation で stack をデプロイ
> sam deploy --guided
# すでにデプロイ済みの場合
> sam deploy
```

**オプション:**
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html

## クリーンアップ

コンソール画面から CloudFormation stack を削除するか、下記のコマンドで削除できます。

```
> aws cloudformation delete-stack --stack-name <stack-name>
```