Remove haproxy and syslog-sidecar

With the introduction of a refdb and the possibility to do HTTP
healthchecks for targets behind a NLB, haproxy is no longer
required.

Remove haproxy and, alongside it, the syslog-sidecar components.

Rely solely on AWS resources to do load balancing,
removing unneeded moving parts and offloading maintenance of
resources to AWS themselves.

Bug: Issue 15158
Change-Id: I88ecbd322b5016e1434a9f1488a2fa55fba40b91
diff --git a/Docker.md b/Docker.md
index 98d81dc..f747330 100644
--- a/Docker.md
+++ b/Docker.md
@@ -22,15 +22,13 @@
 publishing a new docker image will _not_ make it available to ECS, so it cannot be used for upgrading running instances.
 
 Note that you will need to _cd_ to the recipe directory before running any of the following and that the relevant image
-needs to exist for that specific recipe (for example you can't publish HAProxy from the single-primary recipe).
+needs to exist for that specific recipe.
 
 * Gerrit: `make gerrit-publish`
 * SSH Agent: `make git-ssh-publish`
 * Gerrit Daemon: `make git-daemon-publish`
 * Grafana: `make grafana-publish`
 * Prometheus: `make prometheus-publish`
-* HAProxy: `make haproxy-publish`
-* Syslog sidecar: `make syslog-sidecar-publish`
 
 
 
diff --git a/Prerequisites.md b/Prerequisites.md
index 0913f1d..b7327b2 100644
--- a/Prerequisites.md
+++ b/Prerequisites.md
@@ -13,8 +13,6 @@
 aws ecr create-repository --repository-name aws-gerrit/gerrit
 aws ecr create-repository --repository-name aws-gerrit/git-ssh
 aws ecr create-repository --repository-name aws-gerrit/git-daemon
-aws ecr create-repository --repository-name aws-gerrit/haproxy
-aws ecr create-repository --repository-name aws-gerrit/syslog-sidecar
 aws ecr create-repository --repository-name aws-gerrit/prometheus
 aws ecr create-repository --repository-name aws-gerrit/grafana
 aws ecr create-repository --repository-name aws-gerrit/git-gc
diff --git a/common.env b/common.env
index 225f182..09181cc 100644
--- a/common.env
+++ b/common.env
@@ -18,13 +18,9 @@
 
 # Image directories
 IMAGE_DIR:=$(ROOT_DIR)/gerrit
-HAPROXY_IMAGE_DIR=$(ROOT_DIR)/dual-primary/haproxy
-SYSLOG_IMAGE_DIR=$(ROOT_DIR)/dual-primary/syslog-sidecar
 
 # Image SHA1 versions
 HEAD_SHA1=$(shell find $(IMAGE_DIR) -type f -exec cat {} \; | shasum | cut -c 1-20)
-HAPROXY_HEAD_SHA1=$(shell find $(HAPROXY_IMAGE_DIR) -type f -exec cat {} \; | shasum | cut -c 1-20)
-SYSLOG_HEAD_SHA1=$(shell find $(SYSLOG_IMAGE_DIR) -type f -exec cat {} \; | shasum | cut -c 1-20)
 
 IMAGE_TAG=$(GERRIT_VERSION).$(GERRIT_PATCH)-$(HEAD_SHA1)
 
diff --git a/dual-primary/Makefile b/dual-primary/Makefile
index c61e8d0..56fdaee 100644
--- a/dual-primary/Makefile
+++ b/dual-primary/Makefile
@@ -8,7 +8,6 @@
 SERVICE_REPLICA_TEMPLATE:=cf-service-replica.yml
 DNS_ROUTING_TEMPLATE:=cf-dns-route.yml
 CLOUDWATCH_DASHBOARD_TEMPLATE:=cf-dashboard.yml
-LOAD_BALANCER_TEMPLATE:=cf-service-lb.yml
 SERVICE_REPLICATION_TEMPLATE:=cf-service-replication.yml
 AWS_FC_COMMAND=export AWS_PAGER=;aws cloudformation
 GIT_GC_SOURCE_PATH=/mnt/efs/gerrit-shared/git
@@ -27,8 +26,7 @@
 				cluster cluster-keys service-primary-1 service-primary-2 service-replica dns-routing dashboard delete-dashboard\
 				wait-for-cluster-creation wait-for-service-primary-1-creation wait-for-service-primary-2-creation wait-for-service-replica-creation wait-for-dns-routing-creation wait-for-dashboard-creation \
 				wait-for-cluster-deletion wait-for-service-primary-1-deletion wait-for-service-primary-2-deletion wait-for-service-replica-deletion wait-for-dns-routing-deletion wait-for-dashboard-deletion \
-				service-lb wait-for-service-lb-deletion wait-for-service-lb-creation \
-				gerrit-build gerrit-publish haproxy-publish syslog-sidecar-publish
+				gerrit-build gerrit-publish
 
 ifeq ($(REPLICATION_SERVICE_ENABLED),true)
 optional_replication_targets_creation=service-replication wait-for-service-replication-creation
@@ -42,14 +40,13 @@
 
 create-all: upload-common-templates \
 						git-daemon-publish git-ssh-publish \
-						gerrit-publish haproxy-publish syslog-sidecar-publish \
+						gerrit-publish \
 						cluster wait-for-cluster-creation \
 						$(optional_replication_targets_creation) \
 						service-replica service-primary-1 \
 						wait-for-service-primary-1-creation wait-for-service-replica-creation \
 						service-primary-2 wait-for-service-primary-2-creation \
 						$(optional_dashboard_targets_creation) \
-						service-lb wait-for-service-lb-creation \
 						$(optional_git_gc_targets_creation) \
 						dns-routing wait-for-dns-routing-creation
 
@@ -71,12 +68,6 @@
 ifdef PRIMARY_FILESYSTEM_ID
 		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=PrimaryFileSystemID,ParameterValue=$(PRIMARY_FILESYSTEM_ID))
 endif
-ifdef HA_PROXY_MAX_COUNT
-		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=HAProxyMaxCount,ParameterValue=$(HA_PROXY_MAX_COUNT))
-endif
-ifdef HA_PROXY_DESIRED_COUNT
-		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=HAProxyDesiredCount,ParameterValue=$(HA_PROXY_DESIRED_COUNT))
-endif
 ifdef PRIMARY_MAX_COUNT
 		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=PrimaryMaxCount,ParameterValue=$(PRIMARY_MAX_COUNT))
 endif
@@ -146,7 +137,7 @@
 		ParameterKey=GerritKeyPrefix,ParameterValue=$(GERRIT_KEY_PREFIX)\
 		ParameterKey=DockerImage,ParameterValue=aws-gerrit/gerrit:$(IMAGE_TAG) \
 		ParameterKey=PeerSubdomain,ParameterValue=$(PRIMARY2_SUBDOMAIN) \
-		ParameterKey=LBSubdomain,ParameterValue=$(LB_SUBDOMAIN) \
+		ParameterKey=PrimariesGerritSubdomain,ParameterValue=$(PRIMARIES_GERRIT_SUBDOMAIN) \
 		ParameterKey=GerritRAM,ParameterValue=$(GERRIT_RAM) \
 		ParameterKey=GerritCPU,ParameterValue=$(GERRIT_CPU) \
 		ParameterKey=GerritHeapLimit,ParameterValue=$(GERRIT_HEAP_LIMIT) \
@@ -204,7 +195,7 @@
 		ParameterKey=GerritKeyPrefix,ParameterValue=$(GERRIT_KEY_PREFIX)\
 		ParameterKey=DockerImage,ParameterValue=aws-gerrit/gerrit:$(IMAGE_TAG) \
 		ParameterKey=PeerSubdomain,ParameterValue=$(PRIMARY1_SUBDOMAIN) \
-		ParameterKey=LBSubdomain,ParameterValue=$(LB_SUBDOMAIN) \
+		ParameterKey=PrimariesGerritSubdomain,ParameterValue=$(PRIMARIES_GERRIT_SUBDOMAIN) \
 		ParameterKey=ReindexAtSartup,ParameterValue=true \
 		ParameterKey=GerritRAM,ParameterValue=$(GERRIT_RAM) \
 		ParameterKey=GerritCPU,ParameterValue=$(GERRIT_CPU) \
@@ -281,33 +272,6 @@
 		$(GERRIT_OPTIONAL_PARAMS_REPLICA_AUTO_SCALING_CAPACITY) \
 		$(GERRIT_OPTIONAL_PARAMS_REPLICA_AUTO_SCALING_POLICY)
 
-service-lb:
-ifdef LOAD_BALANCER_SCHEME
-		$(eval SERVICE_OPTIONAL_PARAMS := $(SERVICE_OPTIONAL_PARAMS) ParameterKey=LoadBalancerScheme,ParameterValue=$(LOAD_BALANCER_SCHEME))
-endif
-ifdef HA_PROXY_DESIRED_COUNT
-		$(eval SERVICE_OPTIONAL_PARAMS := $(SERVICE_OPTIONAL_PARAMS) ParameterKey=DesiredCount,ParameterValue=$(HA_PROXY_DESIRED_COUNT))
-endif
-
-	$(AWS_FC_COMMAND) create-stack \
-		--stack-name $(LOAD_BALANCER_STACK_NAME) \
-		--capabilities CAPABILITY_IAM  \
-		--template-body file://`pwd`/$(LOAD_BALANCER_TEMPLATE) \
-		--region $(AWS_REGION) \
-		--parameters \
-		ParameterKey=ClusterStackName,ParameterValue=$(CLUSTER_STACK_NAME) \
-		ParameterKey=Primary1ServiceStackName,ParameterValue=$(SERVICE_PRIMARY1_STACK_NAME) \
-		ParameterKey=Primary2ServiceStackName,ParameterValue=$(SERVICE_PRIMARY2_STACK_NAME) \
-		ParameterKey=HostedZoneName,ParameterValue=$(HOSTED_ZONE_NAME) \
-		ParameterKey=DockerRegistryUrl,ParameterValue=$(DOCKER_REGISTRY_URI) \
-		ParameterKey=GerritKeyPrefix,ParameterValue=$(GERRIT_KEY_PREFIX)\
-		ParameterKey=CertificateArn,ParameterValue=$(SSL_CERTIFICATE_ARN) \
-		ParameterKey=Subdomain,ParameterValue=$(LB_SUBDOMAIN) \
-		ParameterKey=TemplateBucketName,ParameterValue=$(TEMPLATE_BUCKET_NAME) \
-		ParameterKey=HAProxyDockerImage,ParameterValue=aws-gerrit/haproxy:$(HAPROXY_HEAD_SHA1) \
-		ParameterKey=SidecarDockerImage,ParameterValue=aws-gerrit/syslog-sidecar:$(SYSLOG_HEAD_SHA1) \
-		$(SERVICE_OPTIONAL_PARAMS)
-
 dns-routing:
 	$(AWS_FC_COMMAND) create-stack \
 		--stack-name $(DNS_ROUTING_STACK_NAME) \
@@ -317,7 +281,6 @@
 		--parameters \
 		ParameterKey=Primary1ServiceStackName,ParameterValue=$(SERVICE_PRIMARY1_STACK_NAME) \
 		ParameterKey=Primary2ServiceStackName,ParameterValue=$(SERVICE_PRIMARY2_STACK_NAME) \
-		ParameterKey=LBServiceStackName,ParameterValue=$(LOAD_BALANCER_STACK_NAME) \
 		ParameterKey=ClusterStackName,ParameterValue=$(CLUSTER_STACK_NAME) \
 		ParameterKey=PrimariesGerritHostedZoneName,ParameterValue=$(HOSTED_ZONE_NAME) \
 		ParameterKey=PrimariesGerritSubdomain,ParameterValue=$(PRIMARIES_GERRIT_SUBDOMAIN)
@@ -384,13 +347,6 @@
 	--region $(AWS_REGION)
 	@echo "*** Service stack '$(SERVICE_REPLICA_STACK_NAME)' created"
 
-wait-for-service-lb-creation:
-	@echo "*** Wait for service lb stack '$(LOAD_BALANCER_STACK_NAME)' creation"
-	$(AWS_FC_COMMAND) wait stack-create-complete \
-	--stack-name $(LOAD_BALANCER_STACK_NAME) \
-	--region $(AWS_REGION)
-	@echo "*** Service stack '$(LOAD_BALANCER_STACK_NAME)' created"
-
 wait-for-dns-routing-creation:
 	@echo "*** Wait for DNS routing stack '$(DNS_ROUTING_STACK_NAME)' creation"
 	$(AWS_FC_COMMAND) wait stack-create-complete \
@@ -433,13 +389,6 @@
 	--region $(AWS_REGION)
 	@echo "*** Service stack replica '$(SERVICE_REPLICA_STACK_NAME)' deleted"
 
-wait-for-service-lb-deletion:
-	@echo "*** Wait for service lb stack '$(LOAD_BALANCER_STACK_NAME)' deletion"
-	$(AWS_FC_COMMAND) wait stack-delete-complete \
-	--stack-name $(LOAD_BALANCER_STACK_NAME) \
-	--region $(AWS_REGION)
-	@echo "*** Service stack '$(LOAD_BALANCER_STACK_NAME)' deleted"
-
 wait-for-dns-routing-deletion:
 	@echo "*** Wait for DNS routing stack '$(DNS_ROUTING_STACK_NAME)' deletion"
 	$(AWS_FC_COMMAND) wait stack-delete-complete \
@@ -481,11 +430,6 @@
 	--stack-name $(SERVICE_REPLICA_STACK_NAME) \
 	--region $(AWS_REGION)
 
-delete-service-lb:
-	$(AWS_FC_COMMAND) delete-stack \
-	--stack-name $(LOAD_BALANCER_STACK_NAME) \
-	--region $(AWS_REGION)
-
 delete-service-replication:
 	$(AWS_FC_COMMAND) delete-stack \
 	--stack-name $(SERVICE_REPLICATION_STACK_NAME) \
@@ -502,7 +446,6 @@
 	--region $(AWS_REGION)
 
 delete-all: delete-dns-routing wait-for-dns-routing-deletion \
-						delete-service-lb wait-for-service-lb-deletion \
 						delete-service-primary-1 delete-service-primary-2 delete-service-replica \
 						wait-for-service-primary-1-deletion wait-for-service-primary-2-deletion wait-for-service-replica-deletion \
 						$(optional_dashboard_targets_deletion) \
@@ -536,12 +479,6 @@
 	$(MAKE) -C ../gerrit gerrit-publish RECIPE=dual-primary PLUGINS="$(HA_SITE_PLUGINS)" PLUGINS_LIBS_LINKS="$(HA_SITE_PLUGINS_LIBS_LINKS)"
 endif
 
-haproxy-publish:
-	$(MAKE) -C haproxy haproxy-publish
-
-syslog-sidecar-publish:
-	$(MAKE) -C syslog-sidecar syslog-sidecar-publish
-
 git-daemon-publish:
 	$(MAKE) -C ../primary-replica/git-daemon git-daemon-publish
 
diff --git a/dual-primary/README.md b/dual-primary/README.md
index 1155491..23bc084 100644
--- a/dual-primary/README.md
+++ b/dual-primary/README.md
@@ -10,7 +10,6 @@
 * `cf-service-primary`: define the service stack running the gerrit primary
 * `cf-dns-route`: define the DNS routing for the service
 * `cf-service-replica`: define the service stack running the gerrit replica
-* `cf-service-lb`: define the LBs in front of gerrit primaries (this includes haproxy as well as NLB)
 * `cf-dashboard`: define the CloudWatch dashboard for the services
 
 When the recipe enables the replication_service (see [docs](#replication-service))
@@ -165,7 +164,6 @@
 * `PRIMARY1_SUBDOMAIN`: Optional. Name of the primary 1 sub domain. `gerrit-primary-1-demo` by default.
 * `PRIMARY2_SUBDOMAIN`: Optional. Name of the primary 2 sub domain. `gerrit-primary-2-demo` by default.
 * `REPLICA_SUBDOMAIN`: Mandatory. The subdomain of the Gerrit replica. For example: `<AWS_PREFIX>-replica`
-* `LB_SUBDOMAIN`: Mandatory. The subdomain of the Gerrit load balancer. For example: `<AWS_PREFIX>-dual-primary`
 * `PRIMARIES_GERRIT_SUBDOMAIN`: Mandatory. The subdomain of the lb serving traffic to both primary gerrit instances.
    For example: `<AWS_PREFIX>-primaries`
 * `PRIMARY_FILESYSTEM_THROUGHPUT_MODE`: Optional. The throughput mode for the primary file system to be created.
@@ -180,17 +178,6 @@
 * `GERRIT_PRIMARY2_INSTANCE_ID`: Optional. Identifier for the Gerrit primary2 instance.
 "gerrit-dual-primary-PRIMARY2" by default.
 
-* `HA_PROXY_DESIRED_COUNT`: Optional. Desired number of haproxy services.
-"2" by default. Minimum: "2".
-
-*Note* ha-proxies are running on ec2 instances with a ratio of 1 to 1: each
-ec2 node hosts one and only one ha-proxy. By increasing the number of desired
-ha-proxies then, the size of the autoscaling group hosting them also increases
-accordingly.
-
-* `HA_PROXY_MAX_COUNT`: Optional. Maximum number of EC2 instances in the haproxy autoscaling group.
-"2" by default. Minimum: "2".
-
 * `PRIMARY_MAX_COUNT`: Optional. Maximum number of EC2 instances in the primary autoscaling group.
 "2" by default. Minimum: "2".
 
diff --git a/dual-primary/cf-cluster.yml b/dual-primary/cf-cluster.yml
index 2560cd2..433a24b 100644
--- a/dual-primary/cf-cluster.yml
+++ b/dual-primary/cf-cluster.yml
@@ -77,16 +77,6 @@
     Description: Gerrit primary filesystem throughput, measured in MiB/s. Valid values are 1-1024.
     Type: Number
     Default: 256
-  HAProxyMaxCount:
-    Description: The maximum number of EC2 instances in the haproxy autoscaling group
-    Type: Number
-    Default: 2
-  HAProxyDesiredCount:
-    Description: The desired number of haproxy instances
-    ConstraintDescription: number of haproxy must be at least 2
-    Type: Number
-    MinValue: 2
-    Default: 2
   PrimaryMaxCount:
     Description: The maximum number of EC2 instances in the primary autoscaling group
     ConstraintDescription: number of haproxy must be at least 2
@@ -276,48 +266,6 @@
 
           /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ReplicaECSAutoScalingGroup --region ${AWS::Region}
 
-  HAProxyECSAutoScalingGroup:
-    Type: AWS::AutoScaling::AutoScalingGroup
-    Properties:
-      VPCZoneIdentifier:
-        - !If [NetworkStackNeeded, !GetAtt ECSTaskNetworkStack.Outputs.PublicSubnetOneRef, !Ref Subnet1IdProp]
-        - !If [NetworkStackNeeded, !GetAtt ECSTaskNetworkStack.Outputs.PublicSubnetTwoRef, !Ref Subnet2IdProp]
-      LaunchConfigurationName: !Ref 'HAProxyLaunchConfiguration'
-      MinSize: '2'
-      MaxSize: !Ref HAProxyMaxCount
-      DesiredCapacity: !Ref HAProxyDesiredCount
-    CreationPolicy:
-      ResourceSignal:
-        Timeout: PT15M
-    UpdatePolicy:
-      AutoScalingReplacingUpdate:
-        WillReplace: 'true'
-
-  HAProxyLaunchConfiguration:
-    Type: AWS::AutoScaling::LaunchConfiguration
-    Properties:
-      ImageId: !Ref 'ECSAMI'
-      SecurityGroups: [!Ref 'EcsHostSecurityGroup']
-      InstanceType: !Ref 'InstanceType'
-      IamInstanceProfile: !Ref 'EC2InstanceProfile'
-      KeyName: !Ref ECSKeyName
-      UserData:
-        Fn::Base64: !Sub |
-          #!/bin/bash -xe
-          echo ECS_CLUSTER=${AWS::StackName}-ECSCluster >> /etc/ecs/ecs.config
-          echo ECS_INSTANCE_ATTRIBUTES={\"target_group\":\"haproxy\"} >> /etc/ecs/ecs.config
-
-          # Make sure latest version of the helper scripts are installed as per recommendation:
-          # https://github.com/awsdocs/aws-cloudformation-user-guide/blob/master/doc_source/cfn-helper-scripts-reference.md#using-the-latest-version
-          yum install -y aws-cfn-bootstrap wget
-
-          # Install the CloudWatch Logs agent
-          wget https://s3.amazonaws.com/amazoncloudwatch-agent/centos/amd64/latest/amazon-cloudwatch-agent.rpm
-          rpm -U ./amazon-cloudwatch-agent.rpm
-          /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s
-
-          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource HAProxyECSAutoScalingGroup --region ${AWS::Region}
-
   PrimariesGerritLoadBalancer:
     Type: AWS::ElasticLoadBalancingV2::LoadBalancer
     Properties:
diff --git a/dual-primary/cf-dns-route.yml b/dual-primary/cf-dns-route.yml
index 1755fbd..156cbc5 100644
--- a/dual-primary/cf-dns-route.yml
+++ b/dual-primary/cf-dns-route.yml
@@ -13,10 +13,6 @@
       Description: Stack name of the ECS Primary Gerrit service
       Type: String
       Default: gerrit-service-primary-2
-  LBServiceStackName:
-      Description: Stack name of the ECS LB service
-      Type: String
-      Default: gerrit-service
   PrimariesGerritSubdomain:
     Description: The subdomain of the load balancer serving requests to primary gerrit instances
     Type: String
@@ -71,29 +67,6 @@
             Fn::ImportValue:
               !Join [':', [!Ref 'Primary2ServiceStackName', 'CanonicalHostedZoneID']]
           EvaluateTargetHealth: False
-  LBDnsRecord:
-      Type: AWS::Route53::RecordSet
-      Properties:
-        Name:
-          !Join
-            - '.'
-            - - Fn::ImportValue: !Join [':', [!Ref 'LBServiceStackName', 'Subdomain']]
-              - Fn::ImportValue: !Join [':', [!Ref 'LBServiceStackName', 'HostedZoneName']]
-        HostedZoneName:
-          !Join
-            - ''
-            - - Fn::ImportValue: !Join [':', [!Ref 'LBServiceStackName', 'HostedZoneName']]
-              - '.'
-        Comment: DNS name for Gerrit LB.
-        Type: A
-        AliasTarget:
-          DNSName:
-            Fn::ImportValue:
-              !Join [':', [!Ref 'LBServiceStackName', 'PublicLoadBalancerDNSName']]
-          HostedZoneId:
-            Fn::ImportValue:
-              !Join [':', [!Ref 'LBServiceStackName', 'CanonicalHostedZoneID']]
-          EvaluateTargetHealth: False
 
   PrimariesGerritDnsRecord:
     Type: AWS::Route53::RecordSet
diff --git a/dual-primary/cf-service-lb.yml b/dual-primary/cf-service-lb.yml
deleted file mode 100644
index 334f1ca..0000000
--- a/dual-primary/cf-service-lb.yml
+++ /dev/null
@@ -1,262 +0,0 @@
-AWSTemplateFormatVersion: '2010-09-09'
-Description: Deploy a service into an ECS cluster behind a public load balancer.
-Parameters:
-  LBServiceName:
-    Type: String
-    Default: gerrit-load-balancer
-  ClusterStackName:
-      Description: Stack name of the ECS cluster to deploy the services
-      Type: String
-      Default: gerrit-cluster
-  TemplateBucketName:
-    Description: S3 bucket containing cloudformation templates
-    Type: String
-  EnvironmentName:
-      Description: An environment name used to build the log stream names
-      Type: String
-      Default: test
-  HAProxyDockerImage:
-        Description: HAProxy Docker image
-        Type: String
-        Default: aws-gerrit/haproxy:latest
-  SidecarDockerImage:
-        Description: Syslog sidecar Docker image
-        Type: String
-        Default: aws-gerrit/syslog-sidecar:latest
-  DockerRegistryUrl:
-        Description: Docker registry URL
-        Type: String
-  DesiredCount:
-        Description: How many instances of this task should we run across our cluster?
-        Type: Number
-        MinValue: 2
-        Default: 2
-        ConstraintDescription: number of haproxy must be at least 2
-  HTTPGerritPort:
-        Description: Gerrit HTTP port
-        Type: Number
-        Default: 8080
-  SSHGerritPort:
-        Description: Gerrit SSH port
-        Type: Number
-        Default: 29418
-  HTTPContainerPort:
-        Description: Gerrit HTTP port
-        Type: Number
-        Default: 80
-  HTTPSHostPort:
-        Description: Gerrit HTTPS port
-        Type: Number
-        Default: 443
-  HTTPHostPort:
-        Description: HAProxy HTTP port
-        Type: Number
-        Default: 80
-  CertificateArn:
-        Description: SSL Certificates ARN
-        Type: String
-  HostedZoneName:
-        Description: The route53 HostedZoneName.
-        Type: String
-  Subdomain:
-        Description: The subdomain of the Gerrit cluster
-        Type: String
-        Default: gerrit-dual-primary
-  LoadBalancerScheme:
-        Description: Load Balancer schema, The nodes of an Internet-facing load balancer have public IP addresses.
-        Type: String
-        Default: internet-facing
-        AllowedValues: [internal, internet-facing]
-  GerritKeyPrefix:
-        Description: Gerrit credentials keys prefix
-        Type: String
-  Primary1ServiceStackName:
-      Description: Stack name of the ECS Primary Gerrit service
-      Type: String
-      Default: gerrit-service-primary-1
-  Primary2ServiceStackName:
-      Description: Stack name of the ECS Primary Gerrit service
-      Type: String
-      Default: gerrit-service-primary-2
-  SyslogSidecarServiceName:
-      Description: HAPRoxy Syslog Sidecar service name
-      Type: String
-      Default: gerrit-haproxy-sidecar
-  HealthCheckGracePeriodSeconds:
-      Description: HAProxy Healtcheck Grace Period
-      Type: Number
-      Default: 60
-
-Resources:
-    LBService:
-        Type: AWS::ECS::Service
-        DependsOn:
-          - HTTPListener
-          - SSHListener
-        Properties:
-            Cluster:
-              Fn::ImportValue:
-                  !Join [':', [!Ref 'ClusterStackName', 'ClusterName']]
-            DesiredCount: !Ref DesiredCount
-            TaskDefinition: !Ref TaskDefinition
-            HealthCheckGracePeriodSeconds: !Ref HealthCheckGracePeriodSeconds
-            LoadBalancers:
-                - ContainerName: !Ref LBServiceName
-                  ContainerPort: !Ref HTTPContainerPort
-                  TargetGroupArn: !Ref HTTPTargetGroup
-                - ContainerName: !Ref LBServiceName
-                  ContainerPort: !Ref SSHGerritPort
-                  TargetGroupArn: !Ref SSHTargetGroup
-
-    TaskDefinition:
-        Type: AWS::ECS::TaskDefinition
-        Properties:
-            Family: !Sub '${LBServiceName}TaskDefinition'
-            TaskRoleArn: !GetAtt ECSTaskExecutionRoleStack.Outputs.TaskExecutionRoleRef
-            ExecutionRoleArn: !GetAtt ECSTaskExecutionRoleStack.Outputs.TaskExecutionRoleRef
-            NetworkMode: bridge
-            PlacementConstraints:
-                - Expression: !Sub 'attribute:target_group == haproxy'
-                  Type: "memberOf"
-            ContainerDefinitions:
-                - Name: !Ref LBServiceName
-                  Essential: true
-                  Image: !Sub '${DockerRegistryUrl}/${HAProxyDockerImage}'
-                  Environment:
-                    - Name: GERRIT_PRIMARY_1_URL
-                      Value:
-                        Fn::ImportValue: !Join [':', [!Ref 'Primary1ServiceStackName', 'PublicLoadBalancerDNSName']]
-                    - Name: GERRIT_PRIMARY_2_URL
-                      Value:
-                        Fn::ImportValue: !Join [':', [!Ref 'Primary2ServiceStackName', 'PublicLoadBalancerDNSName']]
-                    - Name: SYSLOG_SIDECAR
-                      Value: !Ref SyslogSidecarServiceName
-                  Cpu: 1024
-                  Memory: 2048
-                  PortMappings:
-                    - ContainerPort: !Ref HTTPContainerPort
-                      HostPort: !Ref HTTPHostPort
-                      Protocol: tcp
-                    - ContainerPort: !Ref SSHGerritPort
-                      HostPort: !Ref SSHGerritPort
-                      Protocol: tcp
-                  Links:
-                    - !Ref SyslogSidecarServiceName
-                  LogConfiguration:
-                    LogDriver: awslogs
-                    Options:
-                        awslogs-group: !Ref ClusterStackName
-                        awslogs-region: !Ref AWS::Region
-                        awslogs-stream-prefix: !Ref EnvironmentName
-                - Name: !Ref SyslogSidecarServiceName
-                  Essential: true
-                  Image: !Sub '${DockerRegistryUrl}/${SidecarDockerImage}'
-                  Cpu: 256
-                  Memory: 512
-                  LogConfiguration:
-                    LogDriver: awslogs
-                    Options:
-                        awslogs-group: !Ref ClusterStackName
-                        awslogs-region: !Ref AWS::Region
-                        awslogs-stream-prefix: !Ref EnvironmentName
-
-    ECSTaskExecutionRoleStack:
-      Type: AWS::CloudFormation::Stack
-      Properties:
-        TemplateURL: !Join [ '', ['https://', !Ref TemplateBucketName, '.s3.amazonaws.com/cf-gerrit-task-execution-role.yml'] ]
-        TimeoutInMinutes: '5'
-
-    LoadBalancer:
-        Type: AWS::ElasticLoadBalancingV2::LoadBalancer
-        Properties:
-            Type: network
-            Scheme: !Ref 'LoadBalancerScheme'
-            LoadBalancerAttributes:
-              - Key: 'load_balancing.cross_zone.enabled'
-                Value: true
-            Subnets:
-              - Fn::ImportValue:
-                  !Join [':', [!Ref 'ClusterStackName', 'PublicSubnetOne']]
-              - Fn::ImportValue:
-                  !Join [':', [!Ref 'ClusterStackName', 'PublicSubnetTwo']]
-            Tags:
-                - Key: Name
-                  Value: !Join ['-', [!Ref 'EnvironmentName', !Ref 'LBServiceName', 'alb']]
-
-    HTTPTargetGroup:
-        Type: AWS::ElasticLoadBalancingV2::TargetGroup
-        DependsOn: LoadBalancer
-        Properties:
-            VpcId:
-              Fn::ImportValue:
-                  !Join [':', [!Ref 'ClusterStackName', 'VPCId']]
-            Port: !Ref HTTPHostPort
-            Protocol: TCP
-            Name: 'haproxy-http'
-
-    HTTPListener:
-        Type: AWS::ElasticLoadBalancingV2::Listener
-        DependsOn: LoadBalancer
-        Properties:
-            Certificates:
-              - CertificateArn: !Ref CertificateArn
-            DefaultActions:
-            - Type: forward
-              TargetGroupArn: !Ref HTTPTargetGroup
-            LoadBalancerArn: !Ref LoadBalancer
-            Port: !Ref HTTPSHostPort
-            Protocol: TLS
-
-    SSHTargetGroup:
-        Type: AWS::ElasticLoadBalancingV2::TargetGroup
-        DependsOn: LoadBalancer
-        Properties:
-            VpcId:
-              Fn::ImportValue:
-                  !Join [':', [!Ref 'ClusterStackName', 'VPCId']]
-            Port: !Ref SSHGerritPort
-            Protocol: TCP
-            Name: 'haproxy-ssh'
-
-    SSHListener:
-        Type: AWS::ElasticLoadBalancingV2::Listener
-        DependsOn: LoadBalancer
-        Properties:
-            DefaultActions:
-            - Type: forward
-              TargetGroupArn: !Ref SSHTargetGroup
-            LoadBalancerArn: !Ref LoadBalancer
-            Port: !Ref SSHGerritPort
-            Protocol: TCP
-
-Outputs:
-  PublicLoadBalancerDNSName:
-    Description: The DNS name of the external load balancer
-    Value: !GetAtt 'LoadBalancer.DNSName'
-    Export:
-      Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicLoadBalancerDNSName' ] ]
-  CanonicalHostedZoneID:
-    Description: Canonical Hosted Zone ID
-    Value: !GetAtt 'LoadBalancer.CanonicalHostedZoneID'
-    Export:
-      Name: !Join [ ':', [ !Ref 'AWS::StackName', 'CanonicalHostedZoneID' ] ]
-  PublicLoadBalancerUrl:
-    Description: The url of the external load balancer
-    Value: !Join ['', ['https://', !GetAtt 'LoadBalancer.DNSName']]
-    Export:
-      Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicLoadBalancerUrl' ] ]
-  HostedZoneName:
-    Description: Route53 Hosted Zone name
-    Value: !Ref HostedZoneName
-    Export:
-      Name: !Join [ ':', [ !Ref 'AWS::StackName', 'HostedZoneName' ] ]
-  Subdomain:
-    Description: Service DNS subdomain
-    Value: !Ref Subdomain
-    Export:
-      Name: !Join [ ':', [ !Ref 'AWS::StackName', 'Subdomain' ] ]
-  CanonicalWebUrl:
-    Description: Canonical Web URL
-    Value: !Sub 'https://${Subdomain}.${HostedZoneName}'
-    Export:
-      Name: !Join [ ':', [ !Ref 'AWS::StackName', 'CanonicalWebUrl' ] ]
diff --git a/dual-primary/cf-service-primary.yml b/dual-primary/cf-service-primary.yml
index d865835..8c3384d 100644
--- a/dual-primary/cf-service-primary.yml
+++ b/dual-primary/cf-service-primary.yml
@@ -36,8 +36,8 @@
   ReplicaSubdomain:
         Description: The subdomain of the Gerrit replica
         Type: String
-  LBSubdomain:
-        Description: The subdomain of the Gerrit load balancer
+  PrimariesGerritSubdomain:
+        Description: The subdomain of the load balancer fronting both gerrit-1 and gerrit-2
         Type: String
   LoadBalancerScheme:
         Description: Load Balancer scheme, the nodes of an internet-facing load balancer have public IP addresses.
@@ -251,7 +251,7 @@
                   Image: !Sub '${DockerRegistryUrl}/${DockerImage}'
                   Environment:
                     - Name: CANONICAL_WEB_URL
-                      Value: !Sub 'https://${LBSubdomain}.${HostedZoneName}'
+                      Value: !Sub 'https://${PrimariesGerritSubdomain}.${HostedZoneName}'
                     - Name: HTTPD_LISTEN_URL
                       Value: !Sub
                         - 'proxy-https://*:${HTTPContainerPort}/'
diff --git a/dual-primary/haproxy/Dockerfile b/dual-primary/haproxy/Dockerfile
deleted file mode 100644
index d2191e8..0000000
--- a/dual-primary/haproxy/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM haproxy:1.7.14
-
-RUN apt-get update && \
-    apt-get -y install gettext-base netcat && \
-    mkdir /var/lib/haproxy && \
-    mkdir /var/run/haproxy && \
-    chown haproxy: /var/lib/haproxy /var/run/haproxy
-
-COPY haproxy.cfg.template /usr/local/etc/haproxy/
-
-COPY docker-entrypoint.sh /usr/local/bin/
diff --git a/dual-primary/haproxy/Makefile b/dual-primary/haproxy/Makefile
deleted file mode 100644
index 98d7370..0000000
--- a/dual-primary/haproxy/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-include ../../Makefile.common
-include ../setup.env
-
-IMAGE_NAME:=haproxy
-
-docker-registry-login:
-	aws ecr get-login-password --region $(AWS_REGION) \
-		| docker login --username AWS --password-stdin $(DOCKER_REGISTRY_URI)/aws-gerrit/$(IMAGE_NAME)
-
-haproxy-build:
-	docker build -t aws-gerrit/$(IMAGE_NAME):$(HAPROXY_HEAD_SHA1) .
-	docker tag aws-gerrit/$(IMAGE_NAME):$(HAPROXY_HEAD_SHA1) $(DOCKER_REGISTRY_URI)/aws-gerrit/$(IMAGE_NAME):$(HAPROXY_HEAD_SHA1)
-
-haproxy-publish: docker-registry-login haproxy-build
-	docker push $(DOCKER_REGISTRY_URI)/aws-gerrit/$(IMAGE_NAME):$(HAPROXY_HEAD_SHA1)
diff --git a/dual-primary/haproxy/docker-entrypoint.sh b/dual-primary/haproxy/docker-entrypoint.sh
deleted file mode 100755
index b379564..0000000
--- a/dual-primary/haproxy/docker-entrypoint.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-set -e
-
-# first arg is `-f` or `--some-option`
-if [ "${1#-}" != "$1" ]; then
-	set -- haproxy "$@"
-fi
-
-if [ "$1" = 'haproxy' ]; then
-	# if the user wants "haproxy", let's use "haproxy-systemd-wrapper" instead so we can have proper reloadability implemented by upstream
-	shift # "haproxy"
-	set -- "$(which haproxy-systemd-wrapper)" -p /run/haproxy.pid "$@"
-fi
-
-envsubst < /usr/local/etc/haproxy/haproxy.cfg.template > /usr/local/etc/haproxy/haproxy.cfg
-
-exec "$@"
diff --git a/dual-primary/haproxy/haproxy.cfg.template b/dual-primary/haproxy/haproxy.cfg.template
deleted file mode 100644
index 7b4c714..0000000
--- a/dual-primary/haproxy/haproxy.cfg.template
+++ /dev/null
@@ -1,76 +0,0 @@
-global
-    log gerrit-haproxy-sidecar local0 debug
-
-    chroot /var/lib/haproxy
-    stats socket /var/run/haproxy/admin.sock mode 660 level admin
-    stats timeout 30s
-    user haproxy
-    group haproxy
-    daemon
-
-defaults
-    log     global
-    mode    http
-    option  httplog
-    option  dontlognull
-    timeout connect 5000
-    timeout client  900000
-    timeout server  900000
-    timeout check 30000
-
-frontend localnodes
-    bind *:80
-    mode http
-    option httplog
-    capture request header X-Forwarded-For len 15
-    log-format %[capture.req.hdr(0)]:%cp\ [%t]\ %f\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ {%hrl}\ {%hsl}\ %{+Q}r
-
-    default_backend primary
-
-frontend gitssh
-    bind *:29418
-    mode tcp
-    timeout client  5m
-
-    default_backend ssh
-
-backend primary
-    mode http
-    balance roundrobin
-    option forwardfor
-    default-server inter 10s fall 3 rise 2
-    option httpchk GET /config/server/healthcheck~status HTTP/1.0\r\nHost:\ $GERRIT_PRIMARY_1_URL
-    http-check expect status 200
-    server gerrit-1 $GERRIT_PRIMARY_1_URL:8080 check inter 10s
-    server gerrit-2 $GERRIT_PRIMARY_2_URL:8080 check inter 10s backup
-
-backend gerrit-1
-    mode http
-    option forwardfor
-    server gerrit-1 $GERRIT_PRIMARY_1_URL:8080
-
-backend gerrit-2
-    mode http
-    option forwardfor
-    server gerrit-2 $GERRIT_PRIMARY_2_URL:8080
-
-backend ssh
-    mode tcp
-    option redispatch
-    option httpchk GET /config/server/healthcheck~status HTTP/1.0\r\nHost:\ $GERRIT_PRIMARY_1_URL
-    http-check expect status 200
-    balance source
-    timeout connect 10s
-    timeout server 5m
-    server gerrit-ssh-1 $GERRIT_PRIMARY_1_URL:29418 check port 8080 inter 10s
-    server gerrit-ssh-2 $GERRIT_PRIMARY_2_URL:29418 check port 8080 inter 10s backup
-
-backend gerrit-ssh-1
-    mode http
-    option forwardfor
-    server gerrit-ssh-1 $GERRIT_PRIMARY_1_URL:29418
-
-backend gerrit-ssh-2
-    mode http
-    option forwardfor
-    server gerrit-ssh-2 $GERRIT_PRIMARY_2_URL:29418
diff --git a/dual-primary/setup.env.template b/dual-primary/setup.env.template
index b1314ed..8f76af9 100644
--- a/dual-primary/setup.env.template
+++ b/dual-primary/setup.env.template
@@ -19,7 +19,6 @@
 PRIMARY1_SUBDOMAIN:=$(AWS_PREFIX)-primary-1.gerrit-demo
 PRIMARY2_SUBDOMAIN:=$(AWS_PREFIX)-primary-2.gerrit-demo
 REPLICA_SUBDOMAIN:=$(AWS_PREFIX)-replica.gerrit-demo
-LB_SUBDOMAIN=$(AWS_PREFIX)-lb.gerrit-demo
 PRIMARIES_GERRIT_SUBDOMAIN=$(AWS_PREFIX)-primaries.gerrit-demo
 DOCKER_REGISTRY_URI:=<yourAccountId>.dkr.ecr.us-east-1.amazonaws.com
 SSL_CERTIFICATE_ARN=arn:aws:acm:us-east-1:<yourAccountId>:certificate/33e2c235-a4d1-42b7-b866-18d8d744975c
diff --git a/dual-primary/syslog-sidecar/Dockerfile b/dual-primary/syslog-sidecar/Dockerfile
deleted file mode 100644
index 11f3059..0000000
--- a/dual-primary/syslog-sidecar/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM alpine:3.4
-MAINTAINER Ryan Schlesinger <ryan@outstand.com>
-
-RUN apk add --no-cache bash syslog-ng
-
-RUN mkdir /sidecar
-COPY config/* /etc/syslog-ng/
-COPY docker-entrypoint.sh /docker-entrypoint.sh
-VOLUME ["/sidecar"]
-CMD ["syslog-ng", "-F"]
-ENTRYPOINT ["/docker-entrypoint.sh"]
diff --git a/dual-primary/syslog-sidecar/Makefile b/dual-primary/syslog-sidecar/Makefile
deleted file mode 100644
index b2e5e97..0000000
--- a/dual-primary/syslog-sidecar/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-include ../../Makefile.common
-include ../setup.env
-
-IMAGE_NAME:=syslog-sidecar
-
-docker-registry-login:
-	aws ecr get-login-password --region $(AWS_REGION) \
-		| docker login --username AWS --password-stdin $(DOCKER_REGISTRY_URI)/aws-gerrit/$(IMAGE_NAME)
-
-syslog-sidecar-build:
-	docker build -t aws-gerrit/$(IMAGE_NAME):$(SYSLOG_HEAD_SHA1) .
-	docker tag aws-gerrit/$(IMAGE_NAME):$(SYSLOG_HEAD_SHA1) $(DOCKER_REGISTRY_URI)/aws-gerrit/$(IMAGE_NAME):$(SYSLOG_HEAD_SHA1)
-
-syslog-sidecar-publish: docker-registry-login syslog-sidecar-build
-	docker push $(DOCKER_REGISTRY_URI)/aws-gerrit/$(IMAGE_NAME):$(SYSLOG_HEAD_SHA1)
diff --git a/dual-primary/syslog-sidecar/config/syslog-ng-destination.out b/dual-primary/syslog-sidecar/config/syslog-ng-destination.out
deleted file mode 100644
index 170f7e4..0000000
--- a/dual-primary/syslog-sidecar/config/syslog-ng-destination.out
+++ /dev/null
@@ -1 +0,0 @@
-  destination d_stdout { pipe("/dev/stdout"); };
diff --git a/dual-primary/syslog-sidecar/config/syslog-ng-log.out b/dual-primary/syslog-sidecar/config/syslog-ng-log.out
deleted file mode 100644
index 6901c41..0000000
--- a/dual-primary/syslog-sidecar/config/syslog-ng-log.out
+++ /dev/null
@@ -1 +0,0 @@
-log { source(s_all); destination(d_stdout); };
diff --git a/dual-primary/syslog-sidecar/config/syslog-ng-plugins.std b/dual-primary/syslog-sidecar/config/syslog-ng-plugins.std
deleted file mode 100644
index ef0ce3e..0000000
--- a/dual-primary/syslog-sidecar/config/syslog-ng-plugins.std
+++ /dev/null
@@ -1 +0,0 @@
-@version: 3.7
diff --git a/dual-primary/syslog-sidecar/config/syslog-ng-source.sidecar b/dual-primary/syslog-sidecar/config/syslog-ng-source.sidecar
deleted file mode 100644
index 1181f78..0000000
--- a/dual-primary/syslog-sidecar/config/syslog-ng-source.sidecar
+++ /dev/null
@@ -1,5 +0,0 @@
-# sidecar log source for mounting between docker containers
-  network(
-    transport("udp")
-    port("514")
-  );
diff --git a/dual-primary/syslog-sidecar/config/syslog-ng-source.std b/dual-primary/syslog-sidecar/config/syslog-ng-source.std
deleted file mode 100644
index 5a50916..0000000
--- a/dual-primary/syslog-sidecar/config/syslog-ng-source.std
+++ /dev/null
@@ -1,8 +0,0 @@
-# ---------------------------------------------------------------------------------
-# Default syslog-ng sources; Do not edit this file!
-# append source with line on a file: syslog-ng-source.<package>
-# ---------------------------------------------------------------------------------
-# message generated by Syslog-NG
-  internal();
-# standard Linux log source (this is the default place for the syslog() function to send logs to)
-  unix-dgram("/dev/log");
diff --git a/dual-primary/syslog-sidecar/docker-entrypoint.sh b/dual-primary/syslog-sidecar/docker-entrypoint.sh
deleted file mode 100755
index be51a09..0000000
--- a/dual-primary/syslog-sidecar/docker-entrypoint.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-
-# The following two methods are ripped from alpine's syslog-ng package.
-# This allows us (and a user) to customize the config with snippets.
-grep_syslog_conf_entries() {
-  local section="$1" FN filelist
-  grep -v '^#' /etc/syslog-ng/syslog-ng-${section}.std
-  filelist=$(find /etc/syslog-ng/ -maxdepth 1 -type f -name "syslog-ng-${section}.*" | grep -Ev ".backup|.std|~")
-  if [ $? -eq 0 ]
-  then
-    for FN in ${filelist}
-    do
-      grep -v '^#' $FN
-    done
-  fi
-}
-
-update() {
-  local fname='/etc/syslog-ng/syslog-ng.conf'
-  local f_tmp="/etc/syslog-ng/syslog-ng.conf.$$"
-  for ng_std in options source destination filter log
-  do
-    [ -f /etc/syslog-ng/syslog-ng-${ng_std}.std ] || exit 1
-  done
-  {
-    # create options entries
-    grep_syslog_conf_entries plugins
-    echo "options {"
-    grep_syslog_conf_entries options
-    echo "};"
-    # create source entries
-    echo "source s_all {"
-    grep_syslog_conf_entries source
-    echo "};"
-    # create destination entries
-    grep_syslog_conf_entries destination
-    # create filter entries
-    grep_syslog_conf_entries filter
-    # create log entries
-    grep_syslog_conf_entries log
-  } > $f_tmp
-  cp -p $f_tmp $fname
-  rm -f $f_tmp
-}
-
-update
-
-echo Starting "$@"
-exec "$@"
diff --git a/primary-replica/cf-service-primary.yml b/primary-replica/cf-service-primary.yml
index 7c10836..aed8067 100644
--- a/primary-replica/cf-service-primary.yml
+++ b/primary-replica/cf-service-primary.yml
@@ -22,10 +22,6 @@
         Description: Gerrit official Docker image
         Type: String
         Default: aws-gerrit/gerrit:latest
-  GerritLBDockerImage:
-        Description: Load Balancer official Docker image
-        Type: String
-        Default: haproxy:1.7
   DockerRegistryUrl:
         Description: Docker registry URL
         Type: String