皆様、お世話になっております。鈴木と申します。
前回まででRoute53とACMの設定を行いましたので、今回もCloudformationでALBを作成して暗号化通信を実現していきたいと思います。
1.目次
2.要件
- 前回まででACMで証明書を付与したRoute53で作成したドメインを使用してALBの暗号化通信を実現
- HTTP通信をHTTPS通信にリダイレクトさせる
- 2つのAZの各プライベートサブネットにあるEC2に負荷分散させる(ラウンドロビンで確認)
- ヘルスチェック用の実施
3.ALBについて
AWSのALBとNLBについて
AWSのロードバランサーには、主に2種類のタイプがあります:Application Load Balancer(ALB) と Network Load Balancer(NLB)です。
3-1. Application Load Balancer (ALB)
Application Load Balancer(ALB) は、アプリケーション層(レイヤー7)で動作するロードバランサーです。主にHTTPやHTTPSトラフィックを処理し、以下のような機能があります:
-
高度なルーティング機能:
- パスベースルーティング: リクエストのパスに基づいて異なるターゲットグループにルーティングできます(例:
/images
→image-service
)。 - ホストベースルーティング: リクエストのホストヘッダーに基づいて異なるターゲットグループにルーティングできます(例:
api.example.com
→api-service
)。 - クエリ文字列やヘッダーによるルーティング: 特定のクエリ文字列やヘッダーに基づくルーティングが可能です。
- パスベースルーティング: リクエストのパスに基づいて異なるターゲットグループにルーティングできます(例:
-
WebSocketとHTTP/2のサポート: リアルタイム通信や効率的なデータ転送を可能にします。
-
ターゲットグループ: 各ターゲットグループは複数のEC2インスタンスやコンテナで構成され、ALBはこれらにトラフィックを分散します。
-
セキュリティ: AWS Certificate Manager(ACM)との統合により、TLS証明書の管理やHTTPS通信の設定が容易です。
3-2. Network Load Balancer (NLB)との違いについて
特徴 | Application Load Balancer (ALB) | Network Load Balancer (NLB) |
---|---|---|
レイヤー | アプリケーション層(レイヤー7) | ネットワーク層(レイヤー4) |
トラフィックの種類 | HTTP、HTTPS | TCP、UDP、TCP_UDP(TCPとUDPの両方) |
ルーティング機能 | – パスベースルーティング – ホストベースルーティング – クエリ文字列やヘッダーによるルーティング |
– 基本的なルーティング(IPアドレスとポートに基づく) |
パフォーマンス | – 高機能なルーティング – レイヤー7の処理があるためレイテンシーが高くなる可能性がある |
– 高いスループット – 低レイテンシー |
静的IPアドレス | 動的IPアドレス | 静的IPアドレス |
プロトコルサポート | HTTP、HTTPS | TCP、UDP、TCP_UDP |
高可用性 | – AWS Certificate Manager(ACM)との統合によるHTTPS設定 – ターゲットグループへのトラフィック分散 |
– 高い耐障害性と可用性 – ゾーン単位での健康チェック |
追加機能 | – WebSocketとHTTP/2のサポート | – ゾーンヘルスチェック |
3-3.要点
-
ALBはアプリケーション層で動作し、HTTP/HTTPSトラフィックの高度なルーティングが可能です。セキュリティ機能が充実しており、ACMとの統合によりHTTPS通信が容易に設定できますが、レイヤー7の処理があるため、レイテンシーが高くなる可能性があります。
-
NLBはネットワーク層で動作し、TCP/UDPトラフィックの高いスループットと低レイテンシーを提供します。静的IPアドレスをサポートし、ネットワークトラフィックの高パフォーマンス処理が求められるシナリオに最適です。
4.構成図
すべての通信を暗号化します。
5.ソースコード全体
YAML形式にて記述しております。
Route53、ACM、ALBを同じファイルで記述しているため、ALB部分のみを抜粋しております。
またALBのアクセスログも取得するため、そちらも記述しております。
こちらで説明予定です。
# ALB 作成
LoadBalancerResource:
Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
Properties:
Name: "naoki-alb"
Scheme: "internet-facing"
Type: "application"
Subnets:
- !Ref Subnet1Id
- !Ref Subnet2Id
SecurityGroups:
- !Ref SecurityGroupId
IpAddressType: "ipv4"
Tags:
- Key: "Name"
Value: "naoki-alb"
LoadBalancerAttributes:
- Key: "access_logs.s3.enabled"
Value: "true"
- Key: "access_logs.s3.bucket"
Value: !Ref S3BucketName
- Key: "access_logs.s3.prefix"
Value: "alb-logs"
# ターゲットグループ作成
TargetGroupResource:
Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
Properties:
Name: "naoki-tg-web"
VpcId: !Ref VpcId
Protocol: "HTTP"
Port: 80
TargetType: "instance"
Targets:
- Id: !Ref InstanceId1
Port: 80
- Id: !Ref InstanceId2
Port: 80
HealthCheckEnabled: true
HealthCheckIntervalSeconds: 30
HealthCheckPath: "/mnt/efs/healthcheck.html"
HealthCheckPort: "traffic-port"
HealthCheckProtocol: "HTTP"
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
Matcher:
HttpCode: "200"
Tags:
- Key: "Name"
Value: "naoki-tg-web"
# HTTPS リスナー作成
HttpsListener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
LoadBalancerArn: !Ref LoadBalancerResource
Port: 443
Protocol: "HTTPS"
Certificates:
- CertificateArn: !Ref SubdomainCertificate
DefaultActions:
- Type: "forward"
TargetGroupArn: !Ref TargetGroupResource
# HTTP リスナー作成(HTTPS へのリダイレクト)
HttpListener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
LoadBalancerArn: !Ref LoadBalancerResource
Port: 80
Protocol: "HTTP"
DefaultActions:
- Type: "redirect"
RedirectConfig:
Protocol: "HTTPS"
Port: "443"
StatusCode: "HTTP_301"
6.ソースコード詳細
6-1.ALB作成
まずはALBの作成の詳細を下記にて記載します。
アクセスログのところは今後の構築で使用するため有効化しております。
またデフォルトでラウンドロビン形式となるため今回下記には指定していません。
使用するオプション | 設定値 | 説明 |
---|---|---|
Type | AWS::CertificateManager::Certificate | デフォルトの定義 |
DomainName | !Sub "${SubdomainName}" | サブドメインを指定 |
ValidationMethod | DNS | 検証方法をDNSで指定 |
DomainValidationOptions DomainName |
!Sub "${SubdomainName}" | 検証サブドメインを指定 |
DomainValidationOptions ValidationDomain |
!Sub "ホストドメイン名" | サブドメインのホストゾーンであるドメインを指定 |
Tags | Key: ‘Name’ Value: ‘naoki-acm’ |
タグのキーと値を設定 |
LoadBalancerAttributes | Key: "access_logs.s3.enabled "Value: "true" |
アクセスログを有効化 |
LoadBalancerAttributes | Key: "access_logs.s3.bucket" Value: !Ref S3BucketName |
保管先S3を指定 |
LoadBalancerAttributes | Key: "access_logs.s3.prefix" Value: "alb-logs" |
S3のプレフィックスを指定 |
# ALB 作成
LoadBalancerResource:
Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
Properties:
Name: "naoki-alb"
Scheme: "internet-facing"
Type: "application"
Subnets:
- !Ref Subnet1Id
- !Ref Subnet2Id
SecurityGroups:
- !Ref SecurityGroupId
IpAddressType: "ipv4"
Tags:
- Key: "Name"
Value: "naoki-alb"
LoadBalancerAttributes:
- Key: "access_logs.s3.enabled"
Value: "true"
- Key: "access_logs.s3.bucket"
Value: !Ref S3BucketName
- Key: "access_logs.s3.prefix"
Value: "alb-logs"
6-2.ターゲットグループ作成
事前にEC2にて/mnt/efsにヘルスチェック用のPHPファイルを作成しているためヘルスチェック先はそちらを指定しております。
使用するオプション | 設定値 | 説明 |
---|---|---|
Type | AWS::ElasticLoadBalancingV2::TargetGroup | デフォルトの定義 |
Name | naoki-tg-web | ターゲットグループ名 |
VpcId | !Ref VpcId | VPCIDを指定 |
Protocol | HTTP | プロトコルを指定 |
Port | 80 | プロトコルの番号を指定 |
TargetType | instance | インスタンスをターゲットに指定 |
Targets | Id: !Ref InstanceId1Id Port: 80 Id: !Ref InstanceId2Id Port: 80 |
インスタンスIDを指定 |
HealthCheckEnabled | true | ヘルスチェックを有効化 |
HealthCheckIntervalSeconds | 30 | 間隔(秒) |
HealthCheckPath | /healthcheck.php | ヘルスチェックパスを指定 |
HealthCheckPort | traffic-port | トラフィックポートを指定(TCP) |
HealthCheckProtocol | HTTP | ヘルスチェックのポートを指定 |
HealthCheckTimeoutSeconds | 5 | タイムアウトを指定(秒) |
HealthyThresholdCount | 5 | 正常なしきい値を指定 |
UnHealthyThresholdCount | 2 | 非正常のしきい値を指定 |
HttpCode | 200 | 成功コードを指定 |
Tags | Key: ‘Name’ Value: ‘naoki-tg-web’ |
タグのキーと値を設定 |
6-3.HTTPSリスナー作成
続いてHTTPS通信を受信できるようにリスナーを作成します。
使用するオプション | 設定値 | 説明 |
---|---|---|
Type | AWS::ElasticLoadBalancingV2::Listener | デフォルトの定義 |
LoadBalancerArn | !Ref LoadBalancerResource | ALBのARNを指定 |
Port | 443 | ポートを指定 |
Protocol | HTTPS | プロトコルを指定 |
CertificateArn | !Ref SubdomainCertificate | ACM(証明書)のARNを指定 |
Type | forward | リスナーが受け取るトラフィックをターゲットグループに転送 |
TargetGroupArn | !Ref TargetGroupResource | ターゲットグループのARNを指定 |
# HTTPS リスナー作成
HttpsListener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
LoadBalancerArn: !Ref LoadBalancerResource
Port: 443
Protocol: "HTTPS"
Certificates:
- CertificateArn: !Ref SubdomainCertificate
DefaultActions:
- Type: "forward"
TargetGroupArn: !Ref TargetGroupResource
6-4. HTTP リスナー作成(HTTPS へのリダイレクト)
続いてHTTP通信をHTTPSへリダイレクトできるようにリスナーを作成します。
使用するオプション | 設定値 | 説明 |
---|---|---|
Type | AWS::ElasticLoadBalancingV2::Listener | デフォルトの定義 |
LoadBalancerArn | !Ref LoadBalancerResource | ALBのARNを指定 |
Port | 80 | ポートを指定 |
Protocol | HTTP | プロトコルを指定 |
Type | redirect | リダイレクトを指定 |
Protocol | HTTPS | リダイレクト先プロトコルを指定 |
Port | 443 | リダイレクト先ポートを指定 |
StatusCode | HTTP_301 | ステータスコードを指定 |
7.テスト
7-1.テスト内容
今回はいくつかのテストを実施していきたいと思います。
- EC2の内容をWEBサーバーで表示できるか(ALB→EC2→NAT構成)
- ラウンドロビンで1号機・2号機を表示可能かどうか
- Route53で作成したドメイン経由でWEBサーバーへアクセスし暗号化通信をできているか
7-2.EC2の内容をWEBサーバーで表示できるか?(ALB→EC2→NAT構成)
実際にEC2にALBを紐づけてまずはALBのDNS経由でアクセスしていきます。
下記赤枠のDNSからWEBサーバーで検索をかけていきます。
そうすると下記でアクセスを確認できました。
7-3.ラウンドロビンで1号機・2号機を表示可能かどうか
こちらでページの更新(F5)をしていきます。
これで2号機の内容も表示させることが出来ましたのでラウンドロビン方式でできていることを確認できました。
7-4.Route53で作成したドメイン経由でWEBサーバーへアクセスし暗号化通信をできているか
最後にRoute53で証明書を付与したドメインでアクセスした際にHTTPSでの通信ができるのかを確認します。
下記でRoute53で作成したドメインを確認します。
ちなみにACMで証明書を発行できていることをACMのコンソール画面でも念のため表示しておきます。
こちらで検索をかけると…
HTTPSで通信できていることを確認しました。
最後にHTTPで通信するようにすると,,,
HTTPSへリダイレクトされていることを確認することが出来ました。
8.感想
Route53から一連の流れでの構築となりました。
ALBは資格試験ではよく出てきた内容でしたので構築時はそこまで戸惑うことは少なかったように感じます。
次回はここでも少し出てきましたが、ALBのアクセスログやVPCフローログについて投稿していきます。