AWSTemplateFormatVersion: "2010-09-09"
Description: FortiGate for ElasticCluster
Parameters:
  KeyName:
    Description: SSH Key
    Type: AWS::EC2::KeyPair::KeyName

  InstanceType:
    Type: String
    Default: t2.micro

  FGUserName:
    Type: String
    Description: Adminuser on FG

  VPCName:
    Type: String
    Description: Name of VPC to run this in

  Elanet:
    Type: String
    Description: Local net allowed to connect

  VPCNet:
    Type: String
    Description: Whole network of VPC

  VPCSubnetFront:
    Type: String
    Description: Subnet for interfaces facing the internet

  VPCSubnetBack:
    Type: String
    Description: Subnet for the 'internal' side of the network

  S3Bucketname:
    Type: String
    Description: Bucket for license

  S3Region:
    Type: String
    Description: Region for bucket

  LicenseFileName:
    Type: String
    Description: Licensefilename in Bucket

Resources:
  FortiVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock:
        Ref: VPCNet
      Tags:
        - Key: Name
          Value:
            Ref: VPCName


  FortiVPCFrontNet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock:
        Ref: VPCSubnetFront
      MapPublicIpOnLaunch: true
      VpcId:
        Ref: FortiVPC


  FortiVPCBackNet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock:
        Ref: VPCSubnetBack
      MapPublicIpOnLaunch: false
      AvailabilityZone: !GetAtt FortiVPCFrontNet.AvailabilityZone
      VpcId:
        Ref: FortiVPC

  FortiSecGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: Group for FG
      GroupName: fg
      SecurityGroupEgress: 
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      SecurityGroupIngress: 
        - IpProtocol: tcp
          FromPort: 0
          ToPort: 65535
          CidrIp: 0.0.0.0/0
        - IpProtocol: udp
          FromPort: 0
          ToPort: 65535
          CidrIp: 0.0.0.0/0
      VpcId: 
        Ref: FortiVPC

  InstanceProfile:
    Properties:
      Path: /
      Roles:
        - Ref: InstanceRole
    Type: AWS::IAM::InstanceProfile
  InstanceRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
        Version: 2012-10-17
      Path: /
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - ec2:Describe*
                  - ec2:AssociateAddress
                  - ec2:AssignPrivateIpAddresses
                  - ec2:UnassignPrivateIpAddresses
                  - ec2:ReplaceRoute
                  - s3:GetObject
                Effect: Allow
                Resource: '*'
            Version: 2012-10-17
          PolicyName: ApplicationPolicy
    Type: AWS::IAM::Role

        
  FortiInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      IamInstanceProfile:
        Ref: InstanceProfile      
      ImageId: "ami-06f4dce9c3ae2c504" # for eu-west-3 paris
      InstanceType: t2.small
      AvailabilityZone: !GetAtt FortiVPCFrontNet.AvailabilityZone
      KeyName:
        Ref: KeyName
      NetworkInterfaces:
        - DeviceIndex: 0
          NetworkInterfaceId:
            Ref: fgteni1
        - DeviceIndex: 1
          NetworkInterfaceId:
            Ref: fgteni2
      UserData:
        Fn::Base64:
          Fn::Join:
            - ''
            -
              - "{\n"
              - '"bucket"'
              - ' : "'
              - Ref: S3Bucketname
              - '"'
              - ",\n"
              - '"region"'
              - ' : '
              - '"'
              - Ref: S3Region
              - '"'
              - ",\n"
              - '"license"'
              - ' : '
              - '"'
              - /
              - Ref: LicenseFileName
              - '"'
              - ",\n"
              - '"config"'
              - ' : '
              - '"'
              - /fg.txt
              - '"'
              - "\n"
              - '}'
          
  InternetGateway:
    Type: AWS::EC2::InternetGateway

  AttachGateway:
    Properties:
      InternetGatewayId:
        Ref: InternetGateway
      VpcId:
        Ref: FortiVPC
    Type: AWS::EC2::VPCGatewayAttachment

  RouteTablePub:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: FortiVPC

  DefRoutePub:
    DependsOn: AttachGateway
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId:
        Ref: InternetGateway
      RouteTableId:
        Ref: RouteTablePub
    Type: AWS::EC2::Route
    
      
  RouteTablePriv:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: FortiVPC

  DefRoutePriv:
    DependsOn: AttachGateway
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      NetworkInterfaceId:
        Ref: fgteni2
      RouteTableId:
        Ref: RouteTablePriv
    Type: AWS::EC2::Route

  SubnetRouteTableAssociationPub:
    Properties:
      RouteTableId:
        Ref: RouteTablePub
      SubnetId:
        Ref: FortiVPCFrontNet
    Type: AWS::EC2::SubnetRouteTableAssociation
    
  SubnetRouteTableAssociationPriv:
    Properties:
      RouteTableId:
        Ref: RouteTablePriv
      SubnetId:
        Ref: FortiVPCBackNet
    Type: AWS::EC2::SubnetRouteTableAssociation


  fgteni1:
    Type: AWS::EC2::NetworkInterface
    Properties:
      Description: port1
      GroupSet:
        - Ref: FortiSecGroup
      SourceDestCheck: false
      SubnetId:
        Ref: FortiVPCFrontNet

  fgteni2:
    Type: AWS::EC2::NetworkInterface     
    Properties:
      Description: port2
      GroupSet:
        - Ref: FortiSecGroup
      SourceDestCheck: false
      SubnetId:
        Ref: FortiVPCBackNet

  FgtEIP:
    DependsOn: FortiInstance
    Properties:
      Domain: FortiVPC
    Type: AWS::EC2::EIP
    
  Fgt1EIPASSOCIATION:
    Type: AWS::EC2::EIPAssociation    
    DependsOn: FgtEIP
    Properties:
      AllocationId:
        Fn::GetAtt:
          - FgtEIP
          - AllocationId
      NetworkInterfaceId:
        Ref: fgteni1

  ServerSecGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: Group for DC Server
      GroupName: server
      SecurityGroupEgress: 
        - IpProtocol: -1
          FromPort: 0
          CidrIp: 0.0.0.0/0
      SecurityGroupIngress: 
        - IpProtocol: tcp
          FromPort: 0
          ToPort: 65535
          CidrIp:
            Ref: Elanet
        - IpProtocol: tcp
          FromPort: 0
          ToPort: 65535
          CidrIp:
            Ref: VPCNet
        - IpProtocol: udp
          FromPort: 0
          ToPort: 65535
          CidrIp:
            Ref: Elanet
        - IpProtocol: udp
          FromPort: 0
          ToPort: 65535
          CidrIp:
            Ref: VPCNet            
        - IpProtocol: icmp
          FromPort: 8
          ToPort: -1
          CidrIp: 0.0.0.0/0
      VpcId: 
        Ref: FortiVPC


        
  ServerInstance: 
    Type: "AWS::EC2::Instance"
    Properties: 
      ImageId: "ami-0e1ab783dc9489f34" # Centos7 for paris
      InstanceType: t3.2xlarge
      AvailabilityZone: !GetAtt FortiVPCFrontNet.AvailabilityZone
      KeyName:
        Ref: KeyName
      SubnetId:
        Ref: FortiVPCBackNet
      SecurityGroupIds:
        - !Ref ServerSecGroup

  Server2Instance:
    Type: "AWS::EC2::Instance"
    Properties: 
      ImageId: "ami-0e1ab783dc9489f34" # Centos7 for paris
      InstanceType: t2.small
      AvailabilityZone: !GetAtt FortiVPCFrontNet.AvailabilityZone
      KeyName:
        Ref: KeyName
      SubnetId:
        Ref: FortiVPCBackNet
      SecurityGroupIds:
        - !Ref ServerSecGroup
        
Outputs:
  FortiGatepubIp:
    Description: IP To reach the fgt
    Value:
      Ref: FgtEIP
  FortiGateId:
    Description: ID of Instance
    Value:
      Ref: FortiInstance
  FGIntAddress:
    Description: Internal IP of the Firewall
    Value: !GetAtt fgteni2.PrimaryPrivateIpAddress
  Server1Address:
    Description: Internal IP of first server 
    Value: !GetAtt ServerInstance.PrivateIp
  Server2Address:
    Description: Internal IP of second server
    Value: !GetAtt Server2Instance.PrivateIp
