Help us understand the problem. What is going on with this article?

Well Architected Frameworkを意識して自分なりにアーキテクチャ設計・構築をしてみた。<VPC、ELB編>

はじめに

この記事は、実務未経験者がロールプレイング形式でアーキテクチャの設計、構築を行うといった記事です。
よろしければ<準備編><アーキテクチャ設計編>もご覧くださいませ。

前回までのあらすじ

前回は問題点を洗い出し、具体的な改善案を提案、アーキテクチャの設計を行いました。
image.png

今現在のアーキテクチャはこれですので、どんどん構築していきます!
スクリーンショット 2020-09-20 23.06.06.png

構築編

今回はVPCとALBの実装を行なっていきます。

VPC / 通信の範囲に応じてSubnetを作成

セキュリテイ向上の為にもWebサーバーをプライベートサブネットに移行します。
また、WEBサーバーとデータベースのセキュリティグループを細かく分けて設定したいで、サブネットも分けてみました。

今回は以下の3種類のサブネットを作成します。

  • publicサブネット

    • NATゲートウェイ、ELB設置用のサブネット
  • privateサブネット(WEBサーバー用)

    • メインのWEBサーバー設置用サブネット
  • privateサブネット(RDS用)

    • RDS設置用サブネット
    • ElastiCacheを追加する際はここのサブネットに配置

publicサブネットとprivateサブネット(RDS用)は前回作成したサブネットをそのまま使用できるので、privateサブネット(WEBサーバー用)を各AZに作成しました。
一応Nameタグも変更しておきましょう!
スクリーンショット 2020-09-23 16.55.42.png

6つのサブネットの作成が完了したので、WEBサーバーを移行します。
最新のゴールデンイメージ(AMI)を作成後、インスタンスの起動を行います。

Systems Manager / Session Managerを用いてSSHログインを行う

今回はWEBサーバーをプライベートサブネットに設置します。
SSH接続を行う為に、SSM用のIAMロールを作成しましょう。
IAMの「ロールの作成」→ユースケースから「EC2」を選択→ポリシーは「AmazonEC2RoleforSSM」を選択してください。
スクリーンショット 2020-09-23 17.01.28.png

スクリーンショット 2020-09-23 17.01.45.png

こちらのIAMロールをEC2に関連付けると、SSMのセッションマネージャーでSSH接続することが出来ます。

SSHキーも無しで大丈夫ですので、紛失の心配もありません。
(SSMを使用しない方法であれば、踏み台サーバーを設置する方法もありますが、冗長化や管理がめんどくさいのでマネージドサービスに任せましょう!)
スクリーンショット 2020-09-23 17.05.42.png

一応、セッションマネージャーを利用してSSH接続の確認も行なってみます!

Systems Managerからセッションマネージャーを選択
スクリーンショット 2020-09-23 17.14.08.png

セッションの開始を選択
スクリーンショット 2020-09-23 17.14.22.png

接続したいインスタンスを指定して、「セッションを開始する」
スクリーンショット 2020-09-23 17.14.29.png

普通にコマンドを実行出来ますのでオススメです!(もちろん、スマートフォンやタブレットでもアクセス可能です!)
スクリーンショット 2020-09-23 17.15.17.png

スマートフォンでもSSH接続してみました。
179045.jpg

VPC / NAT Gatewayの作成、Route Tableの定義

Privateサブネットからインターネットへアクセスする時に必要となる要素です。
冗長化の為に、各AZに配置します。

Routeテーブルは

  • publicサブネット
    →インターネットゲートウェイ

  • privateサブネット(WEBサーバー用)
    →冗長化の為に同じAZのNATゲートウェイにルーティング

  • privateサブネット(RDS用)
    RDSを利用しているので、一旦VPC内のルーティングのみ

に設定しました。

サクッとNATゲートウェイを作成して、ルーティングも設定しましょう
スクリーンショット 2020-09-23 17.24.10.png

ALB / ターゲットグループの作成

前回までは、テストの為にRoute53の複数値ルーティングを使用していましたが、今後の拡張性も考えて(WAF,AutoScalingの導入など)ALBを実装していきます。

まずはターゲットグループを作成していきます
マネジメントコンソールの「EC2」→「ターゲットグループ」から作成します。
スクリーンショット 2020-09-23 17.26.27.png
HTTPS化をする場合はプロトコルをHTTPSにしてください。
ヘルスチェックはプロトコルと、実際にチェックを行うパスを指定することが出来ます。

インスタンスを指定して、ターゲットグループを作成しましょう。
スクリーンショット 2020-09-23 17.29.38.png

ステッキーセッションの設定を行いたい場合は「属性」の方から設定することも出来ます。
スクリーンショット 2020-09-23 17.30.31.png

「維持設定」を選択すると、1秒から〜7日間まで指定することができます。
スクリーンショット 2020-09-23 17.34.05.png

ALB / ALBの作成

ターゲットグループの設定が終わったので、ロードバランサーを作成していきます。
今回はALBを選択しました。
HTTPS化をしたい場合は、「リスナー」からHTTPSを選択してください
VPCとサブネットの指定も行います。

「アドオンサービス」の「AWS Global Accelerator」を設定するとパフォーマンスが上がりますが、追加料金も掛かるので一旦スルーしておきます。
スクリーンショット 2020-09-23 17.38.07.png

セキュリティグループを選択しましょう。
ALBに関しては0.0.0.0/0のフルオープンでも問題ないでしょう
スクリーンショット 2020-09-23 17.40.29.png

ルーティングの設定で、先ほど作成したターゲットグループを指定してください。

スクリーンショット 2020-09-23 17.41.47.png

そのまま「作成」まで進むと、ALBの完成です。
一応DNS名からアクセス出来るかの確認もしましょう

Cloudwatch / ELBのメトリクスを監視

ELBの監視については、モニタリングのタブからメトリクスの確認が出来ます。
Cloudwatchアラームも設定可能ですので、閾値を設定してサーバーダウンを通知することも可能です
スクリーンショット 2020-09-23 17.46.26.png

主なメトリクスについて確認します。
こちらの記事が分かりやすいので確認しておきましょう
https://dev.classmethod.jp/articles/elb-and-cloudwatch-metrics-in-depth/

  • ELBがバックエンドのステータスコードをそのまま返す場合(HTTPCode_Backend_*)
    • 2XX~5XXまであります
    • 主にバックエンド側でのエラー
  • ELBが独自の判断によりステータスコードを返す場合(HTTPCode_ELB_*)
    • 2XX~5XXまであります
    • ELB側でのエラー
  • RequestCount
    • リクエストの合計値です。
    • HTTPCode_Backend_*の合計がRequestCount
  • SurgeQueueLength
    • ELBで処理出来ず、待機中のリクエスト
    • 基本的に0を目指しましょう(ELBのキャパシティを確認できますね)
  • SpilloverCount
    • ELBのキャパシティ(surge queue)を完全に超えてELBがエラーを返した数になります

ターゲットグループで確認出来るメトリクスもあります。

  • HealthyHostCount
    • ELBから見た正常なEC2インスタンス数の数
  • UnHealthyHostCount
    • ELBから見た異常なEC2インスタンス数の数

具体例を挙げてみます
2つのEC2インスタンスがあると仮定します。
2つとも正常な場合は
HealthyHostCount→2
UnHealthyHostCount→0

2つのインスタンスのサービスが停止している場合は
HealthyHostCount→0
UnHealthyHostCount→2

EC2自体が停止した場合に関しては注意が必要です。
2つのEC2インスタンスが停止している場合
HealthyHostCount→No Data
UnHealthyHostCount→No Data

となってしまいます。
ですので、「ロードバランシング対象サービスに異常がある場合」にも「EC2自体が停止した場合」にもどちらでもCloudWatchアラームを発報させるには、CloudWatchアラームの設定で、

  • ステータスがALARM(閾値を上回った場合、以下の設定ではHealthyHostsが1以下になった場合)
  • ステータスがINSUFFICIENT(データが不足している場合)

のどちらもアクション対象として設定してあげる必要があります。

VPC / VPC FlowLogの作成、S3にログの収集

事前にVPCフローログの出力先となるS3バケットを作成しておきます(今後のログ収集における出力先をこちらのバケットに設定しておくと、その後の分析等が楽になります。)

マネジメントコンソールの「VPC」→「アクション」→「フローログの作成」から作成画面に進んでください
スクリーンショット 2020-09-24 5.34.23.png

VPCフローログはCloudwatchLogs、S3で出力先を選ぶことが出来ますが、「Athenaで一括管理を行いたい」、「コスト」の観点からS3を出力先として指定します。
その他の設定はデフォルトのままでも大丈夫でしょう。
スクリーンショット 2020-09-24 5.35.12.png

S3への出力を確認してみましょう
スクリーンショット 2020-09-24 5.41.57.png

ログ自体は圧縮されたファイルで、尚且つめちゃくちゃ見にくいです。
普通はAthanaなどで分析、閲覧を行います。
スクリーンショット 2020-09-24 5.42.27.png

後ほどAthenaを使ってログの分析を行います!

VPC / Security Groupで必要最小限のアクセスのみを許可

基本的に、ネットワークにアクセスさせるリソース以外のセキュリティグループは最小限にしましょう。
例えば、ELBはフルオープンにせざるを得ないとしても、EC2のセキュリティグループは、ELBのみに制限する などです。

セキュリティグループはアクセス元として、IPアドレス以外にもアクセス元のリソースに関連付けられているセキュリティグループを指定することもできます。
管理も楽ですし、セキュリティグループをソースとして指定する方法をオススメします。

ちなみに補足としてネットワークACLによるアクセス制御も出来ますが、NACLはステートレスである為に一時ポートを考慮する必要があり、管理が大変です。

Config / セキュリティグループのSSH全開放をAWS Configによる自動修復によって修正する

よくやってしまいますが、SSHの全開放(0.0.0.0/0)もあまり好ましくありません。
今回はSystems Managerを使用しておりますので、WEBサーバーのセキュリティグループでSSHポートを開くことは無いと思いますが、AWS Config Rulesでコンプライアンスに非準拠となった時に自動修復が出来るようになりましたので、実装してみようと思います。

仕組みとしては
「ConfigがSSHの全開放を検知」→「Systems ManagerのAutomationによって修正」
という流れになっております。Config側でAutomationは起動してくれるので、SSM用のIAMロールを作成するだけで出来ます。

IAMロールを作成する前に今回必要なIAMポリシーを作成します。
「ポリシーの作成」からJSON形式を指定して、こちらのポリシーを作成して下さい。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:RevokeSecurityGroupIngress",
            "Resource": "*"
        }
    ]
}

ビジュアルエディタの場合はサービスとしてSSMではなくEC2を選択してください。アクションは「RevokeSecurityGroupIngress」です。
スクリーンショット 2020-09-24 6.57.51.png

IAMロールを作成後、Configの設定でIAMロールを関連づけるので、ARNをコピーしておきましょう。
スクリーンショット 2020-09-24 7.00.01.png

また、作成時にはサービスでEC2を選択して作成しましたが、SSMから利用するロールのため「信頼関係」からec2.amazonaws.comssm.amazonaws.comに変更します。
この手法はちょいちょい使いますので、覚えておくと良いでしょう
スクリーンショット 2020-09-24 7.00.08.png

Configの「ルールの追加」からルールを作成していきます。
マネージドルールの検索欄から「restricted-ssh」を指定して下さい。
スクリーンショット 2020-09-24 7.04.46.png

リソースは「AWS EC2 SecurityGroup」を指定します。
スクリーンショット 2020-09-24 7.11.18.png

ルールの作成が完了したら、「アクション」→「修復の管理」を選択します。
スクリーンショット 2020-09-24 7.12.05.png

修復アクションは「AWS-DisablePublicAccessForSecurityGroup」を選択。
リソースIDパラメーターは「GroupID」を選択して、先ほど作成したIAMロールのARNを入力したら完成です!
スクリーンショット 2020-09-24 7.13.23.png

「restricted-ssh」以外にも様々なマネージドルールがありますし、カスタムルールも作成可能ですので
「コンプライアンスに非準拠を検知」→「自動修復」のパターンが色々出来そうですね!

最後に

現時点でのアーキテクチャはこんな感じです。
image.png

参考

「セキュリティグループのSSH全開放をAWS Configで自動修復したら3分くらいで直ったからみんな使ってほしい件」
https://dev.classmethod.jp/articles/auto-recovery-restricted-ssh-without-lambda/

「VPCフローログをAmazon Athenaで分析する」
https://dev.classmethod.jp/articles/vpc-flow-logs-athena/

「ELB + CloudWatchアラームを使ったEC2サービス監視プラクティス」
https://dev.classmethod.jp/articles/elb-using-cloudwatch-alarm/

「ELBの挙動とCloudWatchメトリクスの読み方を徹底的に理解する」
https://dev.classmethod.jp/articles/elb-and-cloudwatch-metrics-in-depth/

mkoki0422
就職活動を始めた22卒の大学生(2020/9/19)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away