[JAWS-UG CLI] CloudWatch Events:#2 Lambda関数のスケジュール実行 (おはようLambda)

CloudWatch EventsでLambda関数を定期実行してみます。



前提条件
========

CloudWatch Eventsへの権限
----------------------------

CloudWatch Eventsに対してフル権限があること。


Lambdaへの権限
--------------

Lambdaに対して読み取り権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

* AWS CLI 1.10.17

```bash:コマンド:
aws --version
```

```text:結果(例):
aws-cli/1.10.17 Python/2.7.10 Darwin/15.4.0 botocore/1.4.8
```



0. 準備
=======


0.1. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       administrator-prjz-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                ap-northeast-1        env    AWS_DEFAULT_REGION
```

プロファイルが想定のものになっていることを確認します。



1. 事前準備
==============

1.1. イベント名の決定
------------------------


```bash:変数の設定
EVENTS_RULE_NAME='good_morning_lambda'
```

同名のイベントが存在しないことを確認します。

```bash:コマンド:
aws events describe-rule \
  --name ${EVENTS_RULE_NAME}
```

```text:結果(例):
A client error (ResourceNotFoundException) occurred when calling the DescribeRule operation: Rule good_morning_lambda does not exist.
```

descriptionも必ず指定しておきましょう。

```bash:変数の設定
EVENT_RULE_DESC="good morning rule."
```



1.2. スケジュールの指定
---------------------------

```bash:変数の設定
EVENT_SCHEDULE_EXP='cron(0/5 * ? * * *)'
```



2. イベントの作成
================================

2.1. イベントの作成
--------------------------------

```bash:変数の確認
cat << ETX

  EVENTS_RULE_NAME:    ${EVENTS_RULE_NAME}
  EVENT_SCHEDULE_EXP:  ${EVENT_SCHEDULE_EXP}
  EVENT_RULE_DESC:    "${EVENT_RULE_DESC}"

ETX
```

```bash:コマンド:
aws events put-rule \
  --name ${EVENTS_RULE_NAME} \
  --schedule-expression "${EVENT_SCHEDULE_EXP}" \
  --description "${EVENT_RULE_DESC}"
```

```json:結果(例):
{
    "RuleArn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/good_morning_lambda"
}
```


2.2. イベントの確認
--------------------------------

```bash:コマンド:
aws events list-rules 
```

```json:結果(例):
{
    "Rules": [
        {
            "State": "ENABLED", 
            "ScheduleExpression": "cron(0/5 * ? * * *)", 
            "Name": "good_morning_lambda", 
            "Arn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/good_morning_lambda",
            "Description": "good morning rule."
        }
    ]
}
```


```bash:コマンド:
aws events describe-rule \
  --name ${EVENTS_RULE_NAME}
```

```json:結果(例):
{
    "ScheduleExpression": "cron(0/5 * ? * * *)", 
    "Name": "good_morning_lambda", 
    "State": "ENABLED", 
    "Arn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/good_morning_lambda", 
    "Description": "good morning rule."
}
```




3. ターゲットの追加
================================

3.1. ターゲットの確認
-----------------------

ルールを作成した直後は、ターゲットが存在しません。
確認してみましょう。

```bash:コマンド:
aws events list-targets-by-rule \
  --rule ${EVENTS_RULE_NAME}
```

```json:結果(例):
{
    "Targets": []
}
```



3.2. Lambda関数の指定
----------------------

定期実行するLambda関数の名前を指定します。

put-targets

```bash:変数の設定
LAMBDA_FUNC_NAME='good_morning_lambda'
```

Lambda関数のARNを取得します。

```bash:変数の設定
LAMBDA_FUNC_ARN=$( \
  aws lambda get-function \
    --function-name ${LAMBDA_FUNC_NAME} \
    --query 'Configuration.FunctionArn' \
    --output text \
) \
  && echo ${LAMBDA_FUNC_ARN}
```

```text:結果(例):
arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:good_morning_lambda
```


3.3. ターゲットID
--------------------------------

ターゲットIDを指定します。

```bash:変数の設定
EVENTS_TARGET_ID='Id1'
```

ターゲットIDとLambda関数のARNを紐付けます。

```bash:変数の確認
cat << ETX

  EVENTS_TARGET_ID: ${EVENTS_TARGET_ID}
  LAMBDA_FUNC_ARN:  ${LAMBDA_FUNC_ARN}

ETX
```

```bash:変数の設定
EVENTS_TARGETS="Id=${EVENTS_TARGET_ID},Arn=${LAMBDA_FUNC_ARN}"
```


3.4. ターゲットの追加
--------------------------------

```bash:変数の確認
cat << ETX

  EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}
  EVENTS_TARGETS:   ${EVENTS_TARGETS}

ETX
```

```bash:コマンド:
aws events put-targets \
  --rule ${EVENTS_RULE_NAME} \
  --targets ${EVENTS_TARGETS}
```

```json:結果(例):
{
    "FailedEntries": [],
    "FailedEntryCount": 0
}
```


3.5. ターゲットの確認
--------------------------------

```bash:コマンド:
aws events list-targets-by-rule \
  --rule ${EVENTS_RULE_NAME}
```

```json:結果(例):
{
    "Targets": [
        {
            "Id": "Id1", 
            "Arn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:good_morning_lambda"
        }
    ]
}
```


3.6. ターゲットのARN取得
--------------------------------

ターゲットのARNを元に、同一ターゲットが使われているルールを検索することができます。

まず、ターゲットのARNを取得します。


```bash:変数の設定
EVENT_TARGET_ARN=$( \
  aws events list-targets-by-rule \
    --rule ${EVENTS_RULE_NAME} \
    --query "Targets[?contains(Arn, \`${LAMBDA_FUNC_NAME}\`)].Arn" \
    --output text \
) \
  && echo ${EVENT_TARGET_ARN}
```

```text:結果(例):
arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:good_morning_lambda
```

list-rule-names-by-targetサブコマンドでターゲットARNを指定することで、そのターゲットを利用しているルールのリストを取得することができます。


```bash:コマンド:
aws events list-rule-names-by-target \
  --target-arn ${EVENT_TARGET_ARN}
```

```json:結果(例):
{
    "RuleNames": [
        "good_morning_lambda"
    ]
}
```


3.7. メッセージの受信
------------------------------------

5分以内にslackのチャンネルにメッセージが届いていればOKです。



4. ルールの無効化/有効化
================================

一時的にルールを無効化してみましょう。

4.1. ルールの無効化
--------------------------------

現在のルールの状態を確認します。

```bash:変数の設定
EVENT_RULE_STATE=$( \
  aws events describe-rule \
    --name ${EVENTS_RULE_NAME} \
    --query 'State' \
    --output text \
) \
  && echo ${EVENT_RULE_STATE}
```

```text:結果(例):
ENABLED
```

ルールの無効化をしてみましょう。

```bash:コマンド:
aws events disable-rule \
  --name ${EVENTS_RULE_NAME}
```


```bash:変数の設定
EVENT_RULE_STATE=$( \
  aws events describe-rule \
    --name ${EVENTS_RULE_NAME} \
    --query 'State' \
    --output text \
) \
  && echo ${EVENT_RULE_STATE}
```


```text:結果(例):
DISABLED
```


4.2. ルールの有効化
--------------------------------

ルールの有効化を再度有効化する場合は、enable-ruleコマンドを利用します。

```bash:コマンド:
aws events enable-rule \
  --name ${EVENTS_RULE_NAME}
```


```bash:変数の設定
EVENT_RULE_STATE=$( \
  aws events describe-rule \
    --name ${EVENTS_RULE_NAME} \
    --query 'State' \
    --output text \
) \
  && echo ${EVENT_RULE_STATE}
```

```text:結果(例):
ENABLED
```


5. スケジュールの変更
================================

5.1. スケジュールの指定
--------------------------------

動作確認が取れたら、起動時間を朝に設定してみましょう。
時刻指定はUTCで指定します。日本時間7時に指定する場合は22を指定します。

```bash:変数の設定
EVENT_SCHEDULE_EXP='cron(0 22 ? * * *)'
```

5.2. ルールの更新
--------------------------------

ルールを更新します。

```bash:変数の確認
cat << ETX

  EVENTS_RULE_NAME:    ${EVENTS_RULE_NAME}
  EVENT_SCHEDULE_EXP:  ${EVENT_SCHEDULE_EXP}

ETX
```


```bash:コマンド:
aws events put-rule \
  --name ${EVENTS_RULE_NAME} \
  --schedule-expression "${EVENT_SCHEDULE_EXP}"
```

```json:結果(例):
{
    "RuleArn": "arn:aws:events:ap-northeast-1:XXXXXXXXXXXX:rule/good_morning_lambda"
}
```


5.3. ルールの確認
--------------------------------

```bash:コマンド:
aws events describe-rule \
  --name ${EVENTS_RULE_NAME}
```

```json:結果(例):
```



----------------------------------------------------------------
6. 後始末
----------------------------------------------------------------

6.1. ターゲットの削除
-----------------------

```bash:変数の設定
ARRAY_EVENTS_TARGET_IDS='Id1'
```

```
aws events remove-targets \
  --rule ${EVENTS_RULE_NAME} \
  --ids "${ARRAY_EVENTS_TARGET_IDS}"
```

```json:結果(例):
{
    "FailedEntries": [], 
    "FailedEntryCount": 0
}
```



6.2. ルールの削除
-----------------------

```bash:変数の確認
cat << ETX

  EVENTS_RULE_NAME: ${EVENTS_RULE_NAME}

ETX
```

```bash:コマンド:
aws events delete-rule \
  --name ${EVENTS_RULE_NAME}
```

```text:結果(例):
(戻り値なし)
```




```bash:コマンド:
aws events list-rules 
```

```json:結果(例):
{
    "Rules": []
}
```



完了
========