--- AWSTemplateFormatVersion: 2010-09-09 ###################################### ## Stack Description ###################################### Description: >- This template creates an HVR environment in a specified VPC. **WARNING** This template creates EC2 instances and related resources. You will be billed for the AWS resources used if you create a stack from this template.(qs-1roo3sq3n) ###################################### ## Stack Metadata ###################################### Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: End User License Agreement (EULA) - HVR CDC Parameters: - AcceptedEULA - Label: default: "VPC network configuration" Parameters: - VPCID - VPCCIDR - PrivateSubnet1 - PrivateSubnet2 - PrivateSubnet1CIDR - PrivateSubnet2CIDR - Label: default: "HVR EC2 Configuration" Parameters: - HVRInstanceTypeHUB - HVRInstanceTypeAgent - KeyName - Label: default: Tag identifiers Parameters: - TagEnvironment - Label: default: Public and Private keys for HVR communication Parameters: - HVRPubKeyBase64 - HVRPrivKeyBase64 - Label: default: Secrets Manager ARN for HVR License Key secret Parameters: - HVRLicenseSecret ParameterLabels: AcceptedEULA: default: Accepted EULA from AWS Marketplace VPCID: default: VPCID ID VPCCIDR: default: CIDR Block for the VPC PrivateSubnet1: default: Private subnet 1 ID PrivateSubnet2: default: Private subnet 2 ID PrivateSubnet1CIDR: default: Private Subnet 1 (AZ1) CIDR Range PrivateSubnet2CIDR: default: Private Subnet 2 (AZ2) CIDR Range HVRInstanceTypeHUB: default: HVR EC2 instance type for HVR HUB HVRInstanceTypeAgent: default: HVR EC2 instance type for HVR Agent KeyName: default: Key pair name TagEnvironment: default: Environment HVRPubKeyBase64: default: HVR Public Key (base64) HVRPrivKeyBase64: default: HVR Private Key (base64) HVRLicenseSecret: default: HVR License Key (Secret ARN) License: Apache-2.0 ###################################### ## Parameters ###################################### Parameters: AcceptedEULA: AllowedValues: - "yes" - "no" Default: "yes" Description: >- PLEASE READ THE HVR SOFTWARE LICENSE AGREEMENT (https://www.hvr-software.com/license-agreement/) CAREFULLY BEFORE USING THE SOFTWARE. The HVR stack can be created only if you have already accepted the EULA. To accept the EULA, see https://aws.amazon.com/marketplace/pp/B077YM8HPW. Type: String VPCID: Type: AWS::EC2::VPC::Id Description: The ID of the existing VPC that contains the subnets. VPCCIDR: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.0.0/16 Description: CIDR block for the VPC Type: String PrivateSubnet1: Description: "An existing private subnet 1 to launch secondary resources (e.g. PostgresSQL database)." Type: AWS::EC2::Subnet::Id PrivateSubnet2: Description: "An existing private subnet 2 to launch secondary resources (e.g. PostgresSQL database)." Type: AWS::EC2::Subnet::Id PrivateSubnet1CIDR: Description: VPC Stack Shared CIDR block for the private subnet 1 located in Availability Zone 1 Type: String NoEcho: true PrivateSubnet2CIDR: Description: VPC Stack Shared CIDR block for the private subnet 2 located in Availability Zone 2 Type: String NoEcho: true HVRInstanceTypeHUB: Description: General Purpose EC2 instance - Recommended for HUB only Instances Type: String Default: c5.large AllowedValues: [ t3.small, t3.medium, t3.large, c5.large, c5.xlarge, c5.2xlarge, c5d.large, c5d.xlarge, c5d.2xlarge ] ConstraintDescription: Must be a valid EC2 instance type. HVRInstanceTypeAgent: Description: Compute Based EC2 instance - Recommended for Agent instances running Capture/Integrate Type: String Default: c5.large AllowedValues: [ t3.small, t3.medium, t3.large, c5.large, c5.xlarge, c5.2xlarge, c5d.large, c5d.xlarge, c5d.2xlarge ] ConstraintDescription: Must be a valid EC2 instance type. KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instance Type: AWS::EC2::KeyPair::KeyName ConstraintDescription: must be the name of an existing EC2 KeyPair. TagEnvironment: Type: String AllowedValues: - dev - test Description: Designates the environment stage of the associated AWS resource. Default: "dev" ## The default public key below is a sample public key, with corresponding private key being defined below. ## These are used internally to allow secure communication between the HVR Hub and Agent. ## Self Signed certificates are used - they can be generated with hvrsslgen utility or using openssl, example ## openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout privkey.pem -out pub_cert.pem -subj "/C=XX/O=Self Signed/CN=Self Signed" -subject ## Lambda does not include openssl anymore otherwise using a lambda function would work. HVRPubKeyBase64: Description: | Specify HVR public key certificate (to be entered as a base64 string) to be used for secure HVR communication between the HVR hub and agents - (hvr.pub_cert), a default key is provided for testing. A method to get this string from your public certificate, is using the base64 utility, example: "cat hvr.pub_cert \| base64" Type: String NoEcho: true Default: | LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM5RENDQWR5Z0F3SUJBd0lCQURBTkJna3Fo a2lHOXcwQkFRc0ZBREFvTVFzd0NRWURWUVFHRXdKT1RERVoKTUJjR0ExVUVBd3dRU0ZaU0lFVjRZ VzF3YkdVZ1MyVjVjekFlRncweU1ERXlNekV3TURVek1qSmFGdzAwTURFeQpNall3TURVek1qSmFN Q2d4Q3pBSkJnTlZCQVlUQWs1TU1Sa3dGd1lEVlFRRERCQklWbElnUlhoaGJYQnNaU0JMClpYbHpN SUlCSURBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVEwQU1JSUJDQUtDQVFFQXB4Q1hVUFN6cUJlVys5 ZFoKbkFTNndQRXJPWVZSYkxhRStleTZUTW84bWUzTldzY044aW1TQktjYnViVFA2ajFUNEd1VzhS QVlaK3pJZGh4TQpRZmswYzRqMUR0NElPRll5UURIOFdHLzlxU3Rmc1psNjJOV2FwNXhDNWxFU0Mx MmQ1dkRqOUp3LzRlV29oU3J4CnBsY3EveVh6SWNoVWdyaWkxbExKSlFEMHUyTWxDQmN3ZjVVQkIv ZWFHa1U4SGZLMHU3MHhWcmtOYnJqYTRweSsKZFNJOS85VnFMWnpRNWZ1aGNhb1Q0WU9WbGpaUUpq UTN1clpaTVVtUnRybWl1SEVpdGtqa3NTeXNkZDdaODI1LwpoNWI3bkMzdlJ0VTExVnk3N3VtT0FB d2htbXJ3bitXb2JqZ0ZyenlvYWVwOVphV1dZY09mMTFKYUlnYk1WdUY1CklKTEUxd0lCQTZNck1D a3dKd1lKWUlaSUFZYjRRZ0VOQkJvV0dFZGxibVZ5WVhSbFpDQmllU0JJVmxJZ05TNDMKTGpBdk9E QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFhckVVYjNxeUcya0dYM1VMNXJHSlo3eW1kTktUMTls eQpLWnBLeWVCMjcvU1hPWVg3RDBITWNESlhlSk9vaGkvcmRBdGR2dXBiU3ZLK1dqSVR6amlSZ0Nw em05ZmNyTlFyCi81RzdONVdKSDJOK3I4cStuZGNaVnhZTytBaHA0djBkVXdDcGlUeVI1dUhWZ1g1 VlpWSyttSFZjTllxalgxaG4KTUVqeW1yUVRwUHdWeEpSY2FKaE9peC9wcThadStmZzRqQ3FrNC9D OTQzMjVPQnZ0ZEhXMkZ6UGZ4TERPM1pUSgpmVE5pTnV0VEM1MDMxZEc0SEJGWGtWdnAxenk3bDRx U2ZVWG1YR0dSMkNETlhYaDVHeVJpWlpFQUlpSHBoR21LClMyUHZlREJPN1B1RDdCcWpqK1BkcE5x UFdzVTN5M3dabHZhcjBkT3NKYWZXSmlYb2x0ay9wZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0t LS0K HVRPrivKeyBase64: Description: | Specify HVR private key (to be entered as a base64 string) to be used for secure HVR communication between the HVR hub and agents - (hvr.pub_cert), a default key is provided for testing. A method to get this string from your public certificate, is using the base64 utility, example: "cat hvr.pub_cert \| base64" Type: String NoEcho: true Default: | LS0tLS1CRUdJTiBFTkNSWVBURUQgUFJJVkFURSBLRVktLS0tLQpNSUlGTFRCWEJna3Foa2lHOXcw QkJRMHdTakFwQmdrcWhraUc5dzBCQlF3d0hBUUlDenVUbmhMbDBZOENBZ2dBCk1Bd0dDQ3FHU0li M0RRSUpCUUF3SFFZSllJWklBV1VEQkFFcUJCREhldVlYMUU2QitxbE52U1M3VTJMbkJJSUUKMEVl aGlVekI0SWUzZWhObnVCWHU5UERmUHZEdFdBcTk5OHlud1M2dTMrSEZJNEhnbkJCQ01KaVllL09w QUI1RgpkQnI0K0NsM1R3VkFENlVJNzkyOXpLVmUxT3lsV0ROUlZNdzF3VVlNUFZVQURNZEFscVRa L2FWZS9NT3A1Qk5hClJZQVV4WkFuTWg0eStyK3U2aWRYZW1wK2hOckJHUVNLeEFPbnNIbVkzQ3pu K01maUxxajRaeThlU0FmbWlFSksKODQwSStQWGtNNG84c2ZNWHAzeEpWY0RxTjBsZ1Aya2JYK0l4 RmdrdzhrQWFoZEJFcDBxSVhKSUtZQ1JUZC9BLwo5TGV6bldYQzFkU0gwRGNlaTRUaVUvMEc1NHgz ODg1MDNJZmV6QUE3TWkxNHpqSWlEckg5TnA0MFMxbDFDOThBCnFXT0FuL2ZzQjFRRmo5S0NUMVdM Wmx1TDJ3NHc2SzZGR2ZkVlB4bFN4RnlVRGxXTEZDeWo4NVI5MWcxdWxGRFEKcHZ5VE5IV3ZRTzFH S0FkR0dkc3VTUnlXOGVJYnlkUTJlNmZaKzJTM3ZibGVMTTdwdUU0aktEcFVCbHpaaUI2bQp6QzRU Mm85a0k0TTVwU0tRYnQ2bFdwNTZnRkMwWmdnaTFiVXFTSDU5RHRKVjcvcmVBdngxcDhvZkpVbUs4 eWhPClRyaTJKYXpzZHBVRVByVitmUHdycXJ2dG4yRUhXVmNqamFiODdLaDFvYmpGZUZ1czBRRE5O aTFsYmYwVlZkZ0EKN2JQVWxXY3BJcndwd09LKzBUZXNBemtlNnREMmhPTi92REJ3S2hwZkd1TFU1 ZEh1VlFLUmdoUk80d1dlanUxRQp2eS9tcWkwbG9DUE95bUFwQ2FVcnd6MmZBbVI0T1d0b0t1Tjli NHhRSTk0dEt2aDk1VGgwN0NyS2k5SUcyZWN5CjJhb1FpRmM2T2hZMndiMHdzUVM1blZId3Q4WCtp SHpJdkJCU3BvaG9xb29pREhUR1k3ODRrN0E4ZVhmQ2o0dkwKUWZnamJ0eWYwOGh1NGpuYXg3TFFy b0hYL0pYUGFHd1Y4Uk03NjZoRTl4bUF6bmhDWDI5M0lrK05CVWRkYkxFNQpnSU1HWUIzejZ3ekI4 b3E5S3lZdVMwbHkweE1MbzBzTVhNTTExR1RDL0Vaem1abm5SMXFGNUZBTCtnckJXV3BCCkQ5Mml6 RElZZmRNYllnbk9vb2RVS2pXSnZyRWZaQUxMWUFJOENaVTJMeHpBRkpPWWpJenR5L2dKNU9vOG1E R3EKU0dlbnBmMXlhUFhpalhUSEJNN3JnNDhoZWl1UGUvbEZ0bmM3bFZkdjR0cEFSaCs2bEJ4alNl R1JQU2lVdG1yUQo0NUNpYTQwaVFEOTZadHc3dGxsNEN1U0I1WTdDVy8wQzVmSFAvdWNTMERWMU9a b3h3R1hmcGdzSnJPM1pDUG1JCkJBbm8xT3JKeWlidHp6ZGppTFBrUkdPZTJJcWlNL25pQUtsZ1pq Q3g2aFZjQzhldlV6RzhiWUREb0o3OGpsRXQKRG9XY2VqY1JXS3NiaUJQbi9UQWd5UTJRUFJMYkY4 V0hxUisweTllK2J0UlpHVXB2aEExMWdOVUVianJTTTE2VwpkazZ1TUtwRUpVeHVrOVp6QjdVSjV6 Qi9UcUhiaUVqM1NDRUdVbzNDMGQ4bW5DVmw4cEZ0OExHaGFDNnV0TWJYCll2Y2JFQ0pySUI2VkVn Z0sxd0FDWlZVdXVFRFF0M2tDbFZsaG5xa1phbmpoSW82TkI0M1c0a1BHRmxWQ2hJTmUKdXZhSzBq bnVkNzU5NHFub0NOOFlSUm5UYUJpT3lBdnpHb3owemlnR1ZRRG55VndqV1oySnZEOTlvNE9iMkhV OQpEVDVhMHRyclM4S1cvcUdqZ2dwYXVPZ0dmUVJBY2doVExpVTBFZnVoN1l1WTlmZFBYR3FLRkhQ MUttSmp4VDMyCjFtT3pzSjZLcWJRR0xsWVMwdGxlN0dNcS9KbEVlOHFaRFlKMWwyWHBkaThiLy9w L3JOZE5lbWZ6Q0VlZnhLSTIKUkN3WFhLeDBuOHNBakc4Y2JmQVJ5eERSK1hoYU1tUTdDeXFiNDJU TzdHOEdlK2VMSEhLWnFSWFlEengzaWxsWAoraGNpd005dXNyZ215bFpJcXZkWjdZS2dNNkFVTURY bDNHYms2N3RzT0l2LwotLS0tLUVORCBFTkNSWVBURUQgUFJJVkFURSBLRVktLS0tLQo= HVRLicenseSecret: Description: | Please specify the ARN to the AWS Secret (to be located in AWS Secrets Manager) that can be used for the HVR deployment. If no value is specified a temporary dummy Secret will be created in Secrets Manager as hvr/quickstart/{TagEnvironment}/hvrlic. If you require a license please contact the HVR Software sales team and leave the value as "none". Type: String Default: "none" ###################################### ## Condition definitions ###################################### Conditions: IsAcceptedEULA: !Equals - !Ref AcceptedEULA - "yes" NoHVRLicenseProvided: !Equals - !Ref HVRLicenseSecret - "none" ###################################### ## Mapping definitions ###################################### # ## You can get the mapping below by using the ec2 describe images option and listing the HVR version you are looking at using ## from the AWS Marketplace - using the BYOL HVR image is recommended. # # version=5.7.0.12-byol # for region in `aws --region ap-southeast-2 ec2 describe-regions --output text | cut -f4` # do # echo -e "$region:" # aws ec2 describe-images --region $region --owners aws-marketplace --filters "Name=name, Values=*hvr-${version}*" --query 'Images[*].[ImageId,CreationDate]' --output text | sort -k2 -r | head -n1 |cut -f1 # done # # Mappings: RegionMap: eu-north-1: AMI: ami-09c028d029aa47c59 ap-south-1: AMI: ami-05b45cb4d48b27c2c eu-west-3: AMI: ami-0d5190aced2bf17ec eu-west-2: AMI: ami-04cf781936ce8f63d eu-west-1: AMI: ami-0e8d392b3ddf9659b ap-northeast-3: AMI: ami-0e7913085a4c9b509 ap-northeast-2: AMI: ami-0c0bae7a0dd8a5098 ap-northeast-1: AMI: ami-07d5ef58b1dbfdbeb sa-east-1: AMI: ami-02654fc04ad5454e5 ca-central-1: AMI: ami-049d7a3dfd3295ac1 ap-southeast-1: AMI: ami-0a23712d215e8963d ap-southeast-2: AMI: ami-01e9fcbbfa56e4c60 eu-central-1: AMI: ami-0a302ce05f1f03bc5 us-east-1: AMI: ami-05ceb67c8f00b6ae4 us-east-2: AMI: ami-0ed20b612db8061af us-west-1: AMI: ami-02dbdb6715defb628 us-west-2: AMI: ami-0ed596901365f3378 ###################################### ## Declaration of stack resources ###################################### Resources: ## ------------------------------------------------------------ # ## Create Secrets Manager Secret to hold the HVR License Key ## ------------------------------------------------------------ # HVRLicKey: Type: AWS::SecretsManager::Secret Properties: Description: HVR Quickstart License Key Tags: - Key: Name Value: !Sub HVRLicKey-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create Secrets Manager Secret to hold the HVR Unix User Password ## ------------------------------------------------------------ # HVRUnixUserPassword: Type: "AWS::SecretsManager::Secret" Properties: Description: Autogenerated HVR Unix User Password GenerateSecretString: PasswordLength: 16 ExcludeCharacters: '"@/\' Tags: - Key: Name Value: !Sub HvrUnixUserPassword-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create Secrets Manager Secret to hold the Private Key for HVR encrypted communication ## ------------------------------------------------------------ # HVRPrivKey: Type: "AWS::SecretsManager::Secret" Properties: Description: Private Key to be used for Secure HVR communication SecretString: !Ref HVRPrivKeyBase64 Tags: - Key: Name Value: !Sub hvrPrivKey-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create Secrets Manager Secret to hold the Public Key for HVR encrypted communication ## ------------------------------------------------------------ # HVRPubKey: Type: "AWS::SecretsManager::Secret" Properties: Description: Public Key to be used for Secure HVR communication SecretString: !Ref HVRPubKeyBase64 Tags: - Key: Name Value: !Sub hvrPubKey-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create S3 Bucket to store NLB Access Logs ## - explicit block public access ## ------------------------------------------------------------ # NLBAccessLogsBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: 'aws:kms' ## ------------------------------------------------------------ # ## Create S3 Bucket Policy (NLB Access Logs) ## ------------------------------------------------------------ # NLBAccessLogsBucketPolicy: Type: AWS::S3::BucketPolicy Properties: PolicyDocument: Id: NLBAccessLogsBucketPolicy Version: 2012-10-17 Statement: - Sid: "AWSLogDeliveryWrite" Effect: Allow Principal: Service: "delivery.logs.amazonaws.com" Action: 's3:PutObject' Resource: !Join - '' - - 'arn:aws:s3:::' - !Ref NLBAccessLogsBucket - /AWSLogs/ - !Ref AWS::AccountId - /* - Sid: "AWSLogDeliveryAclCheck" Effect: Allow Principal: Service: "delivery.logs.amazonaws.com" Action: 's3:GetBucketAcl' Resource: !Join - '' - - 'arn:aws:s3:::' - !Ref NLBAccessLogsBucket Bucket: !Ref NLBAccessLogsBucket ## ------------------------------------------------------------ # ## Create Security Group for the HVR Agent EC2 Instances ## - Allow SSH, and Webdesktop via Bastion host to Hub ## - Allow HVR port on internal subnet for communication with agents ## - Allow EFS Port for Mount ## ------------------------------------------------------------ # HVRSecurityGroupHUB: Condition: IsAcceptedEULA Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security Group for the HVR Hub VpcId: Ref: VPCID Tags: - Key: Name Value: !Sub hvr-SG-Hub-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} SecurityGroupIngress: ## Allow ICMP - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: !Ref VPCCIDR # Bastion HVR GUI to Hub Communication - IpProtocol: tcp FromPort: 4343 ToPort: 4343 CidrIp: !Ref VPCCIDR Description: Allow HVR Port 4343 from within VPC ## Bastion SSH to Hub - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref VPCCIDR Description: Allow SSH from within VPC ## EFS - IpProtocol: tcp FromPort: 2049 ToPort: 2049 CidrIp: !Ref PrivateSubnet1CIDR Description: Allow EFS on private Subnet1 - IpProtocol: tcp FromPort: 2049 ToPort: 2049 CidrIp: !Ref PrivateSubnet2CIDR Description: Allow EFS on private Subnet1 SecurityGroupEgress: ## Allow TCP outbound - IpProtocol: tcp FromPort: 0 ToPort: 65535 CidrIp: 0.0.0.0/0 Description: Allow outbound TCP access ## ------------------------------------------------------------ # ## Create Security Group for the HVR Agent EC2 Instances ## ------------------------------------------------------------ # HVRSecurityGroupAgent: Condition: IsAcceptedEULA Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Security Group for the HVR Agent VpcId: !Ref VPCID Tags: - Key: Name Value: !Sub hvr-SG-Agent-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} SecurityGroupIngress: ## Allow ICMP - IpProtocol: icmp FromPort: -1 ToPort: -1 CidrIp: !Ref VPCCIDR ## Hub/NLB Communication - IpProtocol: tcp FromPort: 4343 ToPort: 4343 CidrIp: !Ref PrivateSubnet1CIDR Description: Allow HVR Port 4343 on private Subnet1 - IpProtocol: tcp FromPort: 4343 ToPort: 4343 CidrIp: !Ref PrivateSubnet2CIDR Description: Allow HVR Port 4343 on private Subnet2 ## ssh in private subnets - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref PrivateSubnet1CIDR Description: Allow SSH on private Subnet1 - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref PrivateSubnet2CIDR Description: Allow SSH on private Subnet2 SecurityGroupEgress: ## Allow TCP outbound - IpProtocol: tcp FromPort: 0 ToPort: 65535 CidrIp: 0.0.0.0/0 Description: Allow outbound TCP access ## ------------------------------------------------------------ # ## Create EFS Filesystem ## ------------------------------------------------------------ # FileSystem: Condition: IsAcceptedEULA Type: AWS::EFS::FileSystem Properties: PerformanceMode: generalPurpose # Enable default encryption on EFS filesystem Encrypted: true FileSystemTags: - Key: Name Value: !Sub HVREFS-${AWS::StackName}-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create EFS Mount Target ## ------------------------------------------------------------ # MountTarget1: Condition: IsAcceptedEULA Type: AWS::EFS::MountTarget Properties: FileSystemId: Ref: FileSystem SubnetId: Ref: PrivateSubnet1 SecurityGroups: - Ref: HVRSecurityGroupHUB ## ------------------------------------------------------------ # ## Create EFS Mount Target ## ------------------------------------------------------------ # MountTarget2: Condition: IsAcceptedEULA Type: AWS::EFS::MountTarget Properties: FileSystemId: Ref: FileSystem SubnetId: Ref: PrivateSubnet2 SecurityGroups: - Ref: HVRSecurityGroupHUB ## ------------------------------------------------------------ # ## Create the Auto Scaling Group for the HVR Hub ## - 1 EC2 Instance running at a time ## ------------------------------------------------------------ # HVRHUBAutoScalingGroup: Condition: IsAcceptedEULA Type: "AWS::AutoScaling::AutoScalingGroup" Properties: AutoScalingGroupName: !Sub hvr-hub-ASG-${TagEnvironment} LaunchTemplate: LaunchTemplateId: !Ref HVRHUBLaunchTemplate Version: !GetAtt HVRHUBLaunchTemplate.LatestVersionNumber VPCZoneIdentifier: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 MinSize: "1" MaxSize: "1" Cooldown: "900" DesiredCapacity: "1" Tags: - Key: Name Value: !Sub HVRHub-${TagEnvironment} PropagateAtLaunch: true - Key: EnvironmentStage Value: !Sub ${TagEnvironment} PropagateAtLaunch: true TargetGroupARNs: - !Ref HVRHUBNLBTargetGroup CreationPolicy: ResourceSignal: Count: 1 Timeout: PT10M AutoScalingCreationPolicy: MinSuccessfulInstancesPercent: 100 UpdatePolicy: AutoScalingReplacingUpdate: WillReplace: true ## ------------------------------------------------------------ # ## Create the Auto Scaling Group for the HVR Agents ## - 1 EC2 Instance (Agent) per AZ ## ------------------------------------------------------------ # HVRAgentAutoScalingGroup: Condition: IsAcceptedEULA Type: "AWS::AutoScaling::AutoScalingGroup" Properties: AutoScalingGroupName: !Sub hvr-agent-ASG-${TagEnvironment} LaunchTemplate: LaunchTemplateId: !Ref HVRAgentLaunchTemplate Version: !GetAtt HVRAgentLaunchTemplate.LatestVersionNumber VPCZoneIdentifier: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 MinSize: "2" MaxSize: "4" Cooldown: "900" DesiredCapacity: "2" Tags: - Key: Name Value: !Sub HVRAgent-${TagEnvironment} PropagateAtLaunch: true - Key: EnvironmentStage Value: !Sub ${TagEnvironment} PropagateAtLaunch: true TargetGroupARNs: - !Ref HVRAgentNLBTargetGroup CreationPolicy: ResourceSignal: Count: 1 Timeout: PT10M AutoScalingCreationPolicy: MinSuccessfulInstancesPercent: 100 UpdatePolicy: AutoScalingReplacingUpdate: WillReplace: true ## ------------------------------------------------------------ # ## Create the Launch Template for the HVR HUB EC2 Instances ## ------------------------------------------------------------ # HVRHUBLaunchTemplate: Condition: IsAcceptedEULA DependsOn: - FileSystem - HVRLicKeyWaitCondition Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: !Sub hvr-hub-LT-${TagEnvironment} LaunchTemplateData: KeyName: !Ref KeyName IamInstanceProfile: Arn: Fn::GetAtt: - HVRInstanceProfile - Arn ImageId: Fn::FindInMap: - RegionMap - Ref: AWS::Region - AMI SecurityGroupIds: - !Ref HVRSecurityGroupHUB InstanceType: !Ref HVRInstanceTypeHUB BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: True VolumeType: gp3 - DeviceName: /dev/xvdb Ebs: DeleteOnTermination: True VolumeType: gp3 UserData: Fn::Base64: !Sub | #!/bin/bash -x yum update -y export HVR_HOME=/opt/hvr/hvr_home export HVR_CONFIG=/opt/hvr/hvr_config REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region) aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRPrivKey} --query 'SecretString' --output text | base64 -d > /opt/hvr/hvr_home/lib/cert/hvrqs.priv_key aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRPubKey} --query 'SecretString' --output text | base64 -d > /opt/hvr/hvr_home/lib/cert/hvrqs.pub_cert HVRUSERPWD=`aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRUnixUserPassword} --query 'SecretString' --output text` if [ "$HVRLicenseSecret" = "none" ]; then aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRLicKey} --query 'SecretString' --output text > /opt/hvr/hvr_home/lib/hvr.lic else aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRLicenseSecret} --query 'SecretString' --output text > /opt/hvr/hvr_home/lib/hvr.lic fi chown -R hvr:hvr /opt/hvr/hvr_home/lib/hvr.lic ## set hvr user password, we use pub/priv cert and password together for hvr authentication echo "hvr:$HVRUSERPWD" | chpasswd ## Create EFS Mount Point - sleep might be required if FS and DNS not ready yet # sleep 90 EFS_MOUNT_OPTIONS=tls,_netdev,defaults mount -t efs --options $EFS_MOUNT_OPTIONS ${FileSystem}:/ $HVR_CONFIG chown -R hvr:hvr $HVR_CONFIG ## Add to fstab to allow mount on restart echo "${FileSystem}:/ $HVR_CONFIG efs $EFS_MOUNT_OPTIONS 0 0" >> /etc/fstab chown hvr:hvr /opt/hvr/hvr_home/lib/cert/hvrqs.* chmod 600 /opt/hvr/hvr_home/lib/cert/hvrqs.* sed -i -e "s/^ExecStart.*/ExecStart\=\/opt\/hvr\/hvr_home\/bin\/hvr -r -plogin -Khvrqs/" /etc/systemd/system/hvr@.service function cfn_fail { /opt/aws/bin/cfn-signal -e 1 --stack ${AWS::StackName} --region ${AWS::Region} --resource HVRHUBAutoScalingGroup exit 1 } function cfn_success { /opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --region ${AWS::Region} --resource HVRHUBAutoScalingGroup exit 0 } # just run cfn-signal cfn_success || cfn_fail ## ------------------------------------------------------------ # ## Create the Launch Template for the HVR Agent EC2 Instances ## ------------------------------------------------------------ # HVRAgentLaunchTemplate: Condition: IsAcceptedEULA DependsOn: FileSystem Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: !Sub hvr-agent-LT-${TagEnvironment} LaunchTemplateData: KeyName: !Ref KeyName IamInstanceProfile: Arn: Fn::GetAtt: - HVRInstanceProfile - Arn ImageId: Fn::FindInMap: - RegionMap - Ref: AWS::Region - AMI SecurityGroupIds: - !Ref HVRSecurityGroupAgent InstanceType: !Ref HVRInstanceTypeAgent BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: True VolumeType: gp3 - DeviceName: /dev/xvdb Ebs: DeleteOnTermination: True VolumeType: gp3 UserData: # This code HVR as a systemd service. unixODBC, mysql, postgres, snowflake, redshift, Then it signals completion: Fn::Base64: !Sub | #!/bin/bash -x yum update -y REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region) aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRPrivKey} --query 'SecretString' --output text | base64 -d > /opt/hvr/hvr_home/lib/cert/hvrqs.priv_key aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRPubKey} --query 'SecretString' --output text | base64 -d > /opt/hvr/hvr_home/lib/cert/hvrqs.pub_cert HVRUSERPWD=`aws --region $REGION secretsmanager get-secret-value --secret-id ${HVRUnixUserPassword} --query 'SecretString' --output text` ## set hvr user password, we use pub/priv cert and password together for hvr authentication echo "hvr:$HVRUSERPWD" | chpasswd chown hvr:hvr /opt/hvr/hvr_home/lib/cert/hvrqs.* chmod 600 /opt/hvr/hvr_home/lib/cert/hvrqs.* sed -i -e "s/^ExecStart.*/ExecStart\=\/opt\/hvr\/hvr_home\/bin\/hvr -r -plogin -Khvrqs/" /etc/systemd/system/hvr@.service function cfn_fail { /opt/aws/bin/cfn-signal -e 1 --stack ${AWS::StackName} --region ${AWS::Region} --resource HVRAgentAutoScalingGroup exit 1 } function cfn_success { /opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --region ${AWS::Region} --resource HVRAgentAutoScalingGroup exit 0 } # just run cfn-signal cfn_success || cfn_fail ## ------------------------------------------------------------ # ## Create the Network Load Balancer for the HVR Hub ## ------------------------------------------------------------ # HVRHUBNLB: Condition: IsAcceptedEULA Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internal LoadBalancerAttributes: - Key: access_logs.s3.enabled Value: "true" - Key: access_logs.s3.bucket Value: !Ref NLBAccessLogsBucket Subnets: - Ref: PrivateSubnet1 - Ref: PrivateSubnet2 Type: network Tags: - Key: Name Value: !Sub hvr-hub-nlb-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create the Network Load Balancer for the HVR Agents ## ------------------------------------------------------------ # HVRAgentNLB: Condition: IsAcceptedEULA Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internal LoadBalancerAttributes: - Key: access_logs.s3.enabled Value: "true" - Key: access_logs.s3.bucket Value: !Ref NLBAccessLogsBucket Subnets: - Ref: PrivateSubnet1 - Ref: PrivateSubnet2 Type: network Tags: - Key: Name Value: !Sub hvr-agent-nlb-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create the Load Balancer Target Group for the HVR Hub ## ------------------------------------------------------------ # HVRHUBNLBTargetGroup: Condition: IsAcceptedEULA DependsOn: HVRHUBNLB Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Sub hvr-hub-nlb-target-${TagEnvironment} TargetType: instance Port: 4343 Protocol: TCP VpcId: !Ref VPCID TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: "60" Tags: - Key: Name Value: !Sub hvr-hub-nlb-target-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create the Load Balancer Target Group for the HVR Agents ## ------------------------------------------------------------ # HVRAgentNLBTargetGroup: Condition: IsAcceptedEULA DependsOn: HVRAgentNLB Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Sub hvr-agent-nlb-target-${TagEnvironment} TargetType: instance Port: 4343 Protocol: TCP VpcId: !Ref VPCID TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: "60" Tags: - Key: Name Value: !Sub hvr-agent-nlb-target-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} ## ------------------------------------------------------------ # ## Create the Network Load Balancer Listener for the HVR Hub ## ------------------------------------------------------------ # HVRHUBNLBListener: Condition: IsAcceptedEULA Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref HVRHUBNLBTargetGroup LoadBalancerArn: !Ref HVRHUBNLB Port: 4343 Protocol: TCP ## ------------------------------------------------------------ # ## Create the Network Load Balancer Listener for the HVR Agents ## ------------------------------------------------------------ # HVRAgentNLBListener: Condition: IsAcceptedEULA Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref HVRAgentNLBTargetGroup LoadBalancerArn: !Ref HVRAgentNLB Port: 4343 Protocol: TCP ## ------------------------------------------------------------ # ## Create Role that will be assigned to EC2 Instance Profile ## ------------------------------------------------------------ # HVRRole: Condition: IsAcceptedEULA Type: AWS::IAM::Role Properties: Description: HVR Role that will be used in EC2 instance profile for the HVR Hub and Agent. Tags: - Key: Name Value: !Sub hvr-role-${TagEnvironment} - Key: EnvironmentStage Value: !Sub ${TagEnvironment} AssumeRolePolicyDocument: Statement: - Action: "sts:AssumeRole" Principal: Service: ec2.amazonaws.com Effect: Allow Sid: "" Policies: - PolicyDocument: Version: 2012-10-17 Statement: ##### # Uncomment the required permissions depending on what service will be used, example RDS or S3 # This will require the explicit set of the RESOURCE to only allow access to the resource and not using * for all of the account ##### # - Action: # - s3:ListAllMyBuckets # - s3:ListBucket # - s3:GetObject # - s3:PutObject # - s3:DeleteObject # - s3:GetBucketLocation # Effect: Allow # Resource: # - "*" # Sid: StmtMinS3 # - Action: # - sqs:DeleteMessage # - sqs:ListQueues # - sqs:ReceiveMessage # - sqs:SendMessage # - sqs:GetQueueUrl # Effect: Allow # Resource: # - "*" # Sid: StmtMinSQS # - Action: # - rds:DescribeDBInstances # Effect: Allow # Resource: # - "*" # Sid: StmtMinRDS # - Action: # - ec2:CreateSnapshot # - ec2:CreateTags # - ec2:DescribeInstances # - ec2:DescribeVolumes # Effect: Allow # Resource: # - "*" # Sid: StmtMinEC2 # - Action: # - sns:ListTopics # - sns:CreateTopic # - sns:Publish # Effect: Allow # Resource: # - "*" # Sid: StmtMinSNS # - Action: # - cloudwatch:PutMetricData # - cloudwatch:ListMetrics # Effect: Allow # Resource: # - "*" # Sid: StmtMinCloudwatch # - Action: # - logs:CreateLogGroup # - logs:CreateLogStream # - logs:PutLogEvents # - logs:DescribeLogStreams # Effect: Allow # Resource: # - arn:aws:logs:*:*:* # Sid: StmtMinCloudwatchLogs # - Action: # - kms:ListAliases # - kms:Encrypt # - kms:Decrypt # Effect: Allow # Resource: # - "*" # Sid: StmtMinKMS # - Action: # - ec2:DescribeRegions # - iam:ListRoles # - s3:GetBucketNotification # - s3:ListAllMyBuckets # - s3:PutBucketNotification # - sqs:ChangeMessageVisibility # - sqs:DeleteMessage # - sqs:ListQueues # - sqs:ReceiveMessage # Effect: Allow # Resource: "*" # Sid: CDCPermissions - Effect: Allow Action: - "secretsmanager:GetSecretValue" Resource: - !Ref HVRPrivKey - !Ref HVRPubKey - !Ref HVRUnixUserPassword - !If - NoHVRLicenseProvided - !Ref HVRLicKey - !Ref HVRLicenseSecret Sid: SSMPermissions PolicyName: !Sub hvr-role-policy-${TagEnvironment} ## ------------------------------------------------------------ # ## Create the EC2 Instance Profile and assign role to it ## ------------------------------------------------------------ # HVRInstanceProfile: Condition: IsAcceptedEULA DependsOn: - HVRLicKeyWaitCondition Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Sub hvr-instance-profile-${TagEnvironment} Path: / Roles: - !Ref HVRRole ## ------------------------------------------------------------ # # This is work-around to ensure we have correct dependancy for License Key secret to be # created prior to other resources, using below is DependsOn does not support !If condition ## ------------------------------------------------------------ # HVRLicKeyWaitHandle: Condition: NoHVRLicenseProvided DependsOn: - "HVRLicKey" Type: AWS::CloudFormation::WaitConditionHandle WaitHandle: Type: AWS::CloudFormation::WaitConditionHandle HVRLicKeyWaitCondition: Type: AWS::CloudFormation::WaitCondition Properties: Handle: !If [NoHVRLicenseProvided, !Ref HVRLicKeyWaitHandle, !Ref WaitHandle] Timeout: "1" Count: 0 ## ------------------------------------------------------------ # ###################################### ## Define stack output values ###################################### Outputs: HVRUnixUserSecretARN: Condition: IsAcceptedEULA Description: AWS Secret ARN for HVR Unix user password, located in Secrets Manager. Value: !Ref HVRUnixUserPassword HVRPort: Condition: IsAcceptedEULA Description: Default Port of the HVR Hub and Agent Value: 4343 HVRHubNLBDns: Condition: IsAcceptedEULA Description: HVR Hub Access Point (Load Balancer DNS) Value: !GetAtt HVRHUBNLB.DNSName HVRAgentNLBDns: Condition: IsAcceptedEULA Description: HVR Agent Access Point (Load Balancer DNS) Value: !GetAtt HVRAgentNLB.DNSName HVRPublicKey: Condition: IsAcceptedEULA Description: HVR Hub Public Key Value: !Ref HVRPubKeyBase64