AWS LambdaをCronっぽく周期実行させる

## はじめに

AWS LambdaはEvent Drivenに設計されており、Cron Jobの様なSchedule Drivenで起動する事は想定されていません。LambdaをScheduleで起動する方法は、[こんな方法](http://qiita.com/toritori0318/items/3ab95e94c5fc47530447)も有るみたいですが、ここではAWSのData Pipelineの機能を使って、LambdaをSchedule Drivenで周期実行する方法をチラ裏しておきます。

ただし、Data Pipelineの制約として、実行周期は15分以上にしか設定出来ないので注意してください、1分毎の実行などはできません。

## 全体の流れ
設定する項目の流れは、以下の様になっています。
#### Lambda functionの作成
* Lambda functionのnode.js codeの作成
* Lambdaの実行に必要なIAM Roleを作成(or 既存のIAM Roleを設定)する
* LambdaのEvent sourceは特に設定をしない

#### Data Pipelineの作成
* Data Pipelineのlogを保存する為のS3 bucketを作成する(既存のBucketの流用も可)
* Data PipelineでShell scriptを定期実行する様に設定する  
Shell scriptの中でAWS CLI toolを使いLambda functionを実行  
* Data Pipeline用のIAM Roleに、Lambda functionを起動出来る権限を付与する


#### Lambda functionの実行Logの確認
* Lambda functionの実行Logは、Cloud WatchのLogsに保存されるので、  
Data PipelineをTriggerに周期実行されているか確認する

## 本記事で設定する内容
この記事では、以下の処理を設定する想定で書いています。

* Lambda自体は特に何も処理せず、LambdaのLogに`Hello world`を出力する
* Data Pipelineで、Lambda functionを15分に1回実行する様に設定する
* Lambda functionのlogを確認し、Lambda functionが15分毎に呼び出され、`Hello world`がLogされている事を確認する

##### 補足
* Data PipelineのSchedule実行の周期は、最短で15分毎です

## Lambda Functionの作成

AWS Console→Lambdaに行き、Lambda functionを以下の手順で作成します。

* `hello-world`の雛形を指定
* Function Nameは、`Lambda_Schedule_Function`とします
* IAM Roleの設定は必須なので、`lambda_basic_execution`を指定します(既存のIAM Roleを割り当てても可)、Lambdaはconsole.logするだけなので、IAM Roleへの権限の付与が何もない状態で問題ありません
* Memory, TimeoutはDefaultのままでOK
* LambdaのNode.jsのCodeは以下の様にします (単にconsole.logしているだけです)

```js
exports.handler = function(event, context) {
    console.log('Lambda function invoked!');
    context.done();
};
```

この設定で作成された`Lambda_Schedule_Function`と言うLambda FunctionをTest実行してみて、`Log output`に`Lambda function invoked!`と出力されている事を確認してください。

## Data Pipelineの作成
### S3 bucketの作成
まず、Data PipelineのLogを保存する為のS3 bucketを作成します(既存のBucketの流用する or Logの保存が必要ない場合はSkip可)。AWS Console→S3に行き、以下の手順でS3 Bucketを作成します。

* `Create Bucket`を選択して、適当な名前を付けて作成(ここでは`datapipeline-lambda-test`というBucketを作成したと想定)

### Data Pipelineの作成
AWS Console→Data Pipelineに行き、Data Pipelineを以下の手順で作成します。

* Nameは適当に設定(ここでは`Test Pipeline`とします)
* Sourceは`Build using a template`で`Run AWS CLI command`を選択
* AWS CLI commandには`aws lambda invoke FunctionError --function-name Lambda_Schedule_Function --region ap-northeast-1`を設定 (`--region`はAWS regionに応じて適宜変えてください)
* Scheduleの箇所は、Run everyに`15 minutes`を指定  
`Starting`と`Ending`は開始/終了の時刻設定で、TestするだけならDefaultのままでOK
* Pipeline ConfigurationのLoggingは、上で作成した`datapipeline-lambda-test`というS3 bucketを指定
* Security/AccessとTagはDefaultのままでOK

この設定で`Edit Architect`を選択して、Data Pipelineを一旦作成します。
作成すると、IAM Roleに`DataPipelineDefaultResourceRole`と`DataPipelineDefaultRole`という2つのIAM Roleが作成されます。
  

### IAM Roleの権限設定
IAM Role作成直後の状態では一部権限が足りない為、`DataPipelineDefaultResourceRole`にLambda Functionを起動する権限を付与します。
AWS Console→Identity & Access Management→Rolesに行き、以下の手順で権限を付与します。

* `DataPipelineDefaultResourceRole`をクリック
* Managed Policies→Attach Policyで、`AWSLambdaInvocation-DynamoDB`を検索して選択し、`Attach Policy`する


### Data PipelineのActivate
AWS Console→Data Pipelineに行き、先ほど作成したData PipelineをActivateします。

* `Test Pipeline`を選択
* `Actions`→`Activate`を選択

これで、Data Pipelineの周期実行がActivateされました。15分毎の実行なので、しばらく待ちましょう。

## Lambda functionの実行Logの確認
AWS Console→CloudWatch→Logsに行き、Lambda functionの実行Logを確認します。

* `/aws/lambda/Lambda_Schedule_Function`を選択すると、Lambda functionの実行結果を確認できるので、  
Lambda functionが15分毎に呼び出され、`Lambda function invoked!`がLogされている事を確認


## 最後に
Lambda functionをSchedule実行できると、各種の周期実行が必要なBatch処理をLambdaで処理させる事が可能になるので、周期実行の為のHostを個別に確保/管理する必要が無くなり、色々捗ります。

## 参考記事
* [Data PipelineのShellCommandActivityについて](http://qiita.com/imaifactory/items/6dc16820c4bec67a7d05)
* [AWS CLIの処理をAWS Data Pipelineで自動化する](http://dev.classmethod.jp/cloud/aws/automate-operation-of-aws-cli-by-aws-data-pipeline/)
* [AWS Data Pipelineを利用したAWSジョブスケジューラ](http://dev.classmethod.jp/cloud/aws/jobscheduler-by-datapipeline/)