From 69d4f1313c81c1f5e7e2159fa0a1c17b703a4558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Czoma?= Date: Fri, 18 Feb 2022 14:29:44 -0500 Subject: [PATCH] 2022 January updates (#57) * New parameter to select worker node storage type, defaulting to less expensive gp2 * Fixed health load balancer check failed when using restricted Remote Access CIDR * Modified assert-master or resync-master for ALL message-vpns * Ported changes from aws-hosted QS: removed condition from BastionHostRole * Documentation updates --- .github/workflows/build-test.yml | 43 ++++++++++++++++------------- README.md | 5 ++-- scripts/install-solace.sh | 23 ++------------- submodules/quickstart-aws-vpc | 2 +- submodules/quickstart-linux-bastion | 2 +- templates/nodecreate.template | 24 ++++++++++++---- templates/solace-master.template | 16 +++++++++-- templates/solace.template | 15 +++++++++- 8 files changed, 77 insertions(+), 53 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index fecb548..ae5b2bf 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -48,7 +48,7 @@ jobs: - name: Copy test artifacts to test S3 bucket run: | MESSAGEBROKERNODEINSTANCETYPE=t2.medium - sed -i "s@SolaceDockerImageParameterValue@${{ secrets.BROKER_DOCKER_IMAGE_REF }}@g" ci/solace-aws-ha-3az-prod-test.json + sed -i "s@SolaceDockerImageParameterValue@solace/solace-pubsub-standard:latest@g" ci/solace-aws-ha-3az-prod-test.json sed -i "s@EventBrokerNodeInstanceTypeParameterValue@${MESSAGEBROKERNODEINSTANCETYPE}@g" ci/solace-aws-ha-3az-prod-test.json aws s3 mb s3://${{ env.TEST_S3_BUCKET }} || echo "s3 bucket already existed" export BUCKETREGION=`aws s3api get-bucket-location --bucket ${{ env.TEST_S3_BUCKET }} | grep LocationConstraint | awk -F' ' '{print $NF}' | tr -d '"'` @@ -91,24 +91,24 @@ jobs: stackid="$(aws cloudformation describe-stacks --stack-name $TESTSTACKNAME | grep StackId | awk -F '"' '{print $4}')" if [ -n "$stackid" ]; then until aws cloudformation describe-stacks --stack-name $stackid | grep -m 1 "DELETE_COMPLETE"; do sleep 10; done; fi - - name: Testing with No Private Subnet - run: | - export TESTSTACKNAME2="$TESTSTACKNAME-1" - echo "TESTSTACKNAME2=$TESTSTACKNAME2" >> $GITHUB_ENV - sed -i "s@true@false@g" ci/solace-aws-ha-3az-prod-test.json - aws cloudformation create-stack --stack-name $TESTSTACKNAME2 --template-body file://templates/solace-master.template --parameters file://ci/solace-aws-ha-3az-prod-test.json --on-failure ROLLBACK --capabilities CAPABILITY_NAMED_IAM - echo "Waiting for stack create complete" - until aws cloudformation describe-stacks --stack-name $TESTSTACKNAME2 | grep -m 1 -E 'CREATE_COMPLETE|DELETE_IN_PROGRESS'; do sleep 10; done - aws cloudformation describe-stack-events --stack-name $TESTSTACKNAME2 - aws cloudformation describe-stacks --stack-name $TESTSTACKNAME2 - - - name: Delete No Private Subnet test deployment (Cleanup) - if: ${{ always() }} - run: | - aws cloudformation delete-stack --stack-name $TESTSTACKNAME2 || echo "Couldn't delete stack $TESTSTACKNAME2" - echo "Waiting for stack delete complete" - stackid="$(aws cloudformation describe-stacks --stack-name $TESTSTACKNAME2 | grep StackId | awk -F '"' '{print $4}')" - if [ -n "$stackid" ]; then until aws cloudformation describe-stacks --stack-name $stackid | grep -m 1 "DELETE_COMPLETE"; do sleep 10; done; fi +# - name: Testing with No Private Subnet +# run: | +# export TESTSTACKNAME2="$TESTSTACKNAME-1" +# echo "TESTSTACKNAME2=$TESTSTACKNAME2" >> $GITHUB_ENV +# sed -i "s@true@false@g" ci/solace-aws-ha-3az-prod-test.json +# aws cloudformation create-stack --stack-name $TESTSTACKNAME2 --template-body file://templates/solace-master.template --parameters file://ci/solace-aws-ha-3az-prod-test.json --on-failure ROLLBACK --capabilities CAPABILITY_NAMED_IAM +# echo "Waiting for stack create complete" +# until aws cloudformation describe-stacks --stack-name $TESTSTACKNAME2 | grep -m 1 -E 'CREATE_COMPLETE|DELETE_IN_PROGRESS'; do sleep 10; done +# aws cloudformation describe-stack-events --stack-name $TESTSTACKNAME2 +# aws cloudformation describe-stacks --stack-name $TESTSTACKNAME2 +# +# - name: Delete No Private Subnet test deployment (Cleanup) +# if: ${{ always() }} +# run: | +# aws cloudformation delete-stack --stack-name $TESTSTACKNAME2 || echo "Couldn't delete stack $TESTSTACKNAME2" +# echo "Waiting for stack delete complete" +# stackid="$(aws cloudformation describe-stacks --stack-name $TESTSTACKNAME2 | grep StackId | awk -F '"' '{print $4}')" +# if [ -n "$stackid" ]; then until aws cloudformation describe-stacks --stack-name $stackid | grep -m 1 "DELETE_COMPLETE"; do sleep 10; done; fi - name: Update QuickStart S3 on success for SolaceProducts if: ${{ success() }} && github.event_name == 'push' @@ -116,3 +116,8 @@ jobs: if [ ${{ github.ref }} == 'refs/heads/master' ] && [ ${{ github.repository_owner }} == 'SolaceProducts' ] ; then aws s3 sync . s3://solace-products/pubsubplus-aws-ha-quickstart/latest --acl public-read fi + + - name: Delete all unattached volumes (Cleanup) + if: ${{ always() }} + run: | + for volume in `aws ec2 describe-volumes --filter "Name=status,Values=available" --query "Volumes[*].{ID:VolumeId}" --region $AWS_DEFAULT_REGION | grep ID | awk -F '"' '{print $4}'`; do aws ec2 delete-volume --volume-id $volume --region $AWS_DEFAULT_REGION; done diff --git a/README.md b/README.md index b9a42e5..1cabe43 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Install and Configure Solace PubSub+ Software Event Broker in an HA Tuple using AWS Cloud Formation -This project is a best practice template intended for development and demo purposes. The tested and recommended Solace PubSub+ Software Event Broker version is 9.10. +This project is a best practice template intended for development and demo purposes. The tested and recommended Solace PubSub+ Software Event Broker version is 9.12. This document provides a quick getting started guide to install a Solace PubSub+ software event broker deployment in Amazon Web Services cloud computing platform. @@ -108,7 +108,8 @@ The next screen will allow you to fill in the details for the selected launch op | Maximum Number of Client Connections (MaxClientConnections)| 100 | Broker system scaling: the maximum supported number of client connections | | Maximum Number of Queue Messages (MaxQueueMessages) | 100 | Broker system scaling: the maximum number of queue messages, in millions | | Instance Type (WorkerNodeInstanceType) | m4.large | The EC2 instance type for the PubSub+ event broker primary and backup instances in Availability Zones 1 and 2. The m series are recommended for production use.
Ensure adequate CPU and Memory resources are available to support the selected broker system scaling parameters. For requirements, check the [Solace documentation](//docs.solace.com/Configuring-and-Managing/SW-Broker-Specific-Config/System-Scaling-Parameters.htm). | -| Persistent Storage (WorkerNodeStorage) | 0 | Amazon event broker storage allocated for each block device, in GiBs. The Quick Start supports up to 640 GiB per device. For sizing requirements, check the [Solace documentation](//docs.solace.com/Configuring-and-Managing/SW-Broker-Specific-Config/System-Scaling-Parameters.htm). The default value of 0 (zero) indicates ephemeral storage only. A non-zero value will cause a new Provisioned IOPS SSD (io1) disk to be created for message-spool. This disk will not be deleted on stack termination. | +| Persistent Storage (WorkerNodeStorage) | 0 | Amazon event broker storage allocated for each block device, in GiBs. The Quick Start supports up to 640 GiB per device. For sizing requirements, check the [Solace documentation](//docs.solace.com/Configuring-and-Managing/SW-Broker-Specific-Config/System-Scaling-Parameters.htm). The default value of 0 (zero) indicates ephemeral storage only. A non-zero value will cause a new disk to be created for message-spool. This disk will not be deleted on stack termination. | +| Persistent Storage Type (WorkerNodeStorageType) | gp2 | Storage volume type provided by Amazon EBS if non-zero Persistent Storage has been specified. "io1" is recommended for Production environments (better performance, more expensive) and is required for large storage size | | Instance Type (MonitorNodeInstanceType) | t2.small | The EC2 instance type for the PubSub+ event broker monitor instance in Availability Zone 3 (or Availability Zone 2, if you’re using only two zones). | | Container logging format (ContainerLoggingFormat) | graylog | The format of the logs sent by the event broker to the CloudWatch service (see [documentation](https://docs.solace.com/Configuring-and-Managing/SW-Broker-Specific-Config/Docker-Tasks/Configuring-VMR-Container-Logging.htm?Highlight=logging#Config-Out-Form ) for details) | | **Network Configuration** | | | diff --git a/scripts/install-solace.sh b/scripts/install-solace.sh index 4dcedb5..d0a4a57 100644 --- a/scripts/install-solace.sh +++ b/scripts/install-solace.sh @@ -506,7 +506,7 @@ if [ "${is_primary}" = "true" ]; then -q "" echo "`date` INFO: Initiating config-sync for default vpn" /tmp/semp_query.sh -n admin -p ${admin_password} -u http://localhost:8080/SEMP \ - -q "default" + -q "*" # Wait for config-sync results count=0 @@ -534,7 +534,7 @@ if [ "${is_primary}" = "true" ]; then /tmp/semp_query.sh -n admin -p ${admin_password} -u http://localhost:8080/SEMP \ -q "" /tmp/semp_query.sh -n admin -p ${admin_password} -u http://localhost:8080/SEMP \ - -q "default" + -q "*" fi sleep ${pause} @@ -545,25 +545,6 @@ if [ "${is_primary}" = "true" ]; then exit 1 fi - # Poll the broker Message-Spool - count=0 - echo "`date` INFO: Wait for the broker message-spool service to be guaranteed-active" - while [ ${count} -lt ${loop_guard} ]; do - health_result=`curl -s -o /dev/null -w "%{http_code}" http://localhost:5550/health-check/guaranteed-active` - run_time=$((${count} * ${pause})) - if [ "${health_result}" = "200" ]; then - echo "`date` INFO: broker message-spool is guaranteed-active, after ${run_time} seconds" - break - fi - ((count++)) - echo "`date` INFO: Waited ${run_time} seconds, broker message-spool not yet guaranteed-active. State: ${health_result}" - sleep ${pause} - done - if [ ${count} -eq ${loop_guard} ]; then - echo "`date` ERROR: broker message-spool never came guaranteed-active" | tee /dev/stderr - exit 1 - fi - fi if [ ${count} -eq ${loop_guard} ]; then diff --git a/submodules/quickstart-aws-vpc b/submodules/quickstart-aws-vpc index dd78cab..b7aefd0 160000 --- a/submodules/quickstart-aws-vpc +++ b/submodules/quickstart-aws-vpc @@ -1 +1 @@ -Subproject commit dd78caba92ec7e31cc2d2b7b623ee53626db986a +Subproject commit b7aefd089e944d77cdc2b083886cdc498d2a6ee4 diff --git a/submodules/quickstart-linux-bastion b/submodules/quickstart-linux-bastion index 5598789..645f03e 160000 --- a/submodules/quickstart-linux-bastion +++ b/submodules/quickstart-linux-bastion @@ -1 +1 @@ -Subproject commit 559878955b9f97873a0b2c99aa4c3619f1cb35c1 +Subproject commit 645f03e28125e145b243f2b6cd21e9ee3b429c98 diff --git a/templates/nodecreate.template b/templates/nodecreate.template index 9277210..dca1ff6 100644 --- a/templates/nodecreate.template +++ b/templates/nodecreate.template @@ -99,6 +99,14 @@ Parameters: - '320' - '640' Type: Number + PersistentStorageType: + Default: 'gp2' + Description: Storage volume type provided by Amazon EBS. "io1" is recommended for Production environments (better performance, more expensive) + and is required for large storage size. + AllowedValues: + - 'gp2' + - 'io1' + Type: String QSS3BucketName: AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ ConstraintDescription: Quick Start bucket name can include numbers, lowercase @@ -184,6 +192,9 @@ Conditions: EphemeralStorage: !Equals - !Ref 'PersistentStorage' - '0' + IOStorageType: !Equals + - !Ref 'PersistentStorageType' + - 'io1' UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] NonHA: !Equals [!Ref NodeDesignation, 'event-broker-singlenode'] Resources: @@ -464,11 +475,14 @@ Resources: Ebs: VolumeSize: !Ref 'PersistentStorage' DeleteOnTermination: 'False' - VolumeType: io1 - Iops: !FindInMap - - IOPsMap - - !Ref 'PersistentStorage' - - IOPs + VolumeType: !Ref 'PersistentStorageType' + Iops: !If + - IOStorageType + - !FindInMap + - IOPsMap + - !Ref 'PersistentStorage' + - IOPs + - !Ref 'AWS::NoValue' ImageId: !FindInMap - AWSAMIRegionMap - !Ref 'AWS::Region' diff --git a/templates/solace-master.template b/templates/solace-master.template index b7e676a..0176431 100644 --- a/templates/solace-master.template +++ b/templates/solace-master.template @@ -16,6 +16,7 @@ Metadata: - MaxQueueMessages - WorkerNodeInstanceType - WorkerNodeStorage + - WorkerNodeStorageType - MonitorNodeInstanceType - ContainerLoggingFormat - Label: @@ -58,6 +59,8 @@ Metadata: default: Message Routing Node Instance Type WorkerNodeStorage: default: Persistent Storage + WorkerNodeStorageType: + default: Persistent Storage Type MonitorNodeInstanceType: default: Monitor Node Instance Type KeyPairName: @@ -174,6 +177,14 @@ Parameters: - '320' - '640' Type: Number + WorkerNodeStorageType: + Default: 'gp2' + Description: Storage volume type provided by Amazon EBS. "io1" is recommended for Production environments (better performance, more expensive) + and is required for large storage size. + AllowedValues: + - 'gp2' + - 'io1' + Type: String KeyPairName: Description: Name of an existing EC2 key pair within the AWS region; all instances will launch with this key pair @@ -244,7 +255,7 @@ Resources: Properties: TemplateURL: !Sub - - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template' + - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template.yaml' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: @@ -252,11 +263,9 @@ Resources: - ',' - !Ref 'AvailabilityZones' CreatePrivateSubnets: !Ref 'CreatePrivateSubnets' - KeyPairName: !Ref 'KeyPairName' NumberOfAZs: !Ref 'NumberOfAZs' BastionHostRole: Type: 'AWS::IAM::Role' - Condition: UsePrivateSubnets Properties: Path: / AssumeRolePolicyDocument: @@ -326,6 +335,7 @@ Resources: MaxQueueMessages: !Ref 'MaxQueueMessages' WorkerNodeInstanceType: !Ref 'WorkerNodeInstanceType' WorkerNodeStorage: !Ref 'WorkerNodeStorage' + WorkerNodeStorageType: !Ref 'WorkerNodeStorageType' MonitorNodeInstanceType: !Ref 'MonitorNodeInstanceType' KeyPairName: !Ref 'KeyPairName' QSS3BucketName: !Ref 'QSS3BucketName' diff --git a/templates/solace.template b/templates/solace.template index 02203e5..7a52fb7 100644 --- a/templates/solace.template +++ b/templates/solace.template @@ -13,6 +13,7 @@ Metadata: - MaxQueueMessages - WorkerNodeInstanceType - WorkerNodeStorage + - WorkerNodeStorageType - MonitorNodeInstanceType - ContainerLoggingFormat - Label: @@ -55,6 +56,8 @@ Metadata: default: Message Routing Node Instance Type WorkerNodeStorage: default: Persistent Storage + WorkerNodeStorageType: + default: Persistent Storage Type MonitorNodeInstanceType: default: Monitor Node Instance Type KeyPairName: @@ -172,6 +175,14 @@ Parameters: - '320' - '640' Type: Number + WorkerNodeStorageType: + Default: 'gp2' + Description: Storage volume type provided by Amazon EBS. "io1" is recommended for Production environments (better performance, more expensive) + and is required for large storage size. + AllowedValues: + - 'gp2' + - 'io1' + Type: String KeyPairName: Description: Name of an existing EC2 key pair within the AWS region; all instances will launch with this key pair @@ -280,6 +291,7 @@ Resources: - !Ref 'RemoteMgmtSecurityGroup' ParentStackName: !Ref 'AWS::StackName' PersistentStorage: !Ref 'WorkerNodeStorage' + PersistentStorageType: !Ref 'WorkerNodeStorageType' QSS3BucketName: !Ref 'QSS3BucketName' QSS3BucketRegion: !Ref 'QSS3BucketRegion' QSS3KeyPrefix: !Ref 'QSS3KeyPrefix' @@ -316,6 +328,7 @@ Resources: - !Ref 'RemoteMgmtSecurityGroup' ParentStackName: !Ref 'AWS::StackName' PersistentStorage: !Ref 'WorkerNodeStorage' + PersistentStorageType: !Ref 'WorkerNodeStorageType' QSS3BucketName: !Ref 'QSS3BucketName' QSS3BucketRegion: !Ref 'QSS3BucketRegion' QSS3KeyPrefix: !Ref 'QSS3KeyPrefix' @@ -451,7 +464,7 @@ Resources: - IpProtocol: tcp FromPort: 5550 ToPort: 5550 - CidrIp: !Ref 'RemoteAccessCIDR' + CidrIp: '0.0.0.0/0' - IpProtocol: tcp FromPort: 55555 ToPort: 55555