---
AWSTemplateFormatVersion: '2010-09-09'
Description: ALB with HTTPS listener and fixed response

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          default: "ALB Configuration"
        Parameters:
          - VPCID
          - Subnets
          - R53Zone
          - R53ZoneId

Parameters:

  VPCID:
    Type: AWS::EC2::VPC::Id
    Description: VPCID

  Subnets:
    Type: List<AWS::EC2::Subnet::Id>
    Description: Public Subnets (min 2) from VPC

  R53Zone:
    Type: String
    Description: R53 Domain for ALB DNS entry
    Default: domain.without.dot.in.the.end.com

  R53ZoneId:
    Type: AWS::Route53::HostedZone::Id
    Description: R53 Domain ID for ALB DNS entry

Rules:

  SubnetsInVPC:
    Assertions:
    - Assert:
        Fn::EachMemberIn:
        - Fn::ValueOf:
          - Subnets
          - VpcId
        - 
          - !Ref VPCID
      AssertDescription: All subnets must be within the given VPC

Outputs:

  URL:
    Description: ALB URL
    Value: !Sub 'https://${AWS::StackName}.${R53Zone}/'

Resources:

  R53Record:
    Type: AWS::Route53::RecordSet
    Properties:
      Type: A
      AliasTarget:
        HostedZoneId: !GetAtt ALB.CanonicalHostedZoneID
        DNSName: !GetAtt ALB.DNSName
      Comment: !Sub '${AWS::StackName} ALB alias'
      HostedZoneId: !Ref R53ZoneId
      Name: !Sub '${AWS::StackName}.${R53Zone}.'

  SSLCert:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: !Sub '${AWS::StackName}.${R53Zone}'
      DomainValidationOptions: 
        - DomainName: !Sub '${AWS::StackName}.${R53Zone}'
          HostedZoneId: !Ref R53ZoneId
      ValidationMethod: DNS

  ALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Type: application
      Scheme: internet-facing
      Subnets: !Ref Subnets
      SecurityGroups: 
        - !Ref ALBSecGroup

  ALBSecGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: !Sub "${AWS::StackName} ALB, allow port 443 from 0.0.0.0/0"
      SecurityGroupIngress: 
        - CidrIp: 0.0.0.0/0
          FromPort: 443
          ToPort: 443
          IpProtocol: tcp
      VpcId: !Ref VPCID

  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties: 
      DefaultActions: 
        - Type: fixed-response
          Order: 1
          FixedResponseConfig:
            ContentType: text/html
            StatusCode: 200
            MessageBody: "<html><title>Hello</title><body><h1>Hello World!</h1></body></html>"
      LoadBalancerArn: !Ref ALB
      Port: 443
      Protocol: HTTPS
      Certificates: 
        - CertificateArn: !Ref SSLCert
