AWSTemplateFormatVersion: 2010-09-09
Description: Deploy a Check Point Cluster in a new VPC (20230801)
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: VPC Network Configuration
        Parameters:
          - AvailabilityZones
          - VPCCIDR
          - PublicSubnet1CIDR
          - PublicSubnet2CIDR
          - PrivateSubnet1CIDR
          - PrivateSubnet2CIDR
      - Label:
          default: EC2 Instance Configuration
        Parameters:
          - GatewayName
          - GatewayInstanceType
          - KeyName
          - AllocatePublicAddress
          - VolumeSize
          - VolumeEncryption
          - EnableInstanceConnect
          - GatewayPredefinedRole
          - TerminationProtection
      - Label:
          default: Check Point Settings
        Parameters:
          - GatewayVersion
          - Shell
          - GatewayPasswordHash
          - GatewaySICKey
      - Label:
          default: Quick connect to Smart-1 Cloud (Recommended)
        Parameters:
          - MemberAToken
          - MemberBToken
      - Label:
          default: Advanced Settings
        Parameters:
          - ResourcesTagName
          - GatewayHostname
          - AllowUploadDownload
          - CloudWatch
          - GatewayBootstrapScript
          - NTPPrimary
          - NTPSecondary
    ParameterLabels:
      AvailabilityZones:
        default: Availability zones
      VPCCIDR:
        default: VPC CIDR
      PublicSubnet1CIDR:
        default: Public subnet 1 CIDR
      PublicSubnet2CIDR:
        default: Public subnet 2 CIDR
      PrivateSubnet1CIDR:
        default: Private subnet 1 CIDR
      PrivateSubnet2CIDR:
        default: Private subnet 2 CIDR
      GatewayName:
        default: Gateway Name
      GatewayInstanceType:
        default: Security Gateways instance type
      KeyName:
        default: Key name
      AllocatePublicAddress:
        default: Allocate Elastic IPs
      VolumeSize:
        default: Root volume size (GB)
      VolumeEncryption:
        default: Volume encryption KMS key identifier
      EnableInstanceConnect:
        default: Enable AWS Instance Connect
      GatewayPredefinedRole:
        default: Existing IAM role name
      TerminationProtection:
        default: Termination Protection
      GatewayVersion:
        default: Version & license
      Shell:
        default: Admin shell
      GatewayPasswordHash:
        default: Password hash
      GatewaySICKey:
        default: SIC key
      MemberAToken:
        default: Smart-1 Cloud Token for member A
      MemberBToken:
        default: Smart-1 Cloud Token for member B
      ResourcesTagName:
        default: Resources prefix tag
      GatewayHostname:
        default: Gateway Hostname
      AllowUploadDownload:
        default: Allow upload & download
      CloudWatch:
        default: CloudWatch metrics
      GatewayBootstrapScript:
        default: Bootstrap Script
      NTPPrimary:
        default: Primary NTP server
      NTPSecondary:
        default: Secondary NTP server
Parameters:
  AvailabilityZones:
    Description: The availability zones in which to deploy the cluster.
    Type: List<AWS::EC2::AvailabilityZone::Name>
    MinLength: 2
  VPCCIDR:
    Description: The CIDR block for your VPC.
    Type: String
    Default: 10.0.0.0/16
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$'
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28.
  PublicSubnet1CIDR:
    Description: The 1st external subnet of the cluster. The cluster's public IPs will be generated from this subnet.
    Type: String
    Default: 10.0.10.0/24
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$'
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28.
  PublicSubnet2CIDR:
    Description: The 2nd external subnet of the cluster. The cluster's public IPs will be generated from this subnet.
    Type: String
    Default: 10.0.20.0/24
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$'
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28.
  PrivateSubnet1CIDR:
    Description: The 1st internal subnet of the cluster. The cluster's private IPs will be generated from this subnet.
    Type: String
    Default: 10.0.11.0/24
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$'
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28.
  PrivateSubnet2CIDR:
    Description: The 2nd internal subnet of the cluster. The cluster's private IPs will be generated from this subnet.
    Type: String
    Default: 10.0.21.0/24
    AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$'
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28.
  GatewayName:
    Description: The name tag of the Security Gateway instances. (optional)
    Type: String
    Default: Check-Point-Cluster
  GatewayInstanceType:
    Description: The instance type of the Secutiry Gateway.
    Type: String
    Default: c5.xlarge
    AllowedValues:
      - c5.large
      - c5.xlarge
      - c5.2xlarge
      - c5.4xlarge
      - c5.9xlarge
      - c5.12xlarge
      - c5.18xlarge
      - c5.24xlarge
      - c5n.large
      - c5n.xlarge
      - c5n.2xlarge
      - c5n.4xlarge
      - c5n.9xlarge
      - c5n.18xlarge
      - m5.large
      - m5.xlarge
      - m5.2xlarge
      - m5.4xlarge
      - m5.8xlarge
      - m5.12xlarge
      - m5.16xlarge
      - m5.24xlarge
      - m6i.large
      - m6i.xlarge
      - m6i.2xlarge
      - m6i.4xlarge
      - m6i.8xlarge
      - m6i.12xlarge
      - m6i.16xlarge
      - m6i.24xlarge
      - m6i.32xlarge
      - c6i.large
      - c6i.xlarge
      - c6i.2xlarge
      - c6i.4xlarge
      - c6i.8xlarge
      - c6i.12xlarge
      - c6i.16xlarge
      - c6i.24xlarge
      - c6i.32xlarge
      - c6in.large
      - c6in.xlarge
      - c6in.2xlarge
      - c6in.4xlarge
      - c6in.8xlarge
      - c6in.12xlarge
      - c6in.16xlarge
      - c6in.24xlarge
      - c6in.32xlarge
      - r5.large
      - r5.xlarge
      - r5.2xlarge
      - r5.4xlarge
      - r5.8xlarge
      - r5.12xlarge
      - r5.16xlarge
      - r5.24xlarge
      - r5a.large
      - r5a.xlarge
      - r5a.2xlarge
      - r5a.4xlarge
      - r5a.8xlarge
      - r5a.12xlarge
      - r5a.16xlarge
      - r5a.24xlarge
      - r5b.large
      - r5b.xlarge
      - r5b.2xlarge
      - r5b.4xlarge
      - r5b.8xlarge
      - r5b.12xlarge
      - r5b.16xlarge
      - r5b.24xlarge
      - r5n.large
      - r5n.xlarge
      - r5n.2xlarge
      - r5n.4xlarge
      - r5n.8xlarge
      - r5n.12xlarge
      - r5n.16xlarge
      - r5n.24xlarge
      - r6i.large
      - r6i.xlarge
      - r6i.2xlarge
      - r6i.4xlarge
      - r6i.8xlarge
      - r6i.12xlarge
      - r6i.16xlarge
      - r6i.24xlarge
      - r6i.32xlarge
      - m6a.large
      - m6a.xlarge
      - m6a.2xlarge
      - m6a.4xlarge
      - m6a.8xlarge
      - m6a.12xlarge
      - m6a.16xlarge
      - m6a.24xlarge
      - m6a.32xlarge
      - m6a.48xlarge
    ConstraintDescription: must be a valid EC2 instance type.
  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance.
    Type: AWS::EC2::KeyPair::KeyName
    MinLength: 1
  AllocatePublicAddress:
    Description: Allocate an Elastic IP for each cluster member, in addition to the shared cluster Elastic IP.
    Type: String
    Default: true
    AllowedValues:
      - true
      - false
  VolumeSize:
    Type: Number
    Default: 100
    MinValue: 100
  VolumeEncryption:
    Description: KMS or CMK key Identifier - Use key ID, alias or ARN. Key alias should be prefixed with 'alias/' (e.g. for KMS default alias 'aws/ebs' - insert 'alias/aws/ebs').
    Type: String
    Default: alias/aws/ebs
  EnableInstanceConnect:
    Description: Enable SSH connection over AWS web console.
    Default: false
    Type: String
    AllowedValues:
      - true
      - false
  GatewayPredefinedRole:
    Description: A predefined IAM role to attach to the cluster profile. (optional)
    Type: String
    Default: ''
  TerminationProtection:
    Description: Prevents an instance from accidental termination.
    Type: String
    Default: false
    AllowedValues:
      - true
      - false
  GatewayVersion:
    Type: String
    Default: R81.20-BYOL
    AllowedValues:
      - R81.20-BYOL
      - R82-BYOL
  Shell:
    Description: Change the admin shell to enable advanced command line configuration.
    Type: String
    Default: /etc/cli.sh
    AllowedValues:
      - /etc/cli.sh
      - /bin/bash
      - /bin/csh
      - /bin/tcsh
  GatewayPasswordHash:
    Description: Admin user's password hash (use command "openssl passwd -6 PASSWORD".
      to get the PASSWORD's hash) (optional)
    Type: String
    Default: ''
    AllowedPattern: '^[\$\./a-zA-Z0-9]*$'
    NoEcho: true
  GatewaySICKey:
    Description: The Secure Internal Communication key creates trusted connections.
      between Check Point components. Choose a random string consisting of at least
      8 alphanumeric characters
    Type: String
    AllowedPattern: '^[a-zA-Z0-9]{8,}$'
    ConstraintDescription: At least 8 alpha numeric characters.
    NoEcho: true
  MemberAToken:
    Description: Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud. Paste here the token copied from the Connect Gateway screen in Smart-1 Cloud portal.
    AllowedPattern: '(^aHR0cHM6Ly9(.+)|(.*)\s[aHR0cHM6Ly9](.+)|^$)'
    Type: String
    NoEcho: true
  MemberBToken:
    Description: Follow the instructions in sk180501 to quickly connect this Cross AZ Cluster to Smart-1 Cloud. Paste here the token copied from the Connect Gateway screen in Smart-1 Cloud portal.
    AllowedPattern: '(^aHR0cHM6Ly9(.+)|(.*)\s[aHR0cHM6Ly9](.+)|^$)'
    Type: String
    NoEcho: true
  ResourcesTagName:
    Description: Name tag prefix of the resources. (optional)
    Type: String
    Default: ''
  GatewayHostname:
    Description: The host name will be appended with member-a/b accordingly (optional). The name must not contain reserved words. For details, refer to sk40179.
    Type: String
    Default: ''
    AllowedPattern: '^([A-Za-z]([-0-9A-Za-z]{0,61}[0-9A-Za-z]))?$'
    ConstraintDescription: A valid hostname label or an empty string.
  AllowUploadDownload:
    Description: Automatically download updates and share statistical data for product improvement purpose.
      Improve product experience by sending data to Check Point.
    Type: String
    Default: true
    AllowedValues:
      - true
      - false
  CloudWatch:
    Description: Report Check Point specific CloudWatch metrics.
    Type: String
    Default: false
    AllowedValues:
      - true
      - false
  GatewayBootstrapScript:
    Description: An optional script with semicolon (;) separated commands to run on the initial boot. (optional)
    Type: String
    Default: ''
    NoEcho: true
  NTPPrimary:
    Description: (optional)
    Type: String
    Default: 169.254.169.123
    AllowedPattern: '^[\.a-zA-Z0-9\-]*$'
  NTPSecondary:
    Description: (optional)
    Type: String
    Default: 0.pool.ntp.org
    AllowedPattern: '^[\.a-zA-Z0-9\-]*$'
Conditions:
  AllocateAddress: !Equals [!Ref AllocatePublicAddress, true]
Resources:
  VPCStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://cgi-cfts.s3.cn-northwest-1.amazonaws.com.cn/utils/vpc.yaml
      Parameters:
        AvailabilityZones: !Join [',', !Ref AvailabilityZones]
        NumberOfAZs: 2
        VPCCIDR: !Ref VPCCIDR
        PublicSubnet1CIDR: !Ref PublicSubnet1CIDR
        PublicSubnet2CIDR: !Ref PublicSubnet2CIDR
        PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR
        PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR
  InternalRouteTable:
    Type: AWS::EC2::RouteTable
    DependsOn: VPCStack
    Properties:
      VpcId: !GetAtt VPCStack.Outputs.VPCID
      Tags:
        - Key: Name
          Value: Private Subnets Route Table
  ClusterStack:
    Type: AWS::CloudFormation::Stack
    DependsOn: VPCStack
    Properties:
      TemplateURL: https://cgi-cfts.s3.cn-northwest-1.amazonaws.com.cn/cluster/cross-az-cluster.yaml
      Parameters:
        VPC: !GetAtt VPCStack.Outputs.VPCID
        PublicSubnetA: !GetAtt VPCStack.Outputs.PublicSubnet1ID
        PublicSubnetB: !GetAtt VPCStack.Outputs.PublicSubnet2ID
        PrivateSubnetA: !GetAtt VPCStack.Outputs.PrivateSubnet1ID
        PrivateSubnetB: !GetAtt VPCStack.Outputs.PrivateSubnet2ID
        InternalRouteTable: !Ref InternalRouteTable
        GatewayName: !Ref GatewayName
        GatewayInstanceType: !Ref GatewayInstanceType
        KeyName: !Ref KeyName
        AllocatePublicAddress: !Ref AllocatePublicAddress
        VolumeSize: !Ref VolumeSize
        VolumeEncryption: !Ref VolumeEncryption
        EnableInstanceConnect: !Ref EnableInstanceConnect
        GatewayPredefinedRole: !Ref GatewayPredefinedRole
        TerminationProtection: !Ref TerminationProtection
        GatewayVersion: !Ref GatewayVersion
        Shell: !Ref Shell
        GatewayPasswordHash: !Ref GatewayPasswordHash
        GatewaySICKey: !Ref GatewaySICKey
        MemberAToken: !Ref MemberAToken
        MemberBToken: !Ref MemberBToken
        ResourcesTagName: !Ref ResourcesTagName
        GatewayHostname: !Ref GatewayHostname
        AllowUploadDownload: !Ref AllowUploadDownload
        CloudWatch: !Ref CloudWatch
        GatewayBootstrapScript: !Ref GatewayBootstrapScript
        NTPPrimary: !Ref NTPPrimary
        NTPSecondary: !Ref NTPSecondary
Outputs:
  ClusterPublicAddress:
    Description: The public address of the cluster.
    Value: !GetAtt ClusterStack.Outputs.ClusterPublicAddress
  MemberAPublicAddress:
    Condition: AllocateAddress
    Description: The public address of member A.
    Value: !GetAtt ClusterStack.Outputs.MemberAPublicAddress
  MemberASSH:
    Condition: AllocateAddress
    Description: SSH command to member A.
    Value: !GetAtt ClusterStack.Outputs.MemberASSH
  MemberAURL:
    Condition: AllocateAddress
    Description: URL to the member A portal.
    Value: !GetAtt ClusterStack.Outputs.MemberAURL
  MemberBPublicAddress:
    Condition: AllocateAddress
    Description: The public address of member B.
    Value: !GetAtt ClusterStack.Outputs.MemberBPublicAddress
  MemberBSSH:
    Condition: AllocateAddress
    Description: SSH command to member B.
    Value: !GetAtt ClusterStack.Outputs.MemberBSSH
  MemberBURL:
    Condition: AllocateAddress
    Description: URL to the member B portal.
    Value: !GetAtt ClusterStack.Outputs.MemberBURL
Rules:
  MemberATokenNotProvided:
    RuleCondition: !Equals [!Ref MemberAToken, '']
    Assertions:
      - AssertDescription: "Smart-1 Cloud Token for member A can not be empty"
        Assert: !Equals [!Ref MemberBToken, '']
  MemberBTokenNotProvided:
    RuleCondition: !Equals [ !Ref MemberBToken, '' ]
    Assertions:
      - AssertDescription: "Smart-1 Cloud Token for member B can not be empty"
        Assert: !Equals [ !Ref MemberAToken, '' ]
  MembersTokenValueEquals:
    RuleCondition: !EachMemberEquals [ [ !Ref MemberBToken ], !Ref MemberAToken ]
    Assertions:
      - AssertDescription: "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
        Assert: !Equals [ !Ref MemberAToken, '' ]
      - AssertDescription: "The same Smart-1 Cloud token is used for the two Cluster members. Each Cluster member must have a unique token"
        Assert: !Equals [ !Ref MemberBToken, '' ]