[JAWS-UG CLI] CloudWatch Logs:#8 メトリックフィルタの作成 (IAM変更の検知)

AWS CLIを利用して、CloudWatchLogsのロググループを作成してみます。

参考: http://aws.typepad.com/aws_japan/2015/02/how-to-receive-alerts-
when-your-iam-configuration-changes.html


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


CloudWatchLogsへの権限
----------------------

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

* CloudWatchLogsに対してフル権限があること。

* IAMに対してフル権限があること。


AWS CLIのバージョン
-------------------

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

  * AWS CLI 1.7.26

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

結果(例):

      aws-cli/1.7.26 Python/2.7.5 Darwin/13.4.0


0. 準備
=======


0.1. リージョンの決定
---------------------

作成するユーザのデフォルトリージョンを決めます。

(カレントユーザが利用するカレントリージョンも切り変わります。)

```bash:コマンド(アイルランドリージョンの場合):
export AWS_DEFAULT_REGION='eu-west-1'
```


0.2. 変数の確認
---------------

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

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

結果(例):

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       cloudwatchFull-prjZ-mbp13iamFull-prjZ-mbp13              env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                eu-west-1              env    AWS_DEFAULT_REGION


0.3. CloudWatch Logs ロググループ名の確認
-----------------------------------------

メトリックフィルタを作成するロググループの内容を確認します。

```bash:コマンド:
cat << ETX

        LOG_GROUP_NAME: ${LOG_GROUP_NAME}

ETX
```

```bash:コマンド:
aws logs describe-log-groups \
          --log-group-name-prefix ${LOG_GROUP_NAME}
```

結果(例):

      {
        "logGroups": [
          {
              "storedBytes": 0,
              "metricFilterCount": 0,
              "creationTime": 1431298586512,
              "logGroupName": "CloudTrail/DefaultLogGroup",
              "retentionInDays": 60,
              "arn": "arn:aws:logs:eu-west-1:XXXXXXXXXXXX:log-group:CloudTrail/DefaultLogGroup:*"
          }
        ]
      }


0.4. CloudWatch Logs ログストリーム名の確認
-------------------------------------------

メトリックフィルタの動作確認で利用するログストリームを確認します。

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

        LOG_STREAM_NAME: ${LOG_STREAM_NAME}

ETX
```

```bash:コマンド:
aws logs describe-log-streams \
        --log-group-name ${LOG_GROUP_NAME} \
        --log-stream-name-prefix ${LOG_STREAM_NAME}
```

結果(例):

      {
        "logStreams": [
          {
              "creationTime": 1431309653829,
              "arn": "arn:aws:logs:eu-west-1:XXXXXXXXXXXX:log-group:CloudTrail/DefaultLogGroup:log-stream:XXXXXXXXXXXX_CloudTrail_eu-west-1",
              "logStreamName": "XXXXXXXXXXXX_CloudTrail_eu-west-1",
              "storedBytes": 0
          }
        ]
      }


1. 事前作業
===========


1.1. メトリックフィルタ名の決定
-------------------------------

メトリックフィルタ名を決めます。

```bash:コマンド:
LOG_FILTER_NAME='IAMAuthnAuthzActivity'
```


1.2. 同名のメトリックフィルタの不存在確認
-----------------------------------------

同名のメトリックフィルタが存在しないことを確認します。

```bash:コマンド:
aws logs describe-metric-filters \
          --log-group-name ${LOG_GROUP_NAME}
```

結果:

      {
          "metricFilters": []
      }


1.3. メトリックフィルタパターンの決定
-------------------------------------

メトリックに転送するデータのマッチングパターンを決めます。

```bash:コマンド:
STR_FILTER_PATTERN='{ ( ($.eventSource = "iam.amazonaws.com") && (($.eventName = "Add*") || ($.eventName = "Change*") || ($.eventName = "Create*") || ($.eventName = "Deactivate*") || ($.eventName = "Delete*") || ($.eventName = "Enable*") || ($.eventName = "Put*") || ($.eventName = "Remove*") || ($.eventName = "Update*") || ($.eventName = "Upload*")) ) }'
```


1.4. メトリックフィルタパターンのテスト
---------------------------------------

メトリックフィルタパターンがメッセージに対して想定通りにマッチするかテ
ストします。

```bash:コマンド:
LOG_EVENT_MSG='{ "eventVersion": "1.02", "userIdentity": { "type": "IAMUser", "principalId": "AIDAXXXXXXXXXXXXXXXXX", "arn": "arn:aws:iam::XXXXXXXXXXXX:user/administrator-prjz-mbp13", "accountId": "XXXXXXXXXXXX", "accessKeyId": "AKIAXXXXXXXXXXXX", "userName": "administrator-prjz-mbp13" }, "eventTime": "2015-05-11T02:46:40Z", "eventSource": "iam.amazonaws.com", "eventName": "PutRolePolicy", "awsRegion": "us-east-1", "sourceIPAddress": "xxx.xxx.xxx.xxx", "userAgent": "aws-cli/1.7.26 Python/2.7.5 Darwin/13.4.0", "requestParameters": { "policyDocument": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"AWSCloudTrailCreateLogStream20141101\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"logs:CreateLogStream\"\n ],\n \"Resource\": [\n \"arn:aws:logs:eu-west-1:XXXXXXXXXXXX:log-group:CloudTrail/DefaultLogGroup:log-stream:XXXXXXXXXXXX-west-1*\"\n ]\n },\n {\n \"Sid\": \"AWSCloudTrailPutLogEvents20141101\",\n \"Effect\": \"Allow\",\n \"Resource\": [\n \"arn:aws:logs:eu-west-1:XXXXXXXXXXXX:log-group:CloudTrail/DefaultLogGroup:log-stream:XXXXXXXXXXXX-west-1*\"\n ],\n \"Action\": [\n \"logs:PutLogEvents\"\n ]\n }\n ]\n}\n", "policyName": "policy-CloudTrail_CloudWatchLogs_Role_eu-west-1", "roleName": "CloudTrail_CloudWatchLogs_Role-eu-west-1" }, "responseElements": null, "requestID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "eventID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "eventType": "AwsApiCall", "recipientAccountId": "XXXXXXXXXXXX" }'
```

```bash:変数の確認:

cat << ETX

          STR_FILTER_PATTERN: "${STR_FILTER_PATTERN}"
          LOG_EVENT_MSG:      "${LOG_EVENT_MSG}"

ETX
```

```bash:コマンド:
aws logs test-metric-filter \
          --filter-pattern "${STR_FILTER_PATTERN}" \
          --log-event-messages "${LOG_EVENT_MSG}"
```

結果(例):

      {
        "matches": [
          {
              "eventNumber": 1,
              "eventMessage": "{ \"eventVersion\": \"1.02\", \"userIdentity\": { \"type\": \"IAMUser\", \"principalId\": \"AIDAXXXXXXXXXXXXXXXXX\", \"arn\": \"arn:aws:iam::XXXXXXXXXXXX:user/administrator-prjz-mbp13\", \"accountId\": \"XXXXXXXXXXXX\", \"accessKeyId\": \"AKIAXXXXXXXXXXXX\", \"userName\": \"administrator-prjz-mbp13\" }, \"eventTime\": \"2015-05-11T02:46:40Z\", \"eventSource\": \"iam.amazonaws.com\", \"eventName\": \"PutRolePolicy\", \"awsRegion\": \"us-east-1\", \"sourceIPAddress\": \"xxx.xxx.xxx.xxx\", \"userAgent\": \"aws-cli/1.7.26 Python/2.7.5 Darwin/13.4.0\", \"requestParameters\": { \"policyDocument\": \"{\\n \\\"Version\\\": \\\"2012-10-17\\\",\\n \\\"Statement\\\": [\\n {\\n \\\"Sid\\\": \\\"AWSCloudTrailCreateLogStream20141101\\\",\\n \\\"Effect\\\": \\\"Allow\\\",\\n \\\"Action\\\": [\\n \\\"logs:CreateLogStream\\\"\\n ],\\n \\\"Resource\\\": [\\n \\\"arn:aws:logs:eu-west-1:XXXXXXXXXXXX:log-group:CloudTrail/DefaultLogGroup:log-stream:XXXXXXXXXXXX-west-1*\\\"\\n ]\\n },\\n {\\n \\\"Sid\\\": \\\"AWSCloudTrailPutLogEvents20141101\\\",\\n \\\"Effect\\\": \\\"Allow\\\",\\n \\\"Resource\\\": [\\n \\\"arn:aws:logs:eu-west-1:XXXXXXXXXXXX:log-group:CloudTrail/DefaultLogGroup:log-stream:XXXXXXXXXXXX-west-1*\\\"\\n ],\\n \\\"Action\\\": [\\n \\\"logs:PutLogEvents\\\"\\n ]\\n }\\n ]\\n}\\n\", \"policyName\": \"policy-CloudTrail_CloudWatchLogs_Role_eu-west-1\", \"roleName\": \"CloudTrail_CloudWatchLogs_Role-eu-west-1\" }, \"responseElements\": null, \"requestID\": \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\", \"eventID\": \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\", \"eventType\": \"AwsApiCall\", \"recipientAccountId\": \"XXXXXXXXXXXX\" }",
              "extractedValues": {}
          }
        ]
      }


1.5. メトリックの名前空間の決定
-------------------------------

マッチしたメッセージを転送するメトリックの名前空間を決めます。

```bash:コマンド:
CWATCH_NAMESPACE='CloudTrailMetric'
```


1.6. メトリック名の決定
-----------------------

マッチしたメッセージを転送するメトリックを決めます。

```bash:コマンド:
CWATCH_METRIC_NAME='IAMAuthnAuthzActivity'
```


1.7. メトリック値の決定
-----------------------

マッチしたメッセージを転送する条件を決めます。

* キーワードをカウントしている場合: 1

* バイト数をカウントしている場合: 閾値(byte)

```bash:コマンド:
LOG_METRIC_VALUE='1'
```


2. メトリックフィルタの作成
===========================


2.1. メトリックトランスフォーメーションの内容決定
-------------------------------------------------

先程決めたメトリックトランスフォーメーションの各パラメータを組み立てます。

```bash:コマンド:
STR_METRIC_TRANS="metricName=${CWATCH_METRIC_NAME},metricNamespace=${CWATCH_NAMESPACE},metricValue=${LOG_METRIC_VALUE}" \
          && echo "${STR_METRIC_TRANS}"
```


2.2. メトリックフィルタの作成
-----------------------------

メトリックフィルタを作成します。

```bash:変数の確認:

cat << ETX

          LOG_GROUP_NAME:     ${LOG_GROUP_NAME}
          LOG_FILTER_NAME:    ${LOG_FILTER_NAME}
          STR_FILTER_PATTERN: "${STR_FILTER_PATTERN}"
          STR_METRIC_TRANS    ${STR_METRIC_TRANS}

ETX
```

```bash:コマンド:
aws logs put-metric-filter \
          --log-group-name ${LOG_GROUP_NAME} \
          --filter-name ${LOG_FILTER_NAME} \
          --filter-pattern "${STR_FILTER_PATTERN}" \
          --metric-transformations ${STR_METRIC_TRANS}
```

結果:

      (戻り値なし)


3. 事後作業
===========


3.1. メトリックフィルタの確認
-----------------------------

作成したメトリックフィルタを確認します。

```bash:コマンド:
aws logs describe-metric-filters \
          --log-group-name ${LOG_GROUP_NAME}
```

結果(例):

      {
        "metricFilters": [
          {
              "filterName": "IAMAuthnAuthzActivity",
              "metricTransformations": [
                  {
                      "metricValue": "1",
                      "metricNamespace": "CloudTrailMetric",
                      "metricName": "IAMAuthnAuthzActivity"
                  }
              ],
              "creationTime": 1431235800304,
              "filterPattern": "{ ( ($.eventSource = "iam.amazonaws.com") && (($.eventName = "Add*") || ($.eventName = "Change*") || ($.eventName = "Create*") || ($.eventName = "Deactivate*") || ($.eventName = "Delete*") || ($.eventName = "Enable*") || ($.eventName = "Put*") || ($.eventName = "Remove*") || ($.eventName = "Update*") || ($.eventName = "Upload*")) ) }"
          }
        ]
      }


3.2. IAMグループの作成
----------------------

```bash:コマンド:
aws iam create-group --group-name test-`date +%Y%m%d`-01
```

結果(例):

      {
        "Group": {
          "Path": "/",
          "CreateDate": "2015-05-11T06:03:33.140Z",
          "GroupId": "AGPAIXZBI34RKKCMV27VS",
          "Arn": "arn:aws:iam::258890897647:group/test-20150511-01",
          "GroupName": "test-20150511-01"
        }
      }

メトリックが作成されるまでに次の作業を行います。


完了
====