[AWS]ALBのHTTPtoHTTPSリダイレクトをCloudFormationで実装する

CloudFormationを使って、一発でロードバランサーを作成します。また、HTTPをHTTPSへリダイレクトする設定が追加されます。
2019.02.25

コンニチハ、千葉です。

ALBの機能を利用することで、HTTPをHTTPSにリダイレクトが可能です。

[新機能]Webサーバでの実装不要!ALBだけでリダイレクト出来るようになりました!

今回、リダイレクトの設定をCloudFormationを使って構築したので残しておきます。

やってみた

まずは手動で設定してみる

どのパラメータを指定すればいいかわからなかったので、まずは手動で設定してみました。 HTTPからHTTPSへリダイレクトする、リスナールールを設定します。

最終的にリスナールールが https://#{host}:443/#{path}?#{query}、ステータスコードがHTTP_301となっていればよさそうです。

CloudFormationを書く

まずはポート番号80の定義です。ロードバランサーのリスナーの設定箇所で、デフォルトアクションにリダイレクトの定義を追加します。 Type: redirectにて、リダイレクトを指定します。RedirectConfigにて詳細なパラメータを指定します。 https://#{host}:443/#{path}?#{query}、ステータスコードがHTTP_301になるように指定します。 ポイントは、Pathだと/が必要だったり、Queryだと?の指定が不要だったりします。

参考:

Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Port: 80
Protocol: HTTP
DefaultActions:
- Type: redirect
RedirectConfig:
Host: '#{host}'
Path: '/#{path}'
Port: 443
Protocol: HTTPS
Query: '#{query}'
StatusCode: HTTP_301
LoadBalancerArn: #ALBのARNを指定

次に、ポート番号443のリスナー設定です。プロトコルにHTTPSを指定して、証明書も指定しましょう。

Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: #ACMのARNを指定
DefaultActions:
- TargetGroupArn: #ターゲットグループのARNを指定
Type: forward
LoadBalancerArn: #ALBのARNを指定

Cloudformationで構築してみた

実際にCloudFormationスタックでELBを構築してみて、リダイレクトされるか確認してみました。 80番のリスナーは、想定通りのパラメータで作成されています。

実際にアクセスしてみて、リダイレクトされるか確認してみました。

問題なくHTTPからHTTPSへリダイレクトされました!

CloudFormationの全体

コピペ用です。ロードバランサー、リスナー、ターゲットグループを作成します。また、HTTPからHTTPSへリダイレクトします。 Mappingsに適宜パラメータ指定してご利用ください。

前提

CloudFormationを流す前提を書いておきます。

  • VPCが作成済みであること
  • ELB用のセキュリティグループが作成済みであること
  • ACMにて証明書で発行し、有効になっていること
  • ロードバランサーにアタッチするEC2が構築済みであること

作成されるリソース

このテンプレートで作成されるリソースは以下です。

  • ターゲットグループ
  • インターネットフェイシングのALB
  • HTTPリスナー
  • HTTPSリスナー

コード

AWSTemplateFormatVersion: '2010-09-09'
Description: This CloudFormation template to create ELB.

Mappings:
prd:
VPC: { ID: vpc-xxx }
PublicSubnet1a: { ID: subnet-xxx }
PublicSubnet1c: { ID: subnet-xxx }
AlbSecurityGroup: { ID: sg-xxx }
Web1Ec2Instance: { ID: i-xxx }
Web2Ec2Instance: { ID: i-xxx }
Certificate: { ARN: 'arn:aws:acm:ap-northeast-1:xxxx:certificate/xxxx' }

Parameters:
Environment:
Description: Type of this environment.
Type: String
Default: prd
AllowedValues:
- prd
- stg
SystemName:
Description: Name of this system.
Type: String
Default: chiba-lb
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Environment Configuration
Parameters:
- SystemName
- Environment

Resources:
# ALB
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub ${Environment}-${SystemName}-alb
Type: application
Scheme: internet-facing
IpAddressType: ipv4
SecurityGroups:
- !FindInMap [ !Ref Environment, AlbSecurityGroup, ID ]
Subnets:
- !FindInMap [ !Ref Environment, PublicSubnet1a, ID ]
- !FindInMap [ !Ref Environment, PublicSubnet1c, ID ]
Tags:
- Key: Name
Value: !Sub ${Environment}-${SystemName}-alb
ApplicationLoadBalancerListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Port: 80
Protocol: HTTP
DefaultActions:
- Type: redirect
RedirectConfig:
Host: '#{host}'
Path: '/#{path}'
Port: 443
Protocol: HTTPS
Query: '#{query}'
StatusCode: HTTP_301
LoadBalancerArn: !Ref ApplicationLoadBalancer
ApplicationLoadBalancerListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !FindInMap [ !Ref Environment, Certificate, ARN ]
DefaultActions:
- TargetGroupArn: !Ref AlbTargetGroup
Type: forward
LoadBalancerArn: !Ref ApplicationLoadBalancer

# ALB Target group
AlbTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${Environment}-${SystemName}-web-tg
Port: 80
Protocol: HTTP
Targets:
- Id: !FindInMap [ !Ref Environment, Web1Ec2Instance, ID ]
Port: 80
- Id: !FindInMap [ !Ref Environment, Web2Ec2Instance, ID ]
Port: 80
# Health check
HealthCheckProtocol: HTTP
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
Matcher:
HttpCode: 200
VpcId: !FindInMap [ !Ref Environment, VPC, ID ]
Tags:
- Key: Name
Value: !Sub ${Environment}-${SystemName}-web-tg

Outputs:
AlbEndpoint:
Value: !GetAtt ApplicationLoadBalancer.DNSName

最後に

CloudFormationを使って、HTTPをHTTPSへリダイレクトするELBを作りました。コード管理しておくと、何かと便利なのでコピペ用に置いておきます!

参考

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-loadbalancer.html