AWSTemplateFormatVersion: "2010-09-09"
Description: "Deploys the EC2 Autoscaling, LaunchConfig and Instance for Xray"
Parameters:
  PrivateSubnet1Id:
    Type: 'AWS::EC2::Subnet::Id'
  PrivateSubnet2Id:
    Type: 'AWS::EC2::Subnet::Id'
  KeyPairName:
    Type: AWS::EC2::KeyPair::KeyName
  MinScalingNodes:
    Type: Number
  MaxScalingNodes:
    Type: Number
  DeploymentTag:
    Type: String
  QsS3BucketName:
    Type: String
  QsS3KeyPrefix:
    Type: String
  QsS3Uri:
    Type: String
  DatabaseDriver:
    Type: String
  DatabaseType:
    Type: String
  DatabaseUser:
    Type: String
  DatabasePassword:
    Type: String
    NoEcho: 'true'
  MasterKey:
    Type: String
    NoEcho: 'true'
  SecurityGroups:
    Type: String
  VolumeSize:
    Type: Number
  XrayHostProfile:
    Type: String
  XrayHostRole:
    Type: String
  XrayInstanceType:
    Type: String
  JfrogInternalUrl:
    Type: String
  AnsibleVaultPass:
    Description: Ansiblevault Password to secure the artifactory.yml
    Type: String
    NoEcho: 'true'
  XrayDatabaseUser:
    Type: String
  XrayDatabasePassword:
    Type: String
    NoEcho: 'true'
  XrayMasterDatabaseUrl:
    Type: String
  XrayDatabaseUrl:
    Type: String
  XrayFirstNode:
    Description: Runs database scripts if this is the first node
    Type: String
  XrayVersion:
    Type: String
  XrayAmiId:
    Type: String
# To populate additional mappings use the following with the desired --region
# aws --region us-west-2 ec2 describe-images --owners amazon --filters 'Name=name,Values=amzn-ami-hvm-2018.03.0.20181129-x86_64-gp2' 'Name=state,Values=available' --output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
Mappings:
  AWSAMIRegionMap:
    us-east-1:
      "3112": ami-04954176e0e714377
    us-east-2:
      "3112": ami-0dde651cd599d64e8
    us-west-1:
      "3112": ami-0926fb027c339d991
    us-west-2:
      "3112": ami-0e48dd6310c205c33
    ca-central-1:
      "3112": ami-056bafb407aa8e445
    eu-central-1:
      "3112": ami-05ab6de966f830b8a
    eu-west-1:
      "3112": ami-055507b35a350806d
    eu-west-2:
      "3112": ami-007c8adf17c3bee79
    eu-west-3:
      "3112": ami-033e74f7f2e7b43ae
    ap-southeast-1:
      "3112": ami-0114ff3241c5a86a8
    ap-southeast-2:
      "3112": ami-0c753f85c64c4169d
    ap-south-1:
      "3112": ami-09f40817a8786b93c
    ap-northeast-1:
      "3112": ami-00f6ec6314c6ddd27
    ap-northeast-2:
      "3112": ami-05a10d14c3289f2b3
    sa-east-1:
      "3112": ami-0c2acb2f23c3e6743
    us-gov-west-1:
      "3112": ami-0f0208b759ab47734

Resources:
  XrayScalingGroup:
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      LaunchConfigurationName: !Ref XrayLaunchConfiguration
      VPCZoneIdentifier:
        - !Ref PrivateSubnet1Id
        - !Ref PrivateSubnet2Id
      MinSize: !Ref MinScalingNodes
      MaxSize: !Ref MaxScalingNodes
      Cooldown: '300'
      DesiredCapacity: !Ref MinScalingNodes
      HealthCheckType: EC2
      HealthCheckGracePeriod: 900
      Tags:
        - Key: Name
          Value: !Ref DeploymentTag
          PropagateAtLaunch: true
    CreationPolicy:
      ResourceSignal:
        Count: 1
        Timeout: PT60M
  XrayLaunchConfiguration:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Metadata:
      'AWS::CloudFormation::Authentication':
        S3AccessCreds:
          type: S3
          roleName:
            - !Ref XrayHostRole
          buckets:
            - !Ref QsS3BucketName
      'AWS::CloudFormation::Init':
        configSets:
          xray_install:
            - "config-xray"
        config-xray:
          files:
            /root/.xray_ami/xray.yml:
              content: !Sub
                - |
                  # Base install for Xray
                  - import_playbook: site-xray.yml
                    vars:
                      jfrog_url: ${JfrogInternalUrl}
                      master_key: ${MasterKey}
                      join_key: ${MasterKey}
                      db_type: ${DatabaseType}
                      db_driver: ${DatabaseDriver}
                      db_url: postgres://${XrayDatabaseUrl}
                      db_user: ${XrayDatabaseUser}
                      db_password: ${XrayDatabasePassword}
                      xray_version: ${XrayVersion}
                - {
                  product: Xray
                }
              mode: "0400"
            /root/.vault_pass.txt:
              content: !Sub |
                ${AnsibleVaultPass}
              mode: "0400"
    Properties:
      AssociatePublicIpAddress: false
      KeyName: !Ref KeyPairName
      IamInstanceProfile: !Ref XrayHostProfile
      ImageId: !FindInMap
        - AWSAMIRegionMap
        - !Ref 'AWS::Region'
        - !Ref XrayAmiId
      SecurityGroups:
        - !Ref SecurityGroups
      InstanceType: !Ref XrayInstanceType
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: !Ref VolumeSize
            VolumeType: gp2
            DeleteOnTermination: true
      UserData:
        'Fn::Base64':
          !Sub |
            #!/bin/bash -x
            exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1

            #CFN Functions

            function cfn_fail

            {

            cfn-signal -e 1 --stack ${AWS::StackName} --region ${AWS::Region} --resource XrayScalingGroup

            exit 1

            }

            function cfn_success

            {

            cfn-signal -e 0 --stack ${AWS::StackName} --region ${AWS::Region} --resource XrayScalingGroup

            exit 0

            }

            S3URI=${QsS3Uri}

            # yum install -y git

            echo $PATH

            PATH=/opt/aws/bin:$PATH

            echo $PATH
            echo \'[Cloning: Load QuickStart Common Utils]\'

            # git clone https://github.com/aws-quickstart/quickstart-linux-utilities.git

            source /quickstart-linux-utilities/quickstart-cfn-tools.source

            echo \'[Loaded: Load QuickStart Common Utils]\'

            echo \'[Update Operating System]\'

            qs_update-os || qs_err

            qs_bootstrap_pip || qs_err

            qs_aws-cfn-bootstrap || qs_err

            source ~/venv/bin/activate &> /var/log/userdata.activate_venv.log || qs_err " activate venv failed "

            # mkdir ~/.xray_ansible

            # aws s3 --region ${AWS::Region} sync s3://${QsS3BucketName}/${QsS3KeyPrefix}cloudInstallerScripts/ ~/.xray_ansible/

            cfn-init -v --stack ${AWS::StackName} --resource XrayLaunchConfiguration --configsets xray_install --region ${AWS::Region} || cfn_fail

            # CentOS cloned virtual machines do not create a new machine id
            # https://www.thegeekdiary.com/centos-rhel-7-how-to-change-the-machine-id/
            rm -f /etc/machine-id
            systemd-machine-id-setup

            if "true" == "${XrayFirstNode}"
            then
                psql postgresql://${DatabaseUser}:${DatabasePassword}@${XrayMasterDatabaseUrl} -c "CREATE USER ${XrayDatabaseUser} WITH PASSWORD '${XrayDatabasePassword}'" &>> /var/log/userdata.xray_database.log;
                psql postgresql://${DatabaseUser}:${DatabasePassword}@${XrayMasterDatabaseUrl} -c "grant ${XrayDatabaseUser} to ${DatabaseUser}" &>> /var/log/userdata.xray_database.log;
                psql postgresql://${DatabaseUser}:${DatabasePassword}@${XrayMasterDatabaseUrl} -c "CREATE DATABASE xraydb WITH OWNER=${XrayDatabaseUser} ENCODING='UTF8'" &>> /var/log/userdata.xray_database.log;
                psql postgresql://${DatabaseUser}:${DatabasePassword}@${XrayMasterDatabaseUrl} -c "GRANT ALL PRIVILEGES ON DATABASE xraydb TO ${XrayDatabaseUser}" &>> /var/log/userdata.xray_database.log;
            fi

            ansible-playbook /root/.xray_ami/xray.yml || qs_err " ansible execution failed "

            $(qs_status) &> /var/log/qs_status.log
            cfn_success &> /var/log/cfn_success.log
            [ $(qs_status) == 0 ] && cfn_success || cfn_fail