AWS-Systems-Manager

【AWS SSM Run Command】S3イベントで自動的にファイルを同期させる[後編]

はじめに

お疲れ様です、寺井です。

今回のお話は、前回の記事(【SSM Run Command】S3イベントで自動的にEC2にファイルを同期させる[前編])の続きとなりますので、まだ前編を見ていないという方は、前編を見てからお読みいただくことをオススメします。

簡単な振り返り

前回は準備段階として

  • EC2(Webアプリケーションサーバー)
  • S3 (アプリケーションファイルの同期元)

の構築をしました。

今回は

  • [EventBridge]を使用して[S3イベント通知]をトリガーに、[SSM Run Command]を実行するルールの作成
  • 一連の動作と結果を確認する
    といった流れで進めていきたいとおもいます。

実装

リソース名は今回検証に使用したものを記載しておりますので、適宜ご自身の環境のリソース名に読み換えてください。

EventBridge(トリガー)の準備

S3バケットの[Object Created]イベントをトリガーに、SSM Run Commandを実行するEventBridgeルールを作成します。

ルールの詳細

Amazon EventBridge>ルール>ルールを作成

  • 名前、説明  :(お好きな名前で)
  • イベントバス :default
  • ルールタイプ :イベントパターンを持つルール

イベントパターンを構築

作成したS3バケットの特定のイベントを検知する[イベントパターン]を作成する

  • イベントソース  :AWS イベントまたは EventBridge パートナーイベント
  • 作成のメソッド  :パターンフォームを使用する
  • イベントパターン
    イベントソース   :AWS のサービス
    AWS のサービス   :Simple Storage Service (S3)
    イベントタイプ   :Amazon S3 イベント通知
      ├ 特定のイベント  :Object Created
      └ 特定のバケット  :s3sync-test-bucket-20230213


イベントパターンのjsonデータは以下のような内容になる

{
  "source": ["aws.s3"],
  "detail-type": ["Object Created"],
  "detail": {
    "bucket": {
      "name": ["s3sync-test-bucket-20230213"]
    }
  }
}

ターゲットを選択

先程設定したイベントをトリガーに、何をターゲットとして呼び出すかを設定する

  • ターゲットタイプ  :AWS のサービス
  • ターゲットを選択  :System Manager 実行コマンド
    ドキュメント    :AWS-RunShellScript
    ターゲットキー   :InstanceIds
    ターゲット値    :{対象のEC2インスタンスID}

[自動化パラメータを設定]

  • 定数(実際に実行するコマンド)
    Commands :aws s3 sync --exact-timestamps {S3 URI} {アプリケーションのディレクトリパス}

  • 実行ロール :この特定のリソースについて新しいロールを作成

これでS3イベント通知をトリガーにSSM Run Commandを実行するイベントルールが完成しました。

実行確認

実際にS3イベントを発火させてみて、Run Commandの実行履歴に出力されるかを確認します。

SSM Run Command実行履歴

AWS Systems Manager>Run Command

[コマンド履歴]タブでコマンドの実行履歴が閲覧できます。

S3にファイルをアップロード(ファイルを更新)する

アプリケーションの変化が分かるように、ファイルの一部を変更してからアップロードしてみます。

$version = "1.0";
↓変更
$version = "2.0";

Amazon S3>バケット>s3sync-test-bucket-20230213>app/>アップロード

対象のアプリケーションファイルをアップロードする

SSM Run Commandが実行されたことを確認する

先程は空だった[コマンド履歴]タブにコマンドの実行履歴が出力されている

コマンドIDを選択して詳細を確認する

[ターゲットと出力]の欄で対象のインスタンスIDを選択した状態で「出力の表示」

[アウトプット]の欄を確認するとコマンド実行時の出力結果が閲覧できる

アプリケーションが更新されているか確認

ブラウザからアプリケーションを確認すると、無事更新されていることが確認できました!

[おまけ]S3イベント通知をSNSで通知するときの注意点

現在S3で設定できるイベントの送信先は以下の3つです。

  • Lambda 関数
  • SNS トピック
  • SQS キュー

ついでにSNS通知も作ってみます。

SNSトピックの作成

Amazon SNS>トピック>トピックの作成

  • タイプ    :スタンダード
  • 名前、表示名 :s3sync-test-bucket-app-update-sns(お好きな名前で)

  • アクセスポリシー
    {
    "Version": "2008-10-17",
    "Id": "__default_policy_ID",
    "Statement": [
        {
            "Sid": "__default_statement_ID",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "SNS:GetTopicAttributes",
                "SNS:SetTopicAttributes",
                "SNS:AddPermission",
                "SNS:RemovePermission",
                "SNS:DeleteTopic",
                "SNS:Subscribe",
                "SNS:ListSubscriptionsByTopic",
                "SNS:Publish"
            ],
            "Resource": "arn:aws:sns:ap-northeast-1:{アカウントID}:s3sync-test-bucket-app-update-sns",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceOwner": "{アカウントID}"
                }
            }
        },
        {
            "Sid": "SNS topic policy",
            "Effect": "Allow",
            "Principal": {
                "Service": "s3.amazonaws.com"
            },
            "Action": [
                "SNS:Publish"
            ],
            "Resource": "arn:aws:sns:ap-northeast-1:{アカウントID}:s3sync-test-bucket-app-update-sns",
            "Condition": {
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:s3:::s3sync-test-bucket-20230213"
                },
                "StringEquals": {
                    "aws:SourceAccount": "{アカウントID}"
                }
            }
        }
    ]
    }

上記アクセスポリシーを設定しておかないと、S3イベント通知作成時に以下のエラーが表示されます

「Unable to validate the following destination configurations」

参考:発行先 SNS トピックの IAM ポリシー

SNSトピックが作成できたら、[サブスクリプションの作成]からご自身のメールアドレス等を通知先として登録します。

これで必要な通知先[SNS]の設定は完了です。

S3イベントの作成

  • イベント名
    s3sync-test-bucket-app-update-event(お好きな名前で)

  • プレフィックス - オプション
    「app/」とし、「app」フォルダ内の変更を検知

  • イベントタイプ
    「作成・削除・復元」の3つのイベントにチェック

  • 送信先
    先程作成したSNSトピックを選択

作成が完了すれば、以下内容のテストメールが送信されます

{"Service":"Amazon S3","Event":"s3:TestEvent","Time":"2023-02-13T07:54:38.597Z","Bucket":"s3sync-test-bucket-20230213","RequestId":"RPKV9Y0KFC7PXEDV","HostId":"fix5mVQO5J5kufk0UhbPh+92mMnGcw6XY5SK89zWu0RjoNvkm7LNr2PMf/EGNn70HJJk1hOiRQE="}

--
If you wish to stop receiving notifications from this topic, please click or visit the link below to unsubscribe:
https://sns.ap-northeast-1.amazonaws.com/unsubscribe.html?SubscriptionArn=arn:aws:sns:ap-northeast-1:{アカウントID}:s3sync-test-bucket-app-update-sns:6690d012-2b4b-4c45-8730-7bbd04caa35b&Endpoint=<メールアドレス>

Please do not reply directly to this email. If you have any questions or comments regarding this email, please contact us at https://aws.amazon.com/support

上記テストメールが届いていれば、設定以降のS3イベントにおいては、以下のようなイベント内容のjsonデータが届くようになります。

{
    "Records": [
        {
            "eventVersion": "2.1",
            "eventSource": "aws:s3",
            "awsRegion": "ap-northeast-1",
            "eventTime": "{日時}",
            "eventName": "ObjectCreated:Put",
            "userIdentity": {
                "principalId": "AWS:AIDA52S24SOFF7R5KBNIW"
            },
            "requestParameters": {
                "sourceIPAddress": "{送信元IPアドレス}"
            },
            "responseElements": {
                "x-amz-request-id": "MDTHMMY5C1HVJNGG",
                "x-amz-id-2": "WA43Vh2CPAagGPVEkj4qOGHOrc1xGyP6rnMCNYNoyI885s5sBv/hilZKb6CsaRjrSLSJq/CHimZs1c2O7c4z2YChcseqL6zY"
            },
            "s3": {
                "s3SchemaVersion": "1.0",
                "configurationId": "s3sync-test-bucket-app-update-event",
                "bucket": {
                    "name": "s3sync-test-bucket-20230213",
                    "ownerIdentity": {
                        "principalId": "A1Z2IXQ7UVXNFF"
                    },
                    "arn": "arn:aws:s3:::s3sync-test-bucket-20230213"
                },
                "object": {
                    "key": "app/index.php",
                    "size": 460,
                    "eTag": "6a8ad5db622137819438cead524a8ca2",
                    "versionId": "S82fex1J_d20haUne2nOboB5OnwrpwE7",
                    "sequencer": "0063EF3DD21F3D1FE2"
                }
            }
        }
    ]
}

これにてS3イベント通知として、SNSトピックを通知先とする設定は完了です。

感想

やっぱり「自動化」って良いですね。

簡素的なアーキテクチャではありましたが、もっと複雑でカッコいい自動化がサクッとできるように精進していきます。

最後までお読みいただきありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA