AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  InstanceCount:
    Type: Number
    Default: 1
    Description: "Number of EC2 instances for the workers"
    MinValue: 1
    MaxValue: 128
  InstanceType:
    Type: String
    Default: "m5.large"
    Description: "EC2 instance type for the master and worker instances"
    ConstraintDescription: "Must be a valid EC2 instance type"

Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: "10.202.0.0/16"
      EnableDnsSupport: true
      EnableDnsHostnames: true

  MySubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: "10.202.0.0/24"
      VpcId: !Ref MyVPC
      AvailabilityZone:
        Fn::Select:
          - "0"
          - Fn::GetAZs: ""
      MapPublicIpOnLaunch: true

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties: {}

  AttachInternetGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref InternetGateway

  MyRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC

  MyRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref MyRouteTable
      DestinationCidrBlock: "0.0.0.0/0"
      GatewayId: !Ref InternetGateway

  MySubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref MySubnet
      RouteTableId: !Ref MyRouteTable


  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "Allow SSH and NFS access"
      VpcId: !Ref MyVPC
      SecurityGroupIngress:
        - IpProtocol: "-1"
          FromPort: "-1"
          ToPort: "-1"
          CidrIp: "10.202.0.0/16"
        - IpProtocol: "tcp"
          FromPort: "8035"
          ToPort: "8035"
          CidrIp: "0.0.0.0/0"
        - IpProtocol: "tcp"
          FromPort: "7077"
          ToPort: "7077"
          CidrIp: "0.0.0.0/0"
        - IpProtocol: "tcp"
          FromPort: "8081"
          ToPort: "8081"
          CidrIp: "0.0.0.0/0"

  MyEFS:
    Type: AWS::EFS::FileSystem
    Properties:
      PerformanceMode: "generalPurpose"
      Encrypted: true

  MyMountTarget:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref MyEFS
      SubnetId: !Ref MySubnet
      SecurityGroups:
        - Fn::GetAtt: [EC2SecurityGroup, GroupId]

  EC2KeyPair:
    Type: AWS::EC2::KeyPair
    Properties:
      KeyName: "my-ec2-key-pair"

  EC2InstanceMaster:
    Type: AWS::EC2::Instance
    DependsOn: MyMountTarget
    Properties:
      InstanceType: !Ref InstanceType
      ImageId: "ami-0d5569dae64ab95a9"
      KeyName: !Ref EC2KeyPair
      Tags:
        - Key: "Name"
          Value: "chukonuMaster"
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: "0"
          GroupSet:
            - !Ref EC2SecurityGroup
          SubnetId: !Ref MySubnet
      UserData:
        Fn::Base64:
          Fn::Sub: |
            #!/bin/bash
            # 挂载 efs，用户数据可以存储在efs中
            sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${MyEFS}.efs.${AWS::Region}.amazonaws.com.cn:/ /mnt
            # 改变 /mnt 权限
            sudo chmod -R 777 /mnt
            # 创建缓存目录，诸葛弩运行时的必要条件
            sudo mkdir -p /mnt/chukonu_cache
            # 创建数据目录，用户要处理的数据放在该目录下
            sudo mkdir -p /mnt/data
            # 改变 /mnt 权限
            sudo chmod -R 777 /mnt
            # 删除已经存在 /opt/chukonu_cache
            sudo rm -rf /opt/chukonu_cache
            # 创建软连接
            sudo ln -s /mnt/chukonu_cache /opt/chukonu_cache
            # 启动诸葛弩 master，用户集群的调度
            sudo /opt/spark-3.4.1/sbin/start-master.sh --webui-port 8035 && tail -f /dev/null 

  WorkerLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    DependsOn: EC2InstanceMaster
    Properties:
      LaunchTemplateName: "WorkerLaunchTemplate"
      VersionDescription: "1"
      LaunchTemplateData:
        InstanceType: !Ref InstanceType
        ImageId: "ami-0d5569dae64ab95a9"
        KeyName: !Ref EC2KeyPair
        SecurityGroupIds:
          - !Ref EC2SecurityGroup
        UserData:
          Fn::Base64:
            Fn::Sub: |
              #!/bin/bash
              # 挂载 efs，用户数据可以存储在efs中
              sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${MyEFS}.efs.${AWS::Region}.amazonaws.com.cn:/ /mnt
              # 改变 /mnt 权限
              sudo chmod -R 777 /mnt
              # 创建缓存目录，诸葛弩运行时的必要条件
              sudo mkdir -p /mnt/chukonu_cache
              # 创建数据目录，用户要处理的数据放在该目录下
              sudo mkdir -p /mnt/data
              # 改变 /mnt 权限
              sudo chmod -R 777 /mnt
              # 删除已经存在 /opt/chukonu_cache
              sudo rm -rf /opt/chukonu_cache
              # 创建软连接
              sudo ln -s /mnt/chukonu_cache /opt/chukonu_cache
               # 启动诸葛弩 worker，任务的运行在该节点上
              sudo /opt/spark-3.4.1/sbin/start-worker.sh spark://${EC2InstanceMaster.PrivateIp}:7077 && tail -f /dev/null
  WorkerAutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    DependsOn: WorkerLaunchTemplate
    Properties:
      LaunchTemplate:
        LaunchTemplateId: !Ref WorkerLaunchTemplate
        Version: "1"
      MinSize: 1
      MaxSize: 128
      DesiredCapacity: !Ref InstanceCount
      VPCZoneIdentifier:
        - !Ref MySubnet

Outputs:
  EFSId:
    Description: "EFS FileSystem ID"
    Value: !Ref MyEFS

  VPCId:
    Description: "VPC ID"
    Value: !Ref MyVPC

  Instance1Id:
    Description: "EC2 Instance 1 ID"
    Value: !Ref EC2InstanceMaster

  AutoScalingGroupName:
    Description: "Auto Scaling Group Name for Worker Instances"
    Value: !Ref WorkerAutoScalingGroup
