[JAWS-UG CLI] SNS:#6 CloudTrail用トピックの作成

http://jawsug-cli.doorkeeper.jp/events/18569 でのハンズオン資料です。

AWS CLIを利用して、CloudTrailからの通知用トピックを作成してみます。


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

## SNSへの権限

* 操作するトピックに対してRead/Write権限があること。

## AWS CLIのバージョン

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

* AWS CLI 1.7.0


0. 事前準備
===========

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

CloudTrailの設定をするリージョンと同じリージョンを指定します。

```bash:コマンド(例):
export AWS_DEFAULT_REGION='ap-northeast-1'
```

このハンズオンでは、AWS標準のリージョン変数を利用していますが、regionオプションでコマンド毎に指定しても同様の結果になります。 
(「オペミスを回避するために明示的に実行する」という意味ではregionオプションの方が良いです。)



0.2. AWSアカウントIDの取得
----------------------------

AWSアカウントIDを取得します。
SNSのトピックポリシー作成のときに必要となります。

```bash:コマンド:
AWS_ID=`aws iam get-user --query 'User.Arn' --output text | sed 's/^.*:://' | sed 's/:.*$//'` \
  && echo ${AWS_ID}
```

1. トピックの作成
==========================

1.1. トピック名の決定
----------------------

通知先を登録するトピック名を決定します。

```bash:コマンド:
SNS_TOPIC_NAME="trail-${AWS_DEFAULT_REGION}" && echo ${SNS_TOPIC_NAME}
```

1.2. SNSトピックの作成
----------------------

手順: http://qiita.com/tcsh/items/e05e21e7338668cbf3b8

手順の中でトピックARNも取得しておきます。


2. トピックポリシーの作成
==========================


SNSトピックのポリシーをCloudTrail用に設定します。

```bash:コマンド:
FILE_SNS_TOPIC_POLICY='CloudTrail-topic-policy.json'
```

```bash:コマンド:
cat << EOF > ${FILE_SNS_TOPIC_POLICY}
{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {"AWS": "*"},
      "Action": [
        "SNS:Publish",
        "SNS:RemovePermission",
        "SNS:SetTopicAttributes",
        "SNS:DeleteTopic",
        "SNS:ListSubscriptionsByTopic",
        "SNS:GetTopicAttributes",
        "SNS:Receive",
        "SNS:AddPermission",
        "SNS:Subscribe"
      ],
      "Resource": "arn:aws:sns:${AWS_DEFAULT_REGION}:${AWS_ID}:${SNS_TOPIC_NAME}",
      "Condition": {
        "StringEquals":{
          "AWS:SourceOwner":"${AWS_ID}"
        }
      }
    },

    {
      "Sid": "AWSCloudTrailSNSPolicy20141006",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::903692715234:root",
          "arn:aws:iam::035351147821:root",
          "arn:aws:iam::859597730677:root",
          "arn:aws:iam::814480443879:root",
          "arn:aws:iam::216624486486:root",
          "arn:aws:iam::086441151436:root",
          "arn:aws:iam::388731089494:root",
          "arn:aws:iam::284668455005:root",
          "arn:aws:iam::113285607260:root"
        ]
      },
      "Action":"SNS:Publish",
      "Resource":"arn:aws:sns:${AWS_DEFAULT_REGION}:${AWS_ID}:${SNS_TOPIC_NAME}"
    }
  ]
}
EOF
```

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

```bash:コマンド:
$ cat ${FILE_SNS_TOPIC_POLICY} | json_verify
```

```text:結果:
JSON is valid
```

json_verifyでエラーが出たときはjsonlintでチェックします。

```bash:コマンド:
$ cat ${FILE_SNS_TOPIC_POLICY}| jsonlint
```


3. トピックポリシーの適用
==========================

3.1. トピックポリシーの適用
----------------------------

作成したCloudTrail用トピックポリシーをSNSトピックに適用します。

```bash:コマンド:
aws sns set-topic-attributes \
  --topic-arn ${SNS_TOPIC_ARN} \
  --attribute-name Policy \
  --attribute-value file://${FILE_SNS_TOPIC_POLICY}
```

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


3.2. トピックポリシーの確認
---------------------------

SNSトピックのトピックポリシーを確認します。


```bash:コマンド:
aws sns get-topic-attributes --topic-arn ${SNS_TOPIC_ARN}
```

```json:結果:
{
    "Attributes": {
        "SubscriptionsConfirmed": "0", 
        "DisplayName": null, 
        "SubscriptionsDeleted": "0", 
        "EffectiveDeliveryPolicy": "{\"http\":{\"defaultHealthyRetryPolicy\":{\"minDelayTarget\":20,\"maxDelayTarget\":20,\"numRetries\":3,\"numMaxDelayRetries\":0,\"numNoDelayRetries\":0,\"numMinDelayRetries\":0,\"backoffFunction\":\"linear\"},\"disableSubscriptionOverrides\":false}}", 
        "Policy": "{\"Version\":\"2008-10-17\",\"Id\":\"__default_policy_ID\",\"Statement\":[{\"Sid\":\"__default_statement_ID\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":[\"SNS:Publish\",\"SNS:RemovePermission\",\"SNS:SetTopicAttributes\",\"SNS:DeleteTopic\",\"SNS:ListSubscriptionsByTopic\",\"SNS:GetTopicAttributes\",\"SNS:Receive\",\"SNS:AddPermission\",\"SNS:Subscribe\"],\"Resource\":\"arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:trail-ap-northeast-1:\",\"Condition\":{\"StringEquals\":{\"AWS:SourceOwner\":\"XXXXXXXXXXXX\"}}},{\"Sid\":\"AWSCloudTrailSNSPolicy20141006\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam::903692715234:root\",\"arn:aws:iam::035351147821:root\",\"arn:aws:iam::859597730677:root\",\"arn:aws:iam::814480443879:root\",\"arn:aws:iam::216624486486:root\",\"arn:aws:iam::086441151436:root\",\"arn:aws:iam::388731089494:root\",\"arn:aws:iam::284668455005:root\",\"arn:aws:iam::113285607260:root\"]},\"Action\":\"SNS:Publish\",\"Resource\":\"arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:trail-ap-northeast-1:\"}]}", 
        "Owner": "XXXXXXXXXXXX", 
        "TopicArn": "arn:aws:sns:ap-northeast-1::XXXXXXXXXXXX:trail-ap-northeast-1:", 
        "SubscriptionsPending": "0"
    }
}
```

4. トピックの購読
===================

CloudTrailの動作確認のため、SNSトピックを購読しておきましょう。

手順: http://qiita.com/tcsh/items/ca81576b0018bfa32cbe


完了
=======

続いて、CloudTrail設定をします。