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: ap-northeast-1: "330": ami-09dfb20a591375d09 # TODO: Get correct ami - provided by market place tem "361": ami-09dfb20a591375d09 # TODO: Get correct ami - provided by market place tem ap-northeast-2: "330": ami-0eb86b82de93a34fb # TODO: Get correct ami - provided by market place tem "361": ami-0eb86b82de93a34fb # TODO: Get correct ami - provided by market place tem ap-south-1: "330": ami-01b828aa6cc99a322 # TODO: Get correct ami - provided by market place tem "361": ami-01b828aa6cc99a322 # TODO: Get correct ami - provided by market place tem ap-southeast-1: "330": ami-04a94cc4dc0d08c98 # TODO: Get correct ami - provided by market place tem "361": ami-04a94cc4dc0d08c98 # TODO: Get correct ami - provided by market place tem ap-southeast-2: "330": ami-030871aa8d1f0689e # TODO: Get correct ami - provided by market place tem "361": ami-030871aa8d1f0689e # TODO: Get correct ami - provided by market place tem ca-central-1: "330": ami-0148cebea7bea4aaf # TODO: Get correct ami - provided by market place tem "361": ami-0148cebea7bea4aaf # TODO: Get correct ami - provided by market place tem eu-central-1: "330": ami-07961f7c210143a42 # TODO: Get correct ami - provided by market place tem "361": ami-07961f7c210143a42 # TODO: Get correct ami - provided by market place tem eu-west-1: "330": ami-0171b8d46941b4ca1 # TODO: Get correct ami - provided by market place tem "361": ami-0171b8d46941b4ca1 # TODO: Get correct ami - provided by market place tem sa-east-1: "330": ami-0596f196b273bb8a6 # TODO: Get correct ami - provided by market place tem "361": ami-0596f196b273bb8a6 # TODO: Get correct ami - provided by market place tem us-east-1: "330": ami-0d4d4252cdc2b6f11 # TODO: Get correct ami - provided by market place tem "361": ami-086fcbf4aa2bd203f # TODO: Get correct ami - provided by market place tem "386": ami-0becff949aa530956 # partnership account + seller account "3103": ami-0e19b1335bc3654c3 # seller account (shared with partnership account) "3112": ami-0819678d7216af530 # seller account (shared with partnership account) us-east-2: "330": ami-00a5fcde44618d39b # TODO: Get correct ami - using ami generated by myself - provided by market place tem "361": ami-005b2ceceac6999ff # TODO: Get correct ami - using ami generated by myself - provided by market place tem "3112": ami-0bd793595d742f794 # seller account (shared with partnership account) us-west-1: "330": ami-068cd684b4d3a3a86 # TODO: Get correct ami - provided by market place tem "361": ami-068cd684b4d3a3a86 # TODO: Get correct ami - provided by market place tem "3112": ami-012cc5d182bd3bd2b # seller account (shared with partnership account) us-west-2: "330": ami-03d60da4c8a146a55 # TODO: Get correct ami - provided by market place tem "361": ami-03d60da4c8a146a55 # TODO: Get correct ami - provided by market place tem "386": ami-07af1682f09ef4a20 # partnership account + seller account "3112": ami-0b2006b832e129368 # seller account (shared with partnership account) us-gov-east-1: "361": ami-001d5cec1e7399f65 # TODO: Get correct ami - provided by market place tem "3103": ami-08d1d573a758ba6b2 "3112": ami-06e7ce8983a50fd9c us-gov-west-1: "361": ami-0eb4eecce8d5bcb80 # TODO: Get correct ami - provided by market place tem 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