######################################################################################
# Copyright (C) 2016--2022 Lightbits Labs Ltd. - All Rights Reserved
# Unauthorized copying of this file, via any medium is strictly prohibited
# Proprietary and confidential
######################################################################################
# CloudFormation root template file for marketplace
# CF files for marketplace requires adapatations before submit to Marketplace
# Use make-root-for-marketplace.sh utility to generate correct cf before submission
#
######################################################################################
AWSTemplateFormatVersion: '2010-09-09'

Conditions:

  isRegionUsEast1:               !Equals [ Ref: 'AWS::Region', 'us-east-1']

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Network Configuration"
        Parameters:
         - AvailabilityZone
         - ExistingVpcId
         - VpcCIDR
         - PrivateSubnetId
         - RouteTable
      - Label:
          default: "Storage Configuration"
        Parameters:
         - InstanceCount
         - InstanceType
         - KeyName
         - S3ConfBucketName
      - Label:
          default: "Backup Configuration"
        Parameters:
         - S3BackupBucketName
         - ExporterInstanceType

Mappings:

  # Here we specify for each region the Marketplace published Lightbits AMI
  Region2AMI:
    us-east-1:
      LBAMI: ami-0912fd1fc9162dfe2
    ap-south-1:
      LBAMI: ami-01bcbaeaebf1d8ac9
    eu-central-1:
      LBAMI: ami-00d944a54ee47a8eb
    us-east-2:
      LBAMI: ami-02bc3b91150b6c0da
    us-west-1:
      LBAMI: ami-0addf3eab6aa9e880
    us-west-2:
      LBAMI: ami-0c4748b6e76c6eb6e

  ####################################################################################
  # Note for S3NestedScriptsLambdasBucketName
  # -----------------------------------------
  # we specify for each region the S3 bucket where lambdas are located
  # us-east-1 region - we hold main Marketplace bucket
  #       in this bucket we store cf files, lambda files and all other Marketplace assets (this is the bucket submitted to MP)
  #       the us-east-1 bucket name is by default 'lightbits-docs' (based on BucketNameForCFScripts) 
  # on other regions, we use secondary buckets, each bucket name is based on BucketNameForCFScripts + region name (i.e 'lightbits-docs-us-east-2')
  #       in the other regions buckets, we only put duplications of lambda files (no need to put cf files)
  # Q: why we need to duplicate lambdas in different buckets placed on different regions?
  # A: because AWS cannot launch lambda from a bucket which is not on the same deployment region
  ####################################################################################
  MappingToRegionBucket:
    Name:
      BucketNameForCFScripts: "lightbits-docs" # bucket was replaced by markeplace prepare script

  MappingToPrefix:
    Prefix:
      PrefixForCFScripts: "3_5_1/" # prefix was replaced by markeplace prepare script

Resources:

  lbRoot: # lightbits nested cloudfromation stack for root stack
    Type: AWS::CloudFormation::Stack
    Properties:        
      TemplateURL: "https://lightbits-docs.s3.amazonaws.com/3_5_1/cf-lb-root.yml"
      Parameters:
          AvailabilityZone: !Join [",", !Ref AvailabilityZone]
          S3NestedScriptsBucketName: !FindInMap [MappingToRegionBucket, Name, BucketNameForCFScripts]
          S3NestedScriptsLambdasBucketName: # refer note above about S3NestedScriptsLambdasBucketName
              'Fn::If':
               - isRegionUsEast1
               - !FindInMap [MappingToRegionBucket, Name, BucketNameForCFScripts]
               - !Join ["", [ !FindInMap [MappingToRegionBucket, Name, BucketNameForCFScripts], "-", !Ref 'AWS::Region' ] ]
          S3NestedScriptsBucketPrefix: !FindInMap [MappingToPrefix, Prefix, PrefixForCFScripts]
          S3ConfBucketName: !Ref S3ConfBucketName # 'lightos-deployments'
          InstanceCount: !Ref InstanceCount
          KeyName: !Ref KeyName
          ImageId: !FindInMap [Region2AMI, !Ref "AWS::Region", LBAMI] # ami is autoselected per region
          ExporterImageId: !FindInMap [Region2AMI, !Ref "AWS::Region", LBAMI] # Backup exporter ami is autoselected per region 
          InstanceType: !Ref InstanceType
          VpcCIDR: !Ref VpcCIDR
          ExistingVpcId: !Ref ExistingVpcId
          PrivateSubnetId: !Join [",", !Ref PrivateSubnetId]
          RouteTable: !Ref RouteTable
          S3BackupBucketName: !Ref S3BackupBucketName
          ExporterInstanceType: !Ref ExporterInstanceType
   
Parameters:

  ####################################################################################################
  # refer ../README.md for details on parameters and usage
  ####################################################################################################
  
   AvailabilityZone:
     Description: "For a new VPC, select Availability Zone. If more than the needed zones are selected (1 or 3), the first zone(s)\
       \ will be used.\n"
     Type: List<AWS::EC2::AvailabilityZone::Name>
     AllowedPattern: .+
   ExistingVpcId:
     Description: "To deploy into an existing vpc enter VPC ID (i.e 'vpc-12ab345', to see list of VPCs: https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#vpcs).\
       \ To create new vpc leave the default of 'create-new'\n"
     Type: String
     Default: create-new
   ExporterInstanceType:
     Description: Instance type for backup exporter nodes.
     Type: String
     Default: c5n.xlarge
     AllowedValues:
       - c5n.xlarge
       - c5n.2xlarge
   InstanceCount:
     Description: Initial number of EC2 instances (lightbits nodes) to start storage cluster (minimum 3).
     Type: Number
     Default: 3
     MinValue: 3
     MaxValue: 16
     ConstraintDescription: Must be a number between 3 and 16.
   InstanceType:
     Description: Instance type for storage nodes (i4i available on US East and US West regions).
     Type: String
     Default: i3en.6xlarge
     AllowedValues:
       - i3en.6xlarge
       - i3en.12xlarge
       - i3en.24xlarge
       - i3en.metal
       - i4i.4xlarge
       - i4i.8xlarge
       - i4i.16xlarge
       - i4i.32xlarge
       - i4i.metal
   KeyName:
     Description: Name of an existing EC2 key pair for SSH access to the EC2 instance.
     Type: AWS::EC2::KeyPair::KeyName
     Default: ''
   PrivateSubnetId:
     Description: "To deploy using existing VPC, enter desired subnet id (of the form \"subnet-0cd6c0c5df0e478d6\"). In case\
       \ of a Multi-AZ deployment please provide exactly 3 subnet ids. In different availability zones. For new VPC, this parameter\
       \ is ignored\n"
     Type: List<String>
     Default: ''
   RouteTable:
     Description: "Route table to associate subnets with S3 gateway. To deploy using existing VPC, enter desired route-table-id\
       \ (of the form \"rtb-04aff27f814e51154\"). Leave empty for automatically created route-table For new VPC, this parameter\
       \ is ignored\n"
     Type: String
     Default: ''
   S3BackupBucketName:
     Description: "Write accesible S3 Bucket for storing user volume backups. If 'create-new' is chosen, the bucket name will\
       \ be auto-generated. If the field remains empty, the backup process will be disabled. If this is overwritten with a different\
       \ value this name has to be unique,  i.e. a bucket with identical name should not exist.\n"
     Type: String
     Default: create-new
     ConstraintDescription: "The bucket name has to adhere to bucket naming rules. For more information: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html\n"
   S3ConfBucketName:
     Description: "S3 Bucket name (not ARN, only bucket name) to be used for storage cluster configuration. Each new deployment\
       \ stack created will generate a folder in this bucket (so the same bucket can be used for multiple clusters deployments).\
       \ If 'create-new' is chosen, the bucket name will be auto-generated. If you provide a bucket name the bucket with that\
       \ name is used. Please ensure the bucket exists, and it is read/write accessible by your account.\n"
     Type: String
     Default: create-new
     ConstraintDescription: "The bucket name has to adhere to bucket naming rules. For more information: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html\n"
   VpcCIDR:
     Description: "For an exiting VPC, put here a valid CIDR for the cluster network communication For a new VPC, put here a\
       \ CIDR range that will be set for the new VPC, or continue with the suggested CIDR.\n"
     Type: String
     MinLength: '9'
     MaxLength: '18'
     AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
     ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x.
     Default: 10.240.224.0/20
