こんにちは
今日は、EC2 インスタンスの起動に失敗したらメールが届くようにすることができないか試してみたいと思います。
例えば、インスタンスの起動を aws cli から実行します。存在しないインスタンスIDなどを指定すると簡単に起動に失敗したエラーを出すことができると思います。
aws ec2 start-instances --instance-ids i-000000232a600000
(インスタンスIDは適当です)
こんな感じで実行するとCloudTrailのログに以下のように表示されます。
さらに詳細を表示すると、こんな感じに表示されています。今回の場合は、デタラメのインスタンスIDを指定したため、「Client.InvalidInstanceID.Malformed」と表示されています。これでテストしようと思います。
このようにCloudWatchに表示されるエラーをメールなどで通知できるといいのですが、CloudTrailではそれができないようです。ログなどをチェックしてある条件にマッチしたら、メールをするというようなことを実現するためには、CloudWatchという機能を使用しないといけないようです。
CloudTrailの証跡の作成
私もよく理解していないかもしれませんが、自分のアカウントで何かがあった時にメールを受け取るためには、「CloudTrailで証跡を作成する」、「SNSトピックを作成する」、「SNSトピックのサブスクリプションを作成する」、「EventBridgeでルールを作成する」とすることで、「CloudTrailにイベントが上がる(CloudWatchLogsへ記録される)→EventBridgeでルールにマッチする→指定されたSNSトピックに従ってメッセージが送信される」という動きになるようです。めちゃくちゃややこしくないですか?優秀な方が考える仕組みは難しくて理解できません。
証跡の作成
CloudTrailコンソールから、「証跡」を選択して、「証跡の作成」ボタンをクリックします。この「証跡の作成」をしておかないと、特定のイベントが発生した時にメールを送るというような動作を行うことができないようですので注意してください。ちなみに設定はできてしまって、メールが来ないという感じになります。。。ややこしい。
「証跡の作成」をクリックすると、証跡の設定画面が表示されます。証跡名に任意の名前を指定します。保存先はS3です。保存先のS3バケットを新規に作成したいため「新しいS3バケットを作成します」を選択して、フォルダ名称はデフォルトのままにしました。「ログファイルのSSE-KMS暗号化」のチェックは外しました。最初は、「Auditなんだから当然暗号化するでしょ!」とか思って暗号化したのですが、有償だったのでやめました。。。
SNSの設定
S3バケットにファイルを書き込んだ時にメッセージを送信する設定をします。この設定するとS3バケットに保存したというような通知がきます。今回の手順では、ここで作成したSNSの設定をS3への保存時だけではなく、後ほど説明する、EventBridgeのイベント発生時のメッセージの送信先としても使います。
「SNSによる通知の配信」のチェックをして、「新しいSNSトピックの作成」から「新規」を選択します。SNSトピックはデフォルトのままにしました。※ここでは、SNSのトピックしか作りませんので、SNSトピックにE-MAILで通知するように設定する必要があります。後ほど説明します。
CloudWatch Logs オプションを以下のように設定しました。
タグの設定
タグは特に設定せず、「次へ」をクリックします。
ログイベントの選択
ログするイベントの選択画面が表示されます。以下のように設定して「次へ」ボタンをクリックします。
確認と作成
最後に全体的な設定の確認画面が表示されますので。な強を確認して「証跡の作成」ボタンをクリックします。
設定が終わるとこのような表示になります。設定する項目がものすごく多いですよね。。。しかもまだ途中。。。。
ここまで設定してもまだメールは届きません。先ほど設定したSNSのトピックにサブスクリプションを追加する必要があります。
SNSのサブスクリプションの設定
SNSコンソールを開き、先程作成したSNSトピックをクリックします。
トピックを開くと次のような画面になりますので、「サブスクリプションの作成」をクリックします。
作成をクリックすると次のような画面になりますので、プロトコルをE-Mailに設定して、エンドポイントにメールの送信先を設定して、「サブスクリプションの作成」ボタンをクリックします。
正常に作成できると以下のような画面になります。
サブスクリプションが作成されましたが、まだ利用できる状態になっていません。SNSのコンソールへ戻って、「サブスクリプション」をクリックすると、先ほど作成したサブスクリプションのステータスが「保留中の確認」になっています。
E-Mailのサブスクリプションを設定すると、宛先に設定したメールに以下のようなメールが届きますので、Confirm Subscription というリンクをクリックします。
リンクをクリックしたら次のような画面が表示されます。
間違って、「click here to unsubscribe.」をクリックしないようにしてください。よく読めば間違うことはないと思いますが、ついクリックしたくなります。
再度SNSのサブスクリプションを開くと、「ステータス」が確認済みになっていることが確認できると思います。
EventBridgeの設定
まだまだ続きます。先程までの設定で、やっとCloudWatchへLogの保存ができるようになりましたが、S3へ書きましたよというイベントは来ますが、EC2起動失敗というようなイベントの通知は来ません。めんどくさ。
こちらの手順では、先程CloudTrailの証跡を設定した時に作成したSNSの設定を使用しますが、別のものを利用したい方は、SNSコンソールから作成しておいてください。
EventBridgeコンソールを開いて、「ルール」メニューをクリックし、「ルールの作成」ボタンをクリックします。
作成をクリックすると、次のような画面になります。名前と説明を設定して、「次へ」ボタンをクリックします。今回のケースでは以下のように設定しまました。
次へをクリックすると、「イベントパターンを構築」が開きます。「イベントソース」を「AWSイベント又は、EventBridgeパートナーイベント」をチェックします。
「サンプルイベント-オプション」の項目は特に変更しません。
抽出するイベントパターンを設定します。設定したら「次へ」ボタンをクリックします。
以下に抽出するイベントのパターンを示します。以下の条件にマッチした時に、指定したターゲットが動作するという仕組みのようです。
{
"source":["aws.ec2"],
"detail-type":["AWS API Call via CloudTrail"],
"detail":{
"eventSource":["ec2.amazonaws.com"],
"eventName":["StartInstances"],
"errorCode":["Client.InvalidInstanceID.Malformed"]
}
}
次に、イベントにマッチした時の動作を設定します。先程作成CloudTrailの証跡の作成で作成したSNSトピックを指定します。
「追加設定」の箇所を次のように設定します。ターゲットにゅ力を設定の箇所が、「一致したイベント」になっていることを確認して、そのほかはそのままの設定で「次へ」ボタンをクリックします。
タグの設定画面が常時されますが、特にタグは使用しないので、そのまま「次へ」ボタンをクリックします。
次へをクリックすると、設定の確認が表示されますので、「ルールの作成」ボタンをクリックします。
正常にルールが作成されると次のような画面になります。
早速、コマンドラインから以下のように実行します。適当なインスタンスIDを指定しました。
aws % aws ec2 start-instances --instance-ids i-000000232a6000000
実行すると、SNSでサブスクリプションに指定したメールアドレスに以下のようなメールがとd来ます。イベントをそのまま送信してくる感じです。よーくよく見ると、指定されたエラーコードが含まれているのがわかると思います。
メールが届くことは届きましたが、とてもわかりにくいですね。そのうちもうちょっとわかりやすく表示できるように頑張って見たいと思います。