お疲れ様です。株式会社協栄情報システム3部所属の寺尾です。

今回はマルチAZWordpressサイト構築の後編になります。前々回や前回に関しては下記のリンクをご参照ください。

また、全体の作業手順はWordPress環境構築手順をご確認ください。

それでは早速続きのほうをやっていきましょう。

5.監視システム構築

次にCloudWatchを使ってEC2にシステムエラーが起きてないか、EBSのディスク使用率が限界に近づいてないかを監視してみましょう。

1.SNSトピック作成

まずは通知メールの配信先となるSNSトピックを作成します。

1.サービスからSNS、サイドメニューからトピック、そしてトピックの作成を選びましょう。

2.以下の設定値にしたがってトピックを作成します。

設定項目 設定値 理由
名前 TPC-Wordpress01-tr 入力内容は任意
表示名 差出人の名前となる
暗号化 暗号化の無効化 サーバー側での暗号化は必要ないため
タグ: Name TPC-Wordpress01-tr 入力は任意
タグ: Env WordPress01 入力は任意


3.次に配信先を指定するためにサブスクリプションを作成します。

4.以下の設定値にしたがってサブスクリプションを作成します。

設定項目 設定値 理由
トピックARN TPC-Wordpress01-tr TPC-Wordpress01-trからの送信先のため
プロトコル EMAIL メールによって通知するため
エンドポイント 自分のメールアドレス 自分のメールアドレスに通知するため

5.すると指定したメールアドレスにメールが届きますのでリンクをクリックしてconfirmしましょう。

6.cofirmedになりました。

7.サブスクリプション一覧の画面に戻ると有効になっていることが確認できます。

2.CWAlarm(オートリカバリー)作成

次にシステムエラー時に通知と復旧を行うアラームを作成します。

1.サービス→CloudWatch→アラーム→アラームの作成へと進んでいきましょう。

2.インスタンスIDで検索し、メトリクス名:statuscheckfailed_systemになっているものを選びます。


3.以下の設定値通りに設定します。

設定項目 設定値 理由
インスタンスID 一台目:「EC2-Wordpress01-1」のインスタンスID
二台目:「EC2-Wordpress01-2」のインスタンスID
メトリクス名 StatusCheckFailed_System システムエラーを監視しオートリカバリーを行うため
統計 最大 エラーが起きていれば1、そうでなければ0であるため期間の途中からエラーが起きても検知できるように最大とした
期間 1分 迅速なオートリカバリーを考慮し最小値
しきい値の種類 静的
アラーム条件 以上 1以上でエラー状態とするため
…よりも 1 1以上でエラー状態とするため
アラームを実行するデータポイント 2/2 誤ったアラームを防止するため2回データポイントが越えた時アラーム状態に遷移する
欠落データの処理 欠落データを無視 アラーム後のデータ欠落時はなんらかのエラーが起きていることが予想されるため

欠落データを無視と見つかりませんの違いが分かりにくいですが、

  • 無視は欠落データがある場合はアラート状態を維持します

  • 見つかりませんは欠落データがあり、それによってアラーム状態を決めるのに十分なデータがなければInsufficient data状態になります。
    という違いがあります。
    システムエラーが起きた後、データが欠落すればそれは何かしらの異常が疑われますよね。ですのでそういった時にアラーム状態を継続する欠落データを無視を選びました。

  • 参考リンク
    Amazon CloudWatch アラームを使用する


4.アラーム状態のときに先ほど作成したSNSトピックに通知を送信します。
既存のSNSトピックにチェックし、通知の送信先に先ほど作成したSNSトピックを選びましょう。

設定項目 設定値 理由
アラーム状態トリガー アラーム状態 アラーム状態時に通知を送信するため
SNSトピックの選択 既存のSNSトピックの選択 自分宛のトピックをすでに作成したため
通知の送信先 TPC-Wordpress01 作成した自分宛のトピック
アラーム状態トリガー アラーム状態 アラーム状態時にオートリカバリーをするため
アクション このインスタンスを復旧 オートリカバリーをするため
名前 一台目:「CWA-Wordpress01-1」
二台目:「CWA-Wordpress01-2」
入力内容は任意
説明 Alarm for AutoRecover(SystemError) 入力内容は任意



5.確認して作成します。


6.作成に成功しました。ですので、もう一つのインスタンスの分もコピーして作成していきます。
アクションからコピーを選びましょう。

7.インスタンスIDと名前を書き換えて作成します。


8.無事作成できました。

3.CWAlarm(ディスク監視)作成

次はEBSのディスク使用率が70%以上の時にメールで通知してくれるアラームを作成したいと思います。

1.アラームの作成からメトリクスの選択へと進みます。

2.インスタンスIDで検索し、メトリクス名:DiskUsedPercent(ルートボリューム)メトリクスを選びます。

3.以下の設定値通りに設定します。

設定項目 設定値 理由
インスタンスID 一台目:「EC2-Wordpress01-1」のインスタンスID
二台目:「EC2-Wordpress01-2」のインスタンスID
メトリクス名 disk_used_percent ディスク使用率を監視するため
統計 平均 ディスク使用率は平均的に設定値を越えた時にアラーム状態に遷移してほしいので平均とした
期間 5分 緊急性がないのでデフォルト値
しきい値の種類 静的
アラーム条件 以上 70%以上でエラー状態とするため
…よりも 70 70以上でエラー状態とするため
アラームを実行するデータポイント 2/2 誤ったアラームを防止するため2回データポイントが越えた時アラーム状態に遷移する
欠落データの処理 欠落データを見つかりませんとして処理 データ欠落時はデータが欠落していると表示されても問題ないため


4.以下の設定値通りに作成します。今回は復旧はしないのでEC2アクションはデフォルトのままにしました。

設定項目 設定値 理由
アラーム状態トリガー アラーム状態 アラーム状態時に通知を送信するため
SNSトピックの選択 既存のSNSトピックの選択 自分宛のトピックをすでに作成したため
通知の送信先 TPC-Wordpress01 作成した自分宛のトピック
名前 一台目:「CWA-Wordpress01-3」
二台目:「CWA-Wordpress01-4」
入力内容は任意
説明 Alarm for monitoring DiskUsedPercent 入力内容は任意



5.確認して作成します。

6.同じようにもう一台作成しました。

7.EC2の中にダミーファイルを作成してCWAlarmの挙動を確認してみましょう。
dd if=/dev/zero of=1G.dummy bs=1MD count=2000
で二ギガバイト(1000の3乗のもの)を作成してみました。


8.さらにダミーファイルを作ってアラーム状態にしてみましょう。
dd if=/dev/zero of=3G.dummy bs=1MD count=3000
で二ギガバイト(1000の3乗のもの)を作成してみました。1G.dummyのところはファイル名なので1Gのままだと上書きされます。


しばらく待つとアラーム状態になります。

9.SNSトピックに登録したメールにきちんとアラートを通知するメールが届いていました。

10.最後に
rm 1G.dummy 3G.dummyコマンドでダミーファイルを削除すれば完了です。

4.CWAlarm(EC2死活監視)作成

EC2が問題なく動作しているか監視するアラームを作成しましょう。

1.サービスからEC2、サイドメニューからインスタンスを選びましょう。一つ目のインスタンスを選んだら、ステータスチェック、ステータスチェックアラームを作成へと進みます。

2.通知先に作成しておいたトピックを選びましょう。

3.以下の設定値の通りに設定して作成します。
名前が違いますが、入力項目はCWAlarmから作成した時とほとんど同じです。(一部項目が減っています)

設定項目 設定値 理由
アラーム通知 TPC-Wordpress01 自身のメールを設定したトピック
Group samples by 最大 エラーが起きていれば1、そうでなければ0であるため期間の途中からエラーが起きても検知できるように最大とした
Type of data to sample ステータスチェックの失敗:いずれか 死活監視を行うため
統計 最大 エラーが起きていれば1、そうでなければ0であるため期間の途中からエラーが起きても検知できるように最大とした
連続した期間 2 誤ったアラームを防止するため2回データポイントが越えた時アラーム状態に遷移する
期間 1分 迅速なオートリカバリーを考慮し最小値
名前 一台目:「CWA-Wordpress01-5」
二台目:「CWA-Wordpress01-6」
入力内容は任意

4.同じようにもう一台分作成します。


5.CWAlarm(ALB死活監視)作成

ALBの分散対象のEC2が正常かどうかを監視するアラームを作成します。

1.サービス→CWAlarm→アラームの作成へと進みます。

2.ALB名で検索し、ALBのHealthyHostCount(TGN-Wordpress01)メトリクスを選択しましょう。

3.以下の設定値通りに設定します。
欠落データを不正として処理するを選べばインスタンスが停止した時もアラームが発生するようにできます。(インスタンス停止時はデータが欠落扱いになります)

設定項目 設定値 理由
メトリクス名 HealthyHostCount 正常なホスト数を監視するため
LoadBalancer ALB-Wordpress01 監視対象となるロードバランサー
TargetGroup TGN-Wordpress01 監視対象となるターゲットグループ
統計 最小 正常なホスト数が1以下の際に通知を行うため
期間 1分 迅速な復旧のため最小値とする
しきい値の種類 静的
アラーム条件 以下 1以下でアラーム状態とするため
…よりも 1 1以下でアラーム状態とするため
アラームを実行するデータポイント 2/2 誤ったアラームを防止するため2回データポイントが越えた時アラーム状態に遷移する
欠落データの処理 欠落データを見つかりませんとして処理 データ欠落時はデータが欠落していると表示されても問題ないため


4.以下の設定値通りに設定します。

設定項目 設定値 理由
アラーム状態トリガー アラーム状態 アラーム状態時に通知を送信するため
SNSトピックの選択 既存のSNSトピックの選択 自分宛のトピックをすでに作成したため
通知の送信先 TPC-Wordpress01 作成した自分宛のトピック
名前 CWA-Wordpress01-7 入力内容は任意
説明 Alarm for monitoring HealthyHostCount 入力内容は任意


5.確認して作成しましょう。

6.全てのアラームが作成完了です!

6.ApacheアクセスログのエクスポートLambda作成

以前CloudWatchAgentの設定をパラメータストアに書き込んだ際、ApacheのアクセスログをCloudWatchLogsに出力するように書き込みました。
CloudWatchLogsに記録されているアクセスログをS3にLambdaを利用して毎日深夜0時(JST)にエクスポートしていきます。

1.まずはマネジメントコンソールからログが出力されていることを確認しましょう。
ログの中身がELBからのヘルスチェックになっているはずです。


2.ログの保持期間を3日に変更します。

  • Lambdaが動作しなかった場合の対応期間を考慮して三日にしました。

3.サービス→Lambda→関数の作成へと進みます。

4.以下の設定値通りに設定します。

設定項目 設定値 理由
関数の作成 1から作成
名前 Lambda-Wordpress01-Logexport 入力内容は任意
ランタイム Python3.8


4.作成後、以下の設定を編集します。

設定項目 設定値 理由
デッドレターキュー AmazonSNS Lambdaが処理できなかあった時に自分のメールに送るため
トピック TPC-Wordpress01 作成した自分宛のトピック
Name Lambda-Wordpress01-Logexport 入力は任意
Env WordPress01 入力は任意
環境変数
TZ Asia/Tokyo タイムゾーンを東京に変更するため



5.下記のコードを入力し、デプロイします。
自分の環境に合わせて

  • Lambda関数名
  • 保存先S3バケット名
  • 取得するCloudWatchロググループ名
    を編集しましょう。
import datetime
import time
import boto3

lambda_name = 'Lambda-Wordpress01-Logexport'    #Lambda関数名
s3_bucket_name = 's3-wordpress01-tr'    #保存先S3バケット名
s3_prefix = lambda_name + '/%s' % (datetime.date.today() - datetime.timedelta(days = 1))

def get_from_timestamp():
    today = datetime.date.today()
    yesterday = datetime.datetime.combine(today - datetime.timedelta(days = 1), datetime.time(0, 0, 0))
    return int(yesterday.timestamp())

def get_to_timestamp(from_ts):
    return from_ts + (60 * 60 * 24) - 1

def lambda_handler(event, context):
    from_ts = get_from_timestamp()
    to_ts = get_to_timestamp(from_ts)
    print('Timestamp: from_ts %s, to_ts %s' % (from_ts, to_ts))

    client = boto3.client('logs')
    response = client.create_export_task(
        logGroupName      = '/var/log/httpd/access_log',     #取得するCloudWatchロググループ名
        fromTime          = from_ts * 1000,
        to                = to_ts * 1000,
        destination       = s3_bucket_name,     #保存先S3バケット名(修正なしで可)
        destinationPrefix = s3_prefix    #保存先S3バケット名配下の任意のサブフォルダ名(修正なしで可)
    )
    return response

参考リンクCloudWatchLogsをLambdaで自動的にS3へアップロードする1つの仕掛け

  • 以上のコードは昨日の0時(JST)から昨日の23時59分59秒(JST)までのログをエクスポートするものです。

  • 1~3行目

    import datetime
    import time
    import boto3

    は必要なライブラリのインストールですboto3(AWS操作用ライブラリ)と標準ライブラリ以外のライブラリは.zip ファイル形式でデプロイする必要があります。

  • 5~7行目

    lambda_name = 'Lambda-Wordpress01-Logexport'    #Lambda関数名
    s3_bucket_name = 's3-wordpress01-tr'    #保存先S3バケット名
    s3_prefix = lambda_name + '/%s' % (datetime.date.today() - datetime.timedelta(days = 1))

    で変数に関数名、バケット名、プレフィックス名(関数名/前日の日付)を代入しています。

  • 9~12行目

    def get_from_timestamp():
    today = datetime.date.today()
    yesterday = datetime.datetime.combine(today - datetime.timedelta(days = 1), datetime.time(0, 0, 0))
    return int(yesterday.timestamp())

    は前日の0時のUNIX時間を戻り値として返す関数です。

  • 14~15行目

    def get_to_timestamp(from_ts):
    return from_ts + (60 * 60 * 24) - 1

    は引数となるUNIX時間に23時間59分59秒を加えたものを戻り値として返す関数です。

  • 17~30行目

    def lambda_handler(event, context):
    from_ts = get_from_timestamp()
    to_ts = get_to_timestamp(from_ts)
    print('Timestamp: from_ts %s, to_ts %s' % (from_ts, to_ts))
    
    client = boto3.client('logs')
    response = client.create_export_task(
        logGroupName      = '/var/log/httpd/access_log',     #取得するCloudWatchロググループ名
        fromTime          = from_ts * 1000,
        to                = to_ts * 1000,
        destination       = s3_bucket_name,     #保存先S3バケット名(修正なしで可)
        destinationPrefix = s3_prefix    #保存先S3バケット名配下の任意のサブフォルダ名(修正なしで可)
    )
    return response

    は前述の関数とあらかじめ定めた変数を使いUNIX時間で昨日の0時から23時59分までのログを出力しています。

6.テストイベントを作成し、テストしてみます。
Valueのないテストイベントを作り、実行しましょう。


7.成功したのでs3の中を確認してみましょう。
指定したプレフィックス(関数名/前日の日付/エクスポートタスクID/インスタンスID)の下にアクセスログが確認できます。
※ 前日のアクセスログがない場合は確認できません。

7.Amazon EventBridgeでイベント作成

1.トリガーを追加を選択します。

2.以下の設定値通りに作成しましょう。
タグは作成後編集することで追加できます。

設定項目 設定値 理由
ルール名 Eventbridge-Wordpress01 入力内容は任意
ルールの説明 For Log Export 入力は任意
ルールタイプ スケジュール式 毎晩0時にスケジュールするため
スケジュール式 cron(0 15 ? *) UTC表記なので15時0分を指定
Name Eventbridge-Wordpress01 入力は任意
Env WordPress01 入力は任意



7.一日待ってs3の指定したプレフィックス(関数名/前日の日付/エクスポートタスクID/インスタンスID)の中を確認してみましょう。
深夜0時にエクスポートされたログが確認できます。
※ 12:00 AM は深夜0時の意味です。12:00 PM が昼の12時です。

file

6.Wordpress設定とhttps設定

次はいよいよWordpressの設定です。

1.Wordpressのインストールおよび設定

1.http://自分のレコード名/wp-admin/install.php
にアクセスしましょう。日本語を選択して進みましょう。

2.さあ、始めましょう!を選びます。

3.RDSを作成する時に設定した項目を入力しましょう。データベースのホスト名はマネジメントコンソールから確認できます。

4.インストールを実行します。

5.必要情報を入力してインストールします。

6.インストールに成功しました。

7.ログインしてみましょう。

2.ACMで証明書の作成

次にhttpsでアクセスできるようにしていきます。まずはACMを利用して証明書を作成しましょう。

1.サービスからACMを選び、証明書のプロビジョニングへと進みましょう。

2.以下の設定値にしたがって作成しましょう。

設定項目 設定値 理由
証明書のリクエスト パブリック証明書のリクエスト インターネット上で利用するため
ドメイン名の追加 自分のドメイン名
検証方法の選択 DNSの検証 DNSを変更する権限があるため
Name ACM-Wordpress01 入力は任意
Env WordPress01 入力は任意

※ ドメイン名は*.domain.comかreocrd.dmain.comのような形で入力します。




3.確認してリクエストします。

4.Route53でレコードを作成し、証明書を有効化すれば完了です。


3.httpsの設定

手に入れた証明書を使ってhttpsでアクセスできるようにしていきましょう。

1.ALBのリスナーにhttpsプロトコル443ポートを追加します。転送先は先ほど作成したターゲットグルループでSSL証明書はACMで作成した物を選びましょう。

2.リスナーが追加できました。

3.Wordpressの画面に戻ってhttpsを導入するためのプラグインを検索しています。

4.Really Simple SSLをインストールしました。

5.有効化します。

6.httpsを介して再読み込みを選択します。

7.SSLを有効化します。

8.再度ログインしましょう。

9.設定→一般からアドレスを確認すると、httpsになっていることが確認できました。

10.URLの左側にも、接続が保護されていますと表記されました。これで暗号化された通信が可能になりましたね。

11.ALBから不要になったhttpのリスナールールを削除します。

12.ALBのセキュリティグループからもhttpのものを削除します。

これにて構成図のすべてのものが作成完了しました!
作ったものを放置しているとお金がかかるので使い終わったら削除は忘れずに!

おわりに

大変長い記事でしたがここまで読んでいただきありがとうございました。
一つのアーキテクチャを0から全て構築するのはかなり大変でしたが、いい勉強になりました。
間違いなどあればぜひご指摘ください。
この記事が誰かの助けとなれば幸いです。

Last modified: 2022-05-23

Author