[AWS]SAMを使ってLambdaを定期実行するHelloWorld

LambdaファンクションをCloudWatch Eventを使って定期実行してみたいと思います。

#0. 環境
```
$ docker -v
Docker version 18.09.2, build 6247962
$ python --version
Python 3.7.0
$ pip --version
pip 19.0.3
$ aws --version
aws-cli/1.16.114 Python/3.7.0 Darwin/18.2.0 botocore/1.12.104
$ sam --version
SAM CLI, version 0.11.0
```

AWSCLIの設定(aws configure)がしてある前提で進めます。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration

#1. HelloWorld実行(開発準備)
##1-1. テンプレ作成
```
$ sam init -r python3.7 -n my-app
```

今回はpython3.7で開発します。
my-appというプロジェクト名で作成します。

以下の通り、作成されます。

```
$ cd my-app
$ tree
.
|-- README.md
|-- event.json
|-- hello_world
|   |-- __init__.py
|   |-- __pycache__
|   |   |-- __init__.cpython-37.pyc
|   |   `-- app.cpython-37.pyc
|   |-- app.py
|   `-- requirements.txt
|-- template.yaml
`-- tests
    `-- unit
        |-- __init__.py
        |-- __pycache__
        |   |-- __init__.cpython-37.pyc
        |   `-- test_handler.cpython-37.pyc
        `-- test_handler.py

5 directories, 12 files
```


##1-2. 必要ライブラリインストール

```
$ cd hello_world/
$ pip install -r requirements.txt -t build/
$ cp *.py build/
$ cd ..
```

templete.yamlの以下の部分を書き換えてください

```
            CodeUri: hello_world/
```
↓

```
            CodeUri: hello_world/build/
```


##1-3. Lambdaテスト実行
作成したeventファイルで実行します。
hello worldが出力されればOK
初回起動はDockerが立ち上がるのに時間がかかります。

```
$ sam local invoke -e event.json
〜(略)〜
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
```

##1-4. Lambdaローカルエンドポイント作成
以下コマンドでローカルにLambdaのエンドポイントが作成できます。

```
$ sam local start-lambda
```

実行はCLIかSDKを使って行えます。
今回はCLIを使って動作確認しました。

```
$ aws lambda invoke --function-name "HelloWorldFunction" --endpoint-url "http://127.0.0.1:3001" out.txt
{
    "StatusCode": 200
}
$ cat out.txt 
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
```

これで開発環境は整いました。

#2. Lambdaデプロイ
##2.1 template.yaml作成
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
    HelloWorldFunction:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: hello_world/build
            Handler: app.lambda_handler
            Runtime: python3.7
            Events:
                HelloWorld:
                    Type: Schedule
                    Properties:
                        Schedule: cron(30 23 ? * MON-FRI *)
```

「Schedule: cron(30 23 ? * MON-FRI *)」
の箇所は以下公式ドキュメントを参考に定期実行したい時間等を設定します。
時間はUTCなので注意が必要です。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html

##2-2. パッケージ化
S3バケットがない場合は作ります

```
$ aws s3 mb s3://my-app-lambda
make_bucket: my-app-lambda
```

以下コマンドでパッケージ化したものをS3に設置

```
$ sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket my-app-lambda
Uploading to 614e5f60f81b1272edd607033afa55d8  965373 / 965373.0  (100.00%)
Successfully packaged artifacts and wrote output template to file packaged.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file <PATH>/packaged.yaml --stack-name <YOUR STACK NAME>
```

##2-3. デプロイ
```
$ sam deploy --template-file packaged.yaml --stack-name my-app --capabilities CAPABILITY_IAM

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - my-app
```


AWSコンソールから,CloudFormation, Lambda, CloudWatchイベント を確認してみてください。
作成されているはずです。


削除する際は、CloudFormationから削除すれば関連するサービスまとめて削除してくれます。