Merge branch 'stable-3.1'
* stable-3.1:
Use load-balancer service ports from HAProxy
Fix dual-master recipe: add missing template parameters
Fix dual-master recipe adding missing parameter HTTPGerritMaster2Port
Base all image paths on the project ROOT_DIR
Fix SHA1 computation for haproxy / syslog-sidecar
Add missing LB_SUBDOMAIN for dual-master config
Add healthcheck plugin
Fix Gerrit root directory
Remove .empty file
Add HAProxy in front of the dual masters
Fix Gerrit sha1 calculation
Remove auth section duplicate
Change-Id: I31953d155de52acbafc3badfe1da599d18debeb6
diff --git a/Makefile.common b/Makefile.common
index 4f31260..37ae390 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1,4 +1,5 @@
-include $(dir $(realpath $(lastword $(MAKEFILE_LIST))))common.env
+ROOT_DIR=$(dir $(realpath $(filter %Makefile.common,$(MAKEFILE_LIST))))
+include $(ROOT_DIR)common.env
cluster-keys:
diff --git a/common.env b/common.env
index 8f5a906..be6480b 100644
--- a/common.env
+++ b/common.env
@@ -12,7 +12,14 @@
GERRIT_CI=https://gerrit-ci.gerritforge.com/view/Plugins-$(GERRIT_BRANCH)/job
LAST_BUILD=lastSuccessfulBuild/artifact/bazel-bin/plugins
-# Image version
-IMAGE_DIR=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))gerrit
-HEAD_SHA1=$(shell git $(IMAGE_DIR) -type f -exec cat {} \; | shasum | cut -c 1-20)
+# Image directories
+IMAGE_DIR:=$(ROOT_DIR)/gerrit
+HAPROXY_IMAGE_DIR=$(ROOT_DIR)/dual-master/haproxy
+SYSLOG_IMAGE_DIR=$(ROOT_DIR)/dual-master/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-master/Makefile b/dual-master/Makefile
index d91e7c6..038eb70 100644
--- a/dual-master/Makefile
+++ b/dual-master/Makefile
@@ -4,17 +4,20 @@
CLUSTER_TEMPLATE:=cf-cluster.yml
SERVICE_MASTER_TEMPLATE:=cf-service-master.yml
DNS_ROUTING_TEMPLATE:=cf-dns-route.yml
+LOAD_BALANCER_TEMPLATE:=cf-service-lb.yml
AWS_FC_COMMAND=export AWS_PAGER=;aws cloudformation
.PHONY: create-all delete-all \
cluster cluster-keys service-master-1 dns-routing \
wait-for-cluster-creation wait-for-service-master-1-creation wait-for-service-master-2-creation wait-for-dns-routing-creation \
wait-for-cluster-deletion wait-for-service-master-1-deletion wait-for-service-master-2-deletion wait-for-dns-routing-deletion \
- gerrit-build gerrit-publish
+ service-lb wait-for-service-lb-deletion wait-for-service-lb-creation \
+ gerrit-build gerrit-publish haproxy-publish syslog-sidecar-publish
create-all: cluster wait-for-cluster-creation \
service-master-1 wait-for-service-master-1-creation \
service-master-2 wait-for-service-master-2-creation \
+ service-lb wait-for-service-lb-creation \
dns-routing wait-for-dns-routing-creation
cluster: cluster-keys
@@ -39,9 +42,17 @@
ParameterKey=Subdomain,ParameterValue=$(MASTER1_SUBDOMAIN) \
ParameterKey=DockerRegistryUrl,ParameterValue=$(DOCKER_REGISTRY_URI) \
ParameterKey=CertificateArn,ParameterValue=$(SSL_CERTIFICATE_ARN) \
+ ParameterKey=HTTPHostPort,ParameterValue=$(HTTP_HOST_PORT_MASTER1) \
+ ParameterKey=SSHHostPort,ParameterValue=$(SSH_HOST_PORT_MASTER1) \
ParameterKey=GerritKeyPrefix,ParameterValue=$(GERRIT_KEY_PREFIX)\
+ ParameterKey=DockerImage,ParameterValue=aws-gerrit/gerrit:$(IMAGE_TAG) \
+ ParameterKey=GerritDataVolume,ParameterValue=gerrit-data-master-1 \
+ ParameterKey=GerritIndexVolume,ParameterValue=gerrit-index-master-1 \
+ ParameterKey=GerritCacheVolume,ParameterValue=gerrit-cache-master-1 \
+ ParameterKey=GerritDbVolume,ParameterValue=gerrit-db-master-1 \
+ ParameterKey=GerritLogsVolume,ParameterValue=gerrit-logs-master1 \
ParameterKey=PeerSubdomain,ParameterValue=$(MASTER2_SUBDOMAIN) \
- ParameterKey=DockerImage,ParameterValue=aws-gerrit/gerrit:$(IMAGE_TAG)
+ ParameterKey=LBSubdomain,ParameterValue=$(LB_SUBDOMAIN)
service-master-2:
$(AWS_FC_COMMAND) create-stack \
@@ -64,7 +75,26 @@
ParameterKey=GerritCacheVolume,ParameterValue=gerrit-cache-master-2 \
ParameterKey=GerritDbVolume,ParameterValue=gerrit-db-master-2 \
ParameterKey=GerritLogsVolume,ParameterValue=gerrit-logs-master-2 \
- ParameterKey=PeerSubdomain,ParameterValue=$(MASTER1_SUBDOMAIN)
+ ParameterKey=PeerSubdomain,ParameterValue=$(MASTER1_SUBDOMAIN) \
+ ParameterKey=LBSubdomain,ParameterValue=$(LB_SUBDOMAIN)
+
+service-lb:
+ $(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=Master1ServiceStackName,ParameterValue=$(SERVICE_MASTER1_STACK_NAME) \
+ ParameterKey=Master2ServiceStackName,ParameterValue=$(SERVICE_MASTER2_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=HAProxyDockerImage,ParameterValue=aws-gerrit/haproxy:$(HAPROXY_HEAD_SHA1) \
+ ParameterKey=SidecarDockerImage,ParameterValue=aws-gerrit/syslog-sidecar:$(SYSLOG_HEAD_SHA1)
dns-routing:
$(AWS_FC_COMMAND) create-stack \
@@ -74,7 +104,8 @@
--region $(AWS_REGION) \
--parameters \
ParameterKey=Master1ServiceStackName,ParameterValue=$(SERVICE_MASTER1_STACK_NAME) \
- ParameterKey=Master2ServiceStackName,ParameterValue=$(SERVICE_MASTER2_STACK_NAME)
+ ParameterKey=Master2ServiceStackName,ParameterValue=$(SERVICE_MASTER2_STACK_NAME) \
+ ParameterKey=LBServiceStackName,ParameterValue=$(LOAD_BALANCER_STACK_NAME)
wait-for-cluster-creation:
@echo "*** Wait for cluster stack '$(CLUSTER_STACK_NAME)' creation"
@@ -97,6 +128,13 @@
--region $(AWS_REGION)
@echo "*** Service stack '$(SERVICE_MASTER2_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 \
@@ -125,6 +163,13 @@
--region $(AWS_REGION)
@echo "*** Service stack master '$(SERVICE_MASTER2_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 \
@@ -147,15 +192,27 @@
--stack-name $(SERVICE_MASTER2_STACK_NAME) \
--region $(AWS_REGION)
+delete-service-lb:
+ $(AWS_FC_COMMAND) delete-stack \
+ --stack-name $(LOAD_BALANCER_STACK_NAME) \
+ --region $(AWS_REGION)
+
delete-dns-routing:
$(AWS_FC_COMMAND) delete-stack \
--stack-name $(DNS_ROUTING_STACK_NAME) \
--region $(AWS_REGION)
delete-all: delete-dns-routing wait-for-dns-routing-deletion \
+ delete-service-lb wait-for-service-lb-deletion \
delete-service-master-1 wait-for-service-master-1-deletion \
delete-service-master-2 wait-for-service-master-2-deletion \
delete-cluster wait-for-cluster-deletion
gerrit-publish:
$(MAKE) -C ../gerrit gerrit-publish RECIPE=dual-master
+
+haproxy-publish:
+ $(MAKE) -C haproxy haproxy-publish
+
+syslog-sidecar-publish:
+ $(MAKE) -C syslog-sidecar syslog-sidecar-publish
diff --git a/dual-master/README.md b/dual-master/README.md
index ff91fd1..7c5cfe4 100644
--- a/dual-master/README.md
+++ b/dual-master/README.md
@@ -146,6 +146,15 @@
* Add the plugins you want to install in `./gerrit/plugins`
* Publish the image: `make gerrit-publish`
+### Publish custom HAProxy Docker image
+
+* Create the HAProxy and the logging sidecar repository in the Docker registry:
+ `aws ecr create-repository --repository-name aws-gerrit/haproxy`
+ `aws ecr create-repository --repository-name aws-gerrit/syslog-sidecar`
+* Publish the images:
+ `make haproxy-publish`
+ `make syslog-sidecar-publish`
+
### Getting Started
* Create the cluster, services and DNS routing stacks:
diff --git a/dual-master/cf-dns-route.yml b/dual-master/cf-dns-route.yml
index c704f1f..d123d7f 100644
--- a/dual-master/cf-dns-route.yml
+++ b/dual-master/cf-dns-route.yml
@@ -9,6 +9,10 @@
Description: Stack name of the ECS Master Gerrit service
Type: String
Default: gerrit-service-master-2
+ LBServiceStackName:
+ Description: Stack name of the ECS LB service
+ Type: String
+ Default: gerrit-service
Resources:
Master1DnsRecord:
@@ -57,3 +61,26 @@
Fn::ImportValue:
!Join [':', [!Ref 'Master2ServiceStackName', '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
diff --git a/dual-master/cf-service-lb.yml b/dual-master/cf-service-lb.yml
new file mode 100644
index 0000000..16c0b81
--- /dev/null
+++ b/dual-master/cf-service-lb.yml
@@ -0,0 +1,239 @@
+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
+ 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
+ Default: 1
+ 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-master
+ GerritKeyPrefix:
+ Description: Gerrit credentials keys prefix
+ Type: String
+ Master1ServiceStackName:
+ Description: Stack name of the ECS Master Gerrit service
+ Type: String
+ Default: gerrit-service-master-1
+ Master2ServiceStackName:
+ Description: Stack name of the ECS Master Gerrit service
+ Type: String
+ Default: gerrit-service-master-2
+ SyslogSidecarServiceName:
+ Description: HAPRoxy Syslog Sidecar service name
+ Type: String
+ Default: gerrit-haproxy-sidecar
+
+Resources:
+ LBService:
+ Type: AWS::ECS::Service
+ DependsOn:
+ - HTTPListener
+ Properties:
+ Cluster:
+ Fn::ImportValue:
+ !Join [':', [!Ref 'ClusterStackName', 'ClusterName']]
+ DesiredCount: !Ref DesiredCount
+ TaskDefinition: !Ref TaskDefinition
+ LoadBalancers:
+ - ContainerName: !Ref LBServiceName
+ ContainerPort: !Ref HTTPContainerPort
+ TargetGroupArn: !Ref HTTPTargetGroup
+
+ TaskDefinition:
+ Type: AWS::ECS::TaskDefinition
+ Properties:
+ Family: !Sub '${LBServiceName}TaskDefinition'
+ TaskRoleArn: !Ref ECSTaskExecutionRole
+ ExecutionRoleArn: !Ref ECSTaskExecutionRole
+ NetworkMode: bridge
+ ContainerDefinitions:
+ - Name: !Ref LBServiceName
+ Essential: true
+ Image: !Sub '${DockerRegistryUrl}/${HAProxyDockerImage}'
+ Environment:
+ - Name: GERRIT_MASTER_1_URL
+ Value:
+ Fn::ImportValue: !Join [':', [!Ref 'Master1ServiceStackName', 'PublicLoadBalancerDNSName']]
+ - Name: GERRIT_MASTER_2_URL
+ Value:
+ Fn::ImportValue: !Join [':', [!Ref 'Master2ServiceStackName', 'PublicLoadBalancerDNSName']]
+ - Name: SYSLOG_SIDECAR
+ Value: !Ref SyslogSidecarServiceName
+ Cpu: 1024
+ Memory: 2048
+ PortMappings:
+ - ContainerPort: !Ref HTTPContainerPort
+ HostPort: !Ref HTTPHostPort
+ 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
+
+ # This is a role which is used by the ECS tasks themselves.
+ ECSTaskExecutionRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Effect: Allow
+ Principal:
+ Service: [ecs-tasks.amazonaws.com]
+ Action: ['sts:AssumeRole']
+ Path: /
+ Policies:
+ - PolicyName: AmazonECSTaskExecutionRolePolicy
+ PolicyDocument:
+ Statement:
+ - Effect: Allow
+ Action:
+ # Allow the ECS Tasks to download images from ECR
+ - 'ecr:GetAuthorizationToken'
+ - 'ecr:BatchCheckLayerAvailability'
+ - 'ecr:GetDownloadUrlForLayer'
+ - 'ecr:BatchGetImage'
+ # Allow the ECS tasks to upload logs to CloudWatch
+ - 'logs:CreateLogStream'
+ - 'logs:PutLogEvents'
+ Resource: '*'
+ - PolicyName: AmazonECSTaskSecretManagerRolePolicy
+ PolicyDocument:
+ Statement:
+ - Effect: Allow
+ Action:
+ # Allow the ECS Tasks to get SSH Keys
+ - 'secretsmanager:GetSecretValue'
+ - 'kms:Decrypt'
+ Resource: '*'
+
+ LoadBalancer:
+ Type: AWS::ElasticLoadBalancingV2::LoadBalancer
+ Properties:
+ Type: network
+ Scheme: internet-facing
+ Subnets:
+ - Fn::ImportValue:
+ !Join [':', [!Ref 'ClusterStackName', 'PublicSubnetOne']]
+ 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
+
+ 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
+
+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-master/cf-service-master.yml b/dual-master/cf-service-master.yml
index b97fa2c..42ea576 100644
--- a/dual-master/cf-service-master.yml
+++ b/dual-master/cf-service-master.yml
@@ -30,6 +30,10 @@
Description: How many instances of this task should we run across our cluster?
Type: Number
Default: 1
+ HTTPGerritLBPort:
+ Description: Gerrit Load balancer HTTP port
+ Type: Number
+ Default: 8080
HTTPHostPort:
Description: Gerrit HTTP port
Type: Number
@@ -60,6 +64,9 @@
Description: The subdomain of the Gerrit cluster
Type: String
Default: gerrit-master-demo
+ LBSubdomain:
+ Description: The subdomain of the Gerrit load balancer
+ Type: String
GerritKeyPrefix:
Description: Gerrit credentials keys prefix
Type: String
@@ -128,7 +135,7 @@
Image: !Sub '${DockerRegistryUrl}/${DockerImage}'
Environment:
- Name: CANONICAL_WEB_URL
- Value: !Sub 'https://${Subdomain}.${HostedZoneName}'
+ Value: !Sub 'https://${LBSubdomain}.${HostedZoneName}'
- Name: HTTPD_LISTEN_URL
Value: !Sub 'proxy-https://*:${HTTPContainerPort}/'
- Name: AWS_REGION
@@ -140,7 +147,7 @@
- Name: SETUP_HA
Value: true
- Name: HA_PEER_URL
- Value: !Sub 'https://${PeerSubdomain}.${HostedZoneName}'
+ Value: !Sub 'http://${PeerSubdomain}.${HostedZoneName}:${HTTPGerritLBPort}'
- Name: HOSTED_ZONE_NAME
Value: !Ref HostedZoneName
MountPoints:
@@ -236,21 +243,19 @@
VpcId:
Fn::ImportValue:
!Join [':', [!Ref 'ClusterStackName', 'VPCId']]
- Port: !Ref HTTPHostPort
+ Port: !Ref HTTPGerritLBPort
Protocol: TCP
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
+ Port: !Ref HTTPGerritLBPort
+ Protocol: TCP
SSHTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
diff --git a/dual-master/haproxy/Dockerfile b/dual-master/haproxy/Dockerfile
new file mode 100644
index 0000000..f55de52
--- /dev/null
+++ b/dual-master/haproxy/Dockerfile
@@ -0,0 +1,12 @@
+FROM haproxy:1.7
+
+RUN apt-get update && \
+ apt-get -y install gettext-base netcat && \
+ mkdir /var/lib/haproxy && \
+ mkdir /var/run/haproxy && \
+ useradd haproxy && \
+ chown haproxy: /var/lib/haproxy /var/run/haproxy
+
+COPY haproxy.cfg.template /usr/local/etc/haproxy/
+
+COPY docker-entrypoint.sh /
diff --git a/dual-master/haproxy/Makefile b/dual-master/haproxy/Makefile
new file mode 100644
index 0000000..98d7370
--- /dev/null
+++ b/dual-master/haproxy/Makefile
@@ -0,0 +1,15 @@
+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-master/haproxy/docker-entrypoint.sh b/dual-master/haproxy/docker-entrypoint.sh
new file mode 100755
index 0000000..b379564
--- /dev/null
+++ b/dual-master/haproxy/docker-entrypoint.sh
@@ -0,0 +1,17 @@
+#!/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-master/haproxy/haproxy.cfg.template b/dual-master/haproxy/haproxy.cfg.template
new file mode 100644
index 0000000..08536ac
--- /dev/null
+++ b/dual-master/haproxy/haproxy.cfg.template
@@ -0,0 +1,76 @@
+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 master
+
+frontend gitssh
+ bind *:29418
+ mode tcp
+ timeout client 5m
+
+ default_backend ssh
+
+backend master
+ mode http
+ balance roundrobin
+ option forwardfor
+ default-server inter 10s fall 3 rise 2
+ option httpchk GET /config/server/healthcheck~status HTTP/1.0
+ http-check expect status 200
+ server gerrit-1 $GERRIT_MASTER_1_URL:8080 check inter 10s
+ server gerrit-2 $GERRIT_MASTER_2_URL:8080 check inter 10s backup
+
+backend gerrit-1
+ mode http
+ option forwardfor
+ server gerrit-1 $GERRIT_MASTER_1_URL:8080
+
+backend gerrit-2
+ mode http
+ option forwardfor
+ server gerrit-2 $GERRIT_MASTER_2_URL:8080
+
+backend ssh
+ mode tcp
+ option redispatch
+ option httpchk GET /config/server/healthcheck~status HTTP/1.0
+ http-check expect status 200
+ balance source
+ timeout connect 10s
+ timeout server 5m
+ server gerrit-ssh-1 $GERRIT_MASTER_1_URL:29418 check port 8080 inter 10s
+ server gerrit-ssh-2 $GERRIT_MASTER_2_URL:29418 check port 8080 inter 10s backup
+
+backend gerrit-ssh-1
+ mode http
+ option forwardfor
+ server gerrit-ssh-1 $GERRIT_MASTER_1_URL:29418
+
+backend gerrit-ssh-2
+ mode http
+ option forwardfor
+ server gerrit-ssh-2 $GERRIT_MASTER_2_URL:29418
diff --git a/dual-master/setup.env.template b/dual-master/setup.env.template
index d6cbec8..6858912 100644
--- a/dual-master/setup.env.template
+++ b/dual-master/setup.env.template
@@ -4,9 +4,12 @@
SERVICE_MASTER2_STACK_NAME:=$(AWS_PREFIX)-service-master-2
HTTP_HOST_PORT_MASTER2:=8081
SSH_HOST_PORT_MASTER2:=29419
+HTTP_HOST_PORT_MASTER1:=8080
+SSH_HOST_PORT_MASTER1:=29418
DNS_ROUTING_STACK_NAME:=$(AWS_PREFIX)-dns-routing
HOSTED_ZONE_NAME:=yourcompany.com
MASTER1_SUBDOMAIN:=$(AWS_PREFIX)-master-1.gerrit-demo
MASTER2_SUBDOMAIN:=$(AWS_PREFIX)-master-2.gerrit-demo
+LB_SUBDOMAIN=$(AWS_PREFIX)-lb.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-master/syslog-sidecar/Dockerfile b/dual-master/syslog-sidecar/Dockerfile
new file mode 100644
index 0000000..11f3059
--- /dev/null
+++ b/dual-master/syslog-sidecar/Dockerfile
@@ -0,0 +1,11 @@
+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-master/syslog-sidecar/Makefile b/dual-master/syslog-sidecar/Makefile
new file mode 100644
index 0000000..b2e5e97
--- /dev/null
+++ b/dual-master/syslog-sidecar/Makefile
@@ -0,0 +1,15 @@
+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-master/syslog-sidecar/config/syslog-ng-destination.out b/dual-master/syslog-sidecar/config/syslog-ng-destination.out
new file mode 100644
index 0000000..170f7e4
--- /dev/null
+++ b/dual-master/syslog-sidecar/config/syslog-ng-destination.out
@@ -0,0 +1 @@
+ destination d_stdout { pipe("/dev/stdout"); };
diff --git a/dual-master/syslog-sidecar/config/syslog-ng-log.out b/dual-master/syslog-sidecar/config/syslog-ng-log.out
new file mode 100644
index 0000000..6901c41
--- /dev/null
+++ b/dual-master/syslog-sidecar/config/syslog-ng-log.out
@@ -0,0 +1 @@
+log { source(s_all); destination(d_stdout); };
diff --git a/dual-master/syslog-sidecar/config/syslog-ng-plugins.std b/dual-master/syslog-sidecar/config/syslog-ng-plugins.std
new file mode 100644
index 0000000..ef0ce3e
--- /dev/null
+++ b/dual-master/syslog-sidecar/config/syslog-ng-plugins.std
@@ -0,0 +1 @@
+@version: 3.7
diff --git a/dual-master/syslog-sidecar/config/syslog-ng-source.sidecar b/dual-master/syslog-sidecar/config/syslog-ng-source.sidecar
new file mode 100644
index 0000000..1181f78
--- /dev/null
+++ b/dual-master/syslog-sidecar/config/syslog-ng-source.sidecar
@@ -0,0 +1,5 @@
+# sidecar log source for mounting between docker containers
+ network(
+ transport("udp")
+ port("514")
+ );
diff --git a/dual-master/syslog-sidecar/config/syslog-ng-source.std b/dual-master/syslog-sidecar/config/syslog-ng-source.std
new file mode 100644
index 0000000..5a50916
--- /dev/null
+++ b/dual-master/syslog-sidecar/config/syslog-ng-source.std
@@ -0,0 +1,8 @@
+# ---------------------------------------------------------------------------------
+# 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-master/syslog-sidecar/docker-entrypoint.sh b/dual-master/syslog-sidecar/docker-entrypoint.sh
new file mode 100755
index 0000000..be51a09
--- /dev/null
+++ b/dual-master/syslog-sidecar/docker-entrypoint.sh
@@ -0,0 +1,49 @@
+#!/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/gerrit/Makefile b/gerrit/Makefile
index 2bf2055..a6d6719 100644
--- a/gerrit/Makefile
+++ b/gerrit/Makefile
@@ -7,6 +7,7 @@
gerrit-get-plugins:
# Make sure Prometheus Metrics exporter plugin is installed
+ mkdir -p $(@D)/plugins
@echo "Downloading metrics-reporter-prometheus plugin $(GERRIT_BRANCH)"
wget $(GERRIT_CI)/plugin-metrics-reporter-prometheus-bazel-master-$(GERRIT_BRANCH)/$(LAST_BUILD)/metrics-reporter-prometheus/metrics-reporter-prometheus.jar \
@@ -23,6 +24,11 @@
-O ./plugins/high-availability.jar \
|| { echo >&2 "Cannot download high-availability plugin: Check internet connection. Aborting"; exit 1; }
+ @echo "Downloading Health Check plugin $(GERRIT_BRANCH)"
+ wget $(GERRIT_CI)/plugin-healthcheck-bazel-$(GERRIT_BRANCH)/$(LAST_BUILD)/healthcheck/healthcheck.jar \
+ -O ./plugins/healthcheck.jar \
+ || { echo >&2 "Cannot download healthcheck plugin: Check internet connection. Aborting"; exit 1; }
+
gerrit-build:
cat Dockerfile | \
GERRIT_VERSION=$(GERRIT_VERSION) GERRIT_PATCH=$(GERRIT_PATCH) envsubst | \
diff --git a/gerrit/etc/gerrit.config.template b/gerrit/etc/gerrit.config.template
index 5cdbd19..dc11036 100644
--- a/gerrit/etc/gerrit.config.template
+++ b/gerrit/etc/gerrit.config.template
@@ -10,6 +10,7 @@
[auth]
type = ldap
gitBasicAuth = true
+ cookiedomain = .{{ COOKIE_DOMAIN }}
[ldap]
server = {{ LDAP_SERVER }}
username = {{ LDAP_USERNAME }}
@@ -59,6 +60,3 @@
excludeMetrics = caches/.*
{% endif %}
-
-[auth]
- cookiedomain = .{{ COOKIE_DOMAIN }}
diff --git a/gerrit/etc/healthcheck.config b/gerrit/etc/healthcheck.config
new file mode 100644
index 0000000..ddea5f1
--- /dev/null
+++ b/gerrit/etc/healthcheck.config
@@ -0,0 +1,9 @@
+[healthcheck]
+ timeout = 10s
+
+[healthcheck "querychanges"]
+ query = status:open OR status:merged OR status:abandoned
+ limit = 0
+
+[healthcheck "auth"]
+ enabled = false
diff --git a/gerrit/plugins/.empty b/gerrit/plugins/.empty
deleted file mode 100644
index e69de29..0000000
--- a/gerrit/plugins/.empty
+++ /dev/null