Patch-ManagerでWindowsUpdate自動化

参考

SSMパッチマネージャー利用時のハマりポイントをまとめてみた

スケジュール作成

  1. System Manager > パッチマネージャ
    「パッチ適用の設定」ボタンをクリック

  2. パッチを適用するインスタンス

    項目
    選択 インスタンスタグを入力する
    インスタンスタグ/キー ForceWindowsUpdat
    インスタンスタグ/値 true
  3. パッチ適用スケジュール

    項目
    パッチ適用の指定方法 新しいメンテナンスウィンドウでスケジュールを作成する
    メンテナンスの指定方法 CRON スケジュールビルダーを使用
    メンテナンスの実行頻度 毎日 / 11:00 UTC
    メンテナンスの最大時間 2時間 (※)
    メンテナンス名 ForceWindowsUpdate

    (※)
    20:00 JST から、WindowsUpdateを開始する
    22:00 JST にOSを停止を実行するので、2時間あればUpdate終わると予想

  4. パッチ適用オペレーション

    項目
    アクション スキャンのみ

    ※「インストール」は、パッチ適用後に再起動が発生するので注意

  5. 「パッチ適用の設定」ボタンをクリック

スケジュールを確認する方法

  1. System Manager > メンテナンスウィンドウ


    Patch Managerからのパッチ適用は
    内部的には、Run Command で、AWS-RunPatchBaseline を実行しているだけ


    AWS-RunPatchBaseline は
    ベースライン(適用するパッチの種類(クリティカルとか)指定)をパラメータに取らない


    パッチのあたったインスタンスは強制的に再起動がかかります

対象インスタンスをセット

  1. EC2インスタンスにタグをつける

    項目
    タグ名 ForceWindowsUpdate
    true

SNS通知用の IAMポリシーを作成する

SNS通知用の IAMポリシーを作成する

  1. IAM > ポリシー > ポリシーの作成 > JSONタブ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": [
    "sns:Publish"
    ],
    "Resource": "*"
    }
    ]
    }
  2. ポリシーの確認

    項目
    Name SNSPublishPermissions
  3. ポリシーの作成ボタンをクリック

SNS通知用の IAMロールを作成する

  1. IAM > ロール > ロールの作成

  2. AWSサービス > EC2 を選択し、「次のステップ:アクセス権限」ボタンをクリック

  3. アタッチするポリシー選択画面で、作成した「SNSPublishPermissions」を選択

  4. 「次のステップ:タグ」ボタンをクリック
    「次のステップ:確認」ボタンをクリック

  5. ロール名 を入力

    項目
    Name AmazonSNSFullAccess
  6. 「ロールの作成」ボタンをクリック

  7. 作成したロールを選択

  8. 「信頼関係」タブを選択し、”ssm.amazonaws.com” を既存のポリシーに追加

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "",
    "Effect": "Allow",
    "Principal": {
    "Service": [
    "ec2.amazonaws.com",
    "ssm.amazonaws.com"
    ]
    },
    "Action": "sts:AssumeRole"
    }
    ]
    }


    EC2 / SNS

    • IAMロール: AmazonSNSFullAccess
      • IAMポリシー: SNSPublishPermissions

通知用のSNSトピックを作成

  1. SNS > トピック > トピックの作成

    項目
    名前 run_command_report_to_slack
    表示名 -
    暗号化 無効
    アクセスポリシー 基本
    メッセージ発行を許可するユーザー トピック所有者のみ
    トピックにサブスクライブを許可するユーザー トピック所有者のみ
    再送ポリシー デフォルト
    ログ記録 なし
  2. トピックの作成

通知用のLambda関数を作成

  1. Lambda関数

    項目
    名前 Func-PatchManager_slack
    ランタイム Node.js v10
    実行ロール lambda_basic_exection
    説明 PatchMangerがEC2のアップデートを実行した結果をSlack通知
    ネットワーク 非VPC
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    console.log('Loading function');

    const https = require('https');
    const url = require('url');
    const slack_url = 'https://hooks.slack.com/services/xxxxxxxx';
    const slack_req_opts = url.parse(slack_url);
    slack_req_opts.method = 'POST';
    slack_req_opts.headers = {'Content-Type': 'application/json'};

    exports.handler = function(event, context) {
    (event.Records || []).forEach(function (rec) {

    if (rec.Sns) {
    var req = https.request(slack_req_opts, function (res) {
    if (res.statusCode === 200) {
    context.succeed('posted to slack');
    } else {
    context.fail('status code: ' + res.statusCode);
    }
    });

    req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
    context.fail(e.message);
    });

    var message = JSON.parse(rec.Sns.Message);

    var str = "*Subject* :" + rec.Sns.Subject + "\n" +
    "*CommandId* :" + message.commandId + "\n" +
    "*Status* :" + message.status + "\n" +
    "*DocumentName* :" + message.documentName ; "\n" +
    "*InstanceID* :" + message.instanceId + "\n" +
    "*RequestedDatetime* : " + message.RequestedDatetime + "\n" +
    "*EventTime* :" + message.eventTime;

    req.write(JSON.stringify({text: str}));

    req.end();
    }
    });
    };
  2. Lambdaに SNSのトリガーを追加

    項目
    トリガー SNS
    トピック arn:aws:sns:ap-northeast-1:xxx:run_command_report_to_slack
    有効化 on

メンテナンスの通知

  1. System Manager > メンテナンスウインドウ > 対象を選択

  2. 「タスク」タブ > 対象を選択 > 編集

  3. SNS通知

    項目
    SNS通知を有効化 ON
    ロール AmazonSNSFullAccess
    SNSトピック arn:aws:sns:ap-northeast-1:xxx:run_command_report_to_slack
    次の場合通知する 成功/タイムアウト/キャンセル済/失敗
    通知 コマンドのステータスが変更された場合のコマンド概要

AWS Lambda暖気運転

参考

AWS Lambdaの初回起動が遅い問題を解決する魔法の設定

設定

  1. Lamda関数のトリガを開く

  2. 「設定」タブで、「トリガーを追加」をクリック

  3. 「CloudWatch Events」を選択

  4. 「新しいルール」を選択

    設定値
    ルール名 Lambda-WarmUp
    説明 Lambdaの暖気運転
    ルールタイプ スケジュール式
    スケジュール式 rate(5 minutes)
    トリガーの有効 ON
  5. 「追加」をクリック

暖気の実行間隔

Tune Up AWS Lambda

5分間隔程度がおススメ

AWS ALBへのIPアドレス直アクセスを防ぐ

問題点

クラウド型WAFを導入している場合、IPアドレスでELBに直アクセスされると、WAFによるセキュリティチェックを回避されてしまう。

ELB設定

  1. ALB(Appliation LoadBalancer) > 「リスナー」タブを選択

  2. 「HTTP:80」のルール表示

    1. HTTPのアクセスは、HTTPSへ301リダイレクトさせる

      IF Action
      パス * リダイレクト先
      HTTPS/443
      カスタムホスト、パス、クエリを使用
      ホスト: www.example.co.jp
      パス: /#{path}
      クエリ: #{query}
      301 - 完全に移動されました

通信の流れ

  1. http://IPアドレス 」または「http://ALB_DNS名」でアクセスがくる
  2. ルール1により、httpsサイトへ301リダイレクトさせる
  3. 指定したhttpsサイトへFQDNでアクセスがくるようになる

注意点

  • ALB (Application Load Balancer) でないと、URIによる振り分けが出来ない
  • HTTPSが必要

AWS CloudFront CORS設定について

参考

AWS S3とCloudFrontにCORSの設定をしてCSSファイルやJSファイルを配信する

CORS(Cross-Origin Resource Sharing)

CORSとは

Cross-Origin Resource Sharing

オリジン(Origin)とは、

スキーム(http://やhttpsなど)
ホスト名(example.comなど)
ポート番号(:3000など)
のこと。

CORS設定について

システム構成

  • Ajaxリクエストを発行する側を A
  • Ajaxリクエストを受けてレスポンスを返す側を B
  1. ブラウザは、Bへのリクエストヘッダーにアクセス元のオリジン情報を付加

    1
    Origin: http://A-site.example.com
  2. Bは、Aへのアクセスを許可する場合に下記レスポンスヘッダを返す

    1
    Access-Control-Allow-Origin: http://A-site.example.com
  3. ブラウザはレスポンスを見て、許可された別オリジンへのアクセスと判断する

CORS-01

CORS-02

CloudFrontでのCORS

S3に置いたコンテンツをCloudFrontでキャッシュして配信する構成の場合、HTTPヘッダーもキャッシュする設定にしないと、せっかく組んだCORSの設定が反映されない

CloudFrontの設定画面

  1. ディストリビューションを選択する。
  2. 「Cache Based on Selected Request Headers」で「WhiteList」を選択する。
  3. 「Whitelist Headers」に「Origin」を追加する。

CloudFrontは設定を変更しても今キャッシュされているファイルが、再度オリジンから取得されるわけではない。 そこで、コンテンツをオリジンから再取得するために、以下のどちらかの操作をする必要がある。

  • オリジンのコンテンツのファイル名を変更して、CloudFront越しにアクセス
  • CloudFrontのInvalidation(キャッシュ削除)を実行する

Ruby on Rails などのフレームワークは、1番目の方法
Asset Pipelineを利用して、CSSやJavaScriptをビルドしている
ただ、一度プリコンパイルしたCSS・JavaScriptファイルは変更しないと、ダイジェストが変わらないので注意

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×