[備忘録]HTTPS化の作業を一撃で終わらせるCloudFormationテンプレートについて
自身で作ったテンプレを残しておくための備忘録です。
どーもsutoです。AWSのサービスを駆使してWebサーバ(EC2)のSSL設定を自動化するテンプレートを作成しました。
要件
前提
- 対象のEC2は既に作成済
- Route53でドメイン取得、ホストゾーン作成が完了済
テンプレートで自動化する項目
- ALB、ターゲットグループ、リスナーを新規作成
- Route53の既存ホストゾーン下にサブドメインを新規作成、エイリアスにALBをアタッチ
- ALBに紐づけるSGの新規作成
- AWS Certificate Manager(ACM)で証明書を発行、対象のサブドメインに設定
試してみた
以下のテンプレートにテストパラメータを入力して実行結果を見てみます。
AWSTemplateFormatVersion: '2010-09-09' Description: Create new ALB, ACM, SG, https Parameters: ServerName: Description: Server Name Type: String Default: 'test' VPCID: Description: VPC ID Type: String Default: 'vpc-xxx' PrimarySubnet: Description: PrimarySubnet ID Type: String Default: 'subnet-xxx' SecondarySubnet: Description: SecondarySubnet ID Type: String Default: 'subnet-xxxx' AllowIP: Description: IP Address for SG Type: String Default: '' AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})" ConstraintDescription: "Must be a valid IP range of the form x.x.x.x/x" EC2Web1: Description: EC2 Instance ID Type: String Default: 'i-xxx' HostZoneId: Description: FQDN of the hosted zone Type: String Default: 'Z0xxx' DomainName: Description: FQDN of the HostZone Type: String Default: 'example.com' SubDomain: Description: FQDN of the certificate Type: String Default: 'test.example.com' Resources: SGloadbalancer: Type: 'AWS::EC2::SecurityGroup' Properties: GroupName: !Sub ${ServerName}-alb-sg GroupDescription: !Sub ${ServerName}-alb-sg VpcId: !Ref VPCID SecurityGroupIngress: - IpProtocol: tcp FromPort: '443' ToPort: '443' CidrIp: !Ref AllowIP Tags: - Key: Name Value: !Sub ${ServerName}-alb-sg TargetGroup: Type: "AWS::ElasticLoadBalancingV2::TargetGroup" Properties: VpcId: !Ref VPCID Name: !Sub ${ServerName}-tg Protocol: HTTP Port: 80 HealthCheckProtocol: HTTP HealthCheckPath: "/" HealthCheckPort: "traffic-port" HealthyThresholdCount: 5 UnhealthyThresholdCount: 2 HealthCheckTimeoutSeconds: 5 HealthCheckIntervalSeconds: 30 Matcher: HttpCode: 200 Targets: - Id: !Ref EC2Web1 Port: 80 InternetALB: Type: "AWS::ElasticLoadBalancingV2::LoadBalancer" Properties: Name: !Sub ${ServerName}-alb Scheme: "internet-facing" LoadBalancerAttributes: - Key: "deletion_protection.enabled" Value: false - Key: "idle_timeout.timeout_seconds" Value: 4000 SecurityGroups: - !Ref SGloadbalancer Subnets: - !Ref PrimarySubnet - !Ref SecondarySubnet ALBListenerHTTP: 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 InternetALB ALBListenerHTTPS: Type: AWS::ElasticLoadBalancingV2::Listener Properties: Port: 443 Protocol: HTTPS Certificates: - CertificateArn: !Ref ACM DefaultActions: - TargetGroupArn: !Ref TargetGroup Type: forward LoadBalancerArn: !Ref InternetALB DnsRecord: Type: AWS::Route53::RecordSet Properties: HostedZoneId: !Sub '${HostZoneId}' Comment: "DNS for ALB" Name: !Sub '${SubDomain}' Type: A AliasTarget: HostedZoneId: !GetAtt 'InternetALB.CanonicalHostedZoneID' DNSName: !GetAtt 'InternetALB.DNSName' ACM: Type: AWS::CertificateManager::Certificate Properties: DomainName: !Sub '${SubDomain}' DomainValidationOptions: - DomainName: !Sub '${SubDomain}' HostedZoneId: !Sub '${HostZoneId}' ValidationMethod: DNS
約15分程度でスタック処理が完了。無事リソースが出来ていました。
2020年6月17日のアップデートによりACMのDNS検証が自動化されたため、間に手作業をまったく入れずスタックの完了を待つだけで設定できるのはホントに素晴らしい!
時間に余裕があるときにParametersの記述を整理したいなと思います。
作成経緯における個人的な注意点
- 当初”RecordSet”のホストゾーンの指定を”HostedZoneName”にしていたが、値を「example.com.」(←最後にドットが必要)にしなければならず紛らわしかったので”HostedZoneId”の指定に変えた
- このスタックを削除しても、DNS検証で自動作成されたRoute53のCNAMEは削除されず残ってしまうため、不必要なら手動で削除すること
以上となります。