概要
CloudFormationを使ってHTTPS用のListnerとTarget Groupを作成し、HTTPS通信できるよう設定する方法について解説します
前提
- ECSを作成済み
- ドメインをRoute53に作成済み
- ACMを作成済み
以下の記事でECSとALBを作成する方法について解説したので気になる方は読んでいただけると幸いです
ディレクトリ構成
tree
.
└── templates
└── security
└── sg.yml
実装
ALBとRoute53の設定を行います
alb.yml
AWSTemplateFormatVersion: 2010-09-09
Description: "ALB Stack"
# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
AWS::CloudFormation::Interface:
# パラメータの並び順
ParameterGroups:
- Label:
default: "Project Configuration"
Parameters:
- ProjectName
- Environment
- Label:
default: "ELB Configuration"
Parameters:
- VPCID
- HostZoneID
- ALBPublicSubnet1
- ALBPublicSubnet2
- ALBSecurityGroupID
- ACMCertificateArn
- HealthCheckPath
- DeletionProtectionEnabled
- IdleTimeoutSeconds
- ELBSecurityPolicy
# -------------------------------------
# Input parameters
# -------------------------------------
Parameters:
ProjectName:
Description: "Enter the project name. (ex: my-project)"
Type: String
MinLength: 1
ConstraintDescription: "ProjectName must be enter."
Default: my-project
Environment:
Description: "Select the environment."
Type: String
AllowedValues:
- dev
- stg
- prd
ConstraintDescription: "Environment must be select."
HostZoneID:
Type: AWS::Route53::HostedZone::Id
Description: "Select the Route 53 hosted zone ID"
DomainName:
Description: "Enter the Route 53 domain name"
Default: api.shun-practice.com
Type: String
VPCID:
Description: "Select the VPC ID."
Type: AWS::EC2::VPC::Id
ALBPublicSubnet1:
Description: "Enter the Subnet ID for ALB in the selected VPC."
Type: AWS::EC2::Subnet::Id
ALBPublicSubnet2:
Description: "Enter the Subnet ID for ALB in the selected VPC."
Type: AWS::EC2::Subnet::Id
ALBSecurityGroupID:
Description: "Select the Security Group ID for ALB."
Type: AWS::EC2::SecurityGroup::Id
ACMCertificateArn:
Description: "Enter the Certificate ARN. (ex: arn:aws:acm:<AWS_REGION>:<AWS_ACCOUNT_ID>:certificate/<ACMCertificateID>)"
Type: String
# ALB からのヘルスチェックに応答するパス
HealthCheckPath:
Description: "Enter the path respond to health checks from ALB."
Type: String
Default: /api/health
# 今回は検証用のためfalse
DeletionProtectionEnabled:
Description: "Select whether to enable deletion protection."
Type: String
Default: false
AllowedValues:
- false
- true
# アイドルタイムアウト値
IdleTimeoutSeconds:
Description: "Enter the ALB idle timeout seconds. (default: 60)"
Type: String
Default: 60
# https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/create-https-listener.html
ELBSecurityPolicy:
Description: "Select the ELB security policies."
Type: String
AllowedValues:
- ELBSecurityPolicy-TLS-1-2-Ext-2018-06
- ELBSecurityPolicy-TLS13-1-2-2021-06
# -------------------------------------
# Resources
# -------------------------------------
Resources:
# -------------------------------------
# Target Groups
# -------------------------------------
ALBTargetGroupBlue:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn: InternetALB
Properties:
Name: !Sub ${ProjectName}-${Environment}-tg-blue
TargetType: ip
Protocol: HTTP
Port: 80
VpcId: !Ref VPCID
HealthCheckProtocol: HTTP
HealthCheckPath: !Ref HealthCheckPath
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
ALBTargetGroupGreen:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn: InternetALB
Properties:
Name: !Sub ${ProjectName}-${Environment}-tg-green
TargetType: ip
Protocol: HTTP
Port: 80
VpcId: !Ref VPCID
HealthCheckProtocol: HTTP
HealthCheckPath: !Ref HealthCheckPath
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
# -------------------------------------
# Elastic Load Balancer
# -------------------------------------
InternetALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Type: application
Name: !Sub ${ProjectName}-${Environment}-alb-fargate
Scheme: internet-facing
LoadBalancerAttributes:
- Key: "deletion_protection.enabled"
Value: !Ref DeletionProtectionEnabled
- Key: "idle_timeout.timeout_seconds"
Value: !Ref IdleTimeoutSeconds
Subnets:
- !Ref ALBPublicSubnet1
- !Ref ALBPublicSubnet2
SecurityGroups:
- !Ref ALBSecurityGroupID
Tags:
- Key: ProjectName
Value: !Ref ProjectName
- Key: Environment
Value: !Ref Environment
# -------------------------------------
# Listener
# -------------------------------------
ALBListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroupBlue
LoadBalancerArn: !Ref InternetALB
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref ACMCertificateArn
SslPolicy: !Ref ELBSecurityPolicy
ALBListenerHTTPTest:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroupBlue
LoadBalancerArn: !Ref InternetALB
Port: 8080
Protocol: HTTP
# -------------------------------------
# Route 53
# -------------------------------------
ALBAliasRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostZoneID
Name: !Ref DomainName
Type: A
AliasTarget:
HostedZoneId: !GetAtt InternetALB.CanonicalHostedZoneID
DNSName: !GetAtt InternetALB.DNSName
# -------------------------------------
# Output parameters
# -------------------------------------
Outputs:
InternetALBArn:
Value: !Ref InternetALB
InternetALBName:
Value: !GetAtt InternetALB.LoadBalancerName
ALBTargetGroupBlueArn:
Value: !Ref ALBTargetGroupBlue
ALBTargetGroupBlueName:
Value: !GetAtt ALBTargetGroupBlue.TargetGroupName
ALBTargetGroupGreenArn:
Value: !Ref ALBTargetGroupGreen
ALBTargetGroupGreenName:
Value: !GetAtt ALBTargetGroupGreen.TargetGroupName
ターゲットグループ
今回はBlue/Greenデプロイ用にターゲットグループを2つ作成します
# -------------------------------------
# Target Groups
# -------------------------------------
ALBTargetGroupBlue:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn: InternetALB
Properties:
Name: !Sub ${ProjectName}-${Environment}-tg-blue
TargetType: ip
Protocol: HTTP
Port: 80
VpcId: !Ref VPCID
HealthCheckProtocol: HTTP
HealthCheckPath: !Ref HealthCheckPath
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
ALBTargetGroupGreen:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn: InternetALB
Properties:
Name: !Sub ${ProjectName}-${Environment}-tg-green
TargetType: ip
Protocol: HTTP
Port: 80
VpcId: !Ref VPCID
HealthCheckProtocol: HTTP
HealthCheckPath: !Ref HealthCheckPath
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
リスナー
HTTPS通信用にALBListenerHTTPS、Blue/Greenデプロイ用にALBListenerHTTPTestを作成します
ALBListenerHTTPSにACMの設定を行うことでHTTPSで通信できるようになります
また、今回はALBListenerHTTPTestのリスナーのポートを8080に指定します
# -------------------------------------
# Listener
# -------------------------------------
ALBListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroupBlue
LoadBalancerArn: !Ref InternetALB
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref ACMCertificateArn
SslPolicy: !Ref ELBSecurityPolicy
ALBListenerHTTPTest:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroupBlue
LoadBalancerArn: !Ref InternetALB
Port: 8080
Protocol: HTTP
Route53
API用のサブドメインの設定を行います
Route53のAレコードにサブドメインのURLが作成されます
# -------------------------------------
# Route 53
# -------------------------------------
ALBAliasRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostZoneID
Name: !Ref DomainName
Type: A
AliasTarget:
HostedZoneId: !GetAtt InternetALB.CanonicalHostedZoneID
DNSName: !GetAtt InternetALB.DNSName
実際に作成してみよう!
ALBを作成します
ACMを指定する際はALBと同じRegionのものを指定する必要があるので注意が必要です
以下のようにALBのリスナーとターゲットグループが作成され、ヘルスチェックがHealthyになっていたら成功です
参考