Add DNS entry for Gerrit master

Add A type DNS entry for the service

Feature: Issue 12445
Change-Id: I8785cfe0d39c280da554885a7dc59c9ed28dd58c
diff --git a/single-master/Makefile b/single-master/Makefile
index ea8d814..9b94f1c 100644
--- a/single-master/Makefile
+++ b/single-master/Makefile
@@ -2,12 +2,21 @@
 CLUSTER_TEMPLATE:=cf-cluster.yml
 SERVICE_TEMPLATE:=cf-service.yml
 SERVICE_STACK_NAME:=gerrit-service
+DNS_ROUTING_STACK_NAME:=gerrit-dns-routing
+DNS_ROUTING_TEMPLATE:=cf-dns-route.yml
+HOSTED_ZONE_NAME:=mycompany.com
+SUBDOMAIN:=gerrit-master-demo
 AWS_REGION:=us-east-2
 AWS_FC_COMMAND=export AWS_PAGER=;aws cloudformation
 
-.PHONY: create-all delete-all cluster service wait-for-cluster-creation wait-for-service-creation wait-for-cluster-deletion wait-for-service-deletion
+.PHONY: create-all delete-all \
+				cluster service dns-routing \
+				wait-for-cluster-creation wait-for-service-creation wait-for-dns-routing-creation \
+				wait-for-cluster-deletion wait-for-service-deletion wait-for-dns-routing-deletion
 
-create-all: cluster wait-for-cluster-creation service wait-for-service-creation
+create-all: cluster wait-for-cluster-creation \
+						service wait-for-service-creation \
+						dns-routing wait-for-dns-routing-creation
 
 cluster:
 	$(AWS_FC_COMMAND) create-stack \
@@ -22,8 +31,19 @@
 		--capabilities CAPABILITY_IAM  \
 		--template-body file://`pwd`/$(SERVICE_TEMPLATE) \
 		--region $(AWS_REGION) \
-		--parameters ParameterKey=ClusterStackName,ParameterValue=$(CLUSTER_STACK_NAME)
+		--parameters \
+		ParameterKey=ClusterStackName,ParameterValue=$(CLUSTER_STACK_NAME) \
+		ParameterKey=HostedZoneName,ParameterValue=$(HOSTED_ZONE_NAME) \
+		ParameterKey=Subdomain,ParameterValue=$(SUBDOMAIN)
 
+dns-routing:
+	$(AWS_FC_COMMAND) create-stack \
+		--stack-name $(DNS_ROUTING_STACK_NAME) \
+		--capabilities CAPABILITY_IAM  \
+		--template-body file://`pwd`/$(DNS_ROUTING_TEMPLATE) \
+		--region $(AWS_REGION) \
+		--parameters \
+		ParameterKey=ServiceStackName,ParameterValue=$(SERVICE_STACK_NAME) \
 
 wait-for-cluster-creation:
 	@echo "*** Wait for cluster stack '$(CLUSTER_STACK_NAME)' creation"
@@ -39,6 +59,13 @@
 	--region $(AWS_REGION)
 	@echo "*** Service stack '$(SERVICE_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 \
+	--stack-name $(DNS_ROUTING_STACK_NAME) \
+	--region $(AWS_REGION)
+	@echo "*** DNS Routing stack '$(DNS_ROUTING_STACK_NAME)' created"
+
 wait-for-cluster-deletion:
 	@echo "*** Wait for cluster stack '$(CLUSTER_STACK_NAME)' deletion"
 	$(AWS_FC_COMMAND) wait stack-delete-complete \
@@ -53,6 +80,13 @@
 	--region $(AWS_REGION)
 	@echo "*** Service stack '$(SERVICE_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 \
+	--stack-name $(DNS_ROUTING_STACK_NAME) \
+	--region $(AWS_REGION)
+	@echo "*** DNS routing stack '$(DNS_ROUTING_STACK_NAME)' deleted"
+
 delete-cluster:
 	$(AWS_FC_COMMAND) delete-stack \
 	--stack-name $(CLUSTER_STACK_NAME) \
@@ -63,4 +97,11 @@
 	--stack-name $(SERVICE_STACK_NAME) \
 	--region $(AWS_REGION)
 
-delete-all: delete-service wait-for-service-deletion delete-cluster wait-for-cluster-deletion
+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 wait-for-service-deletion \
+						delete-cluster wait-for-cluster-deletion \
diff --git a/single-master/README.md b/single-master/README.md
index f3745d7..d444943 100644
--- a/single-master/README.md
+++ b/single-master/README.md
@@ -8,6 +8,7 @@
 Two templates are provided in this example:
 * `cf-cluster`: define the ECS cluster and the networking stack
 * `cf-service`: defined the service stack running Gerrit
+* `cf-dns-route`: defined the DNS routing for the service
 
 ### Networking
 
@@ -20,6 +21,7 @@
  * HTTP on port 8080
  * SSH on port 29418
 * 1 Internet Gateway
+* 1 type A alias DNS entry
 
 ### Deployment type
 
@@ -39,6 +41,11 @@
 
 ### Getting Started
 
+As a prerequisite to run this stack, you will need a registered and correctly
+configured domain in [Route53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html).
+
+Once you will have it you can continue with the next steps:
+
 * Create a key pair to access the EC2 instances in the cluster:
 
 ```
@@ -49,47 +56,44 @@
 for troubleshooting purposes. Store them in a `pem` file to use when ssh-ing into your
 instances as follow: `ssh -i yourKeyPairs.pem <ec2_instance_ip>`*
 
-* Create the cluster and service stack:
+* Create the cluster, service and DNS routing stacks:
 
 ```
 make create-all
 ```
 
-By default the cluster and service name are called, respectively, `cluster-stack`
-and `service-stack`. If you want to change the name you can do it by overriding
-the *Makefile* parameters:
-
-```
-make create-all CLUSTER_STACK_NAME=my-cluster-stack SERVICE_STACK_NAME=my-service-stack
-```
-
-Keep in mind you will have to pass the same parameters when deleting the stacks.
-
 ### Cleaning up
 
 ```
 make delete-all
 ```
 
+### Stack parameters
+
+The above commands for the creation and deletion of the stacks use a set of default
+parameters which can be overridden as in the following example:
+
+```
+make create-all CLUSTER_STACK_NAME=my-cluster-stack SERVICE_STACK_NAME=my-service-stack
+```
+
+Keep in mind, that once you override a parameter in the creation of the stack,
+you will have to do the same in the deletion, i.e.:
+
+```
+make delete-all CLUSTER_STACK_NAME=my-cluster-stack SERVICE_STACK_NAME=my-service-stack
+```
+
+This is the list of the parameters:
+
+* `CLUSTER_STACK_NAME`: name of the cluster stack. `gerrit-cluster` by default.
+* `SERVICE_STACK_NAME`: name of the service stack. `gerrit-service` by default.
+* `DNS_ROUTING_STACK_NAME`: name of the DNS routing stack. `gerrit-dns-routing` by default.
+* `HOSTED_ZONE_NAME`: name of the hosted zone. `mycompany.com` by default.
+* `SUBDOMAIN`: name of the sub domain. `gerrit-master-demo` by default.
+
 ### Access your Gerrit
 
-You can find the Gerrit public URL by running the following command:
+You Gerrit instance will be available at this URL: `http://<HOSTED_ZONE_NAME>.<SUBDOMAIN>`.
 
-```
-aws cloudformation describe-stacks --stack-name gerrit-service
-```
-
-In the `Outputs` section the URL is set in the `PublicLoadBalancerUrl` key:
-
-```
-  "Outputs": [
-    {
-      "OutputKey": "PublicLoadBalancerUrl",
-      "OutputValue": "http://gerri-LoadB-1CDG276QVT8K8-e28c5bca2e024135.elb.us-east-2.amazonaws.com",
-      "Description": "The url of the external load balancer",
-      "ExportName": "gerrit-ponch-service:PublicLoadBalancerUrl"
-    }
-  ],
-```
-
-The available ports are `8080` for HTTP and `29418` for SSH
+The available ports are `8080` for HTTP and `29418` for SSH.
diff --git a/single-master/cf-dns-route.yml b/single-master/cf-dns-route.yml
new file mode 100644
index 0000000..55f8a15
--- /dev/null
+++ b/single-master/cf-dns-route.yml
@@ -0,0 +1,32 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Description: A stack for the Gerrit service Route53 routing.
+Parameters:
+  ServiceStackName:
+      Description: Stack name of the ECS Gerrit service
+      Type: String
+      Default: gerrit-service
+
+Resources:
+  DnsRecord:
+      Type: AWS::Route53::RecordSet
+      Properties:
+        Name:
+          !Join
+            - '.'
+            - - Fn::ImportValue: !Join [':', [!Ref 'ServiceStackName', 'Subdomain']]
+              - Fn::ImportValue: !Join [':', [!Ref 'ServiceStackName', 'HostedZoneName']]
+        HostedZoneName:
+          !Join
+            - ''
+            - - Fn::ImportValue: !Join [':', [!Ref 'ServiceStackName', 'HostedZoneName']]
+              - '.'
+        Comment: DNS name for Gerrit Master.
+        Type: A
+        AliasTarget:
+          DNSName:
+            Fn::ImportValue:
+              !Join [':', [!Ref 'ServiceStackName', 'PublicLoadBalancerDNSName']]
+          HostedZoneId:
+            Fn::ImportValue:
+              !Join [':', [!Ref 'ServiceStackName', 'CanonicalHostedZoneID']]
+          EvaluateTargetHealth: False
diff --git a/single-master/cf-service.yml b/single-master/cf-service.yml
index bb12213..dec60ec 100644
--- a/single-master/cf-service.yml
+++ b/single-master/cf-service.yml
@@ -28,6 +28,13 @@
         Description: Gerrit SSH port
         Type: Number
         Default: 29418
+  HostedZoneName:
+        Description: The route53 HostedZoneName.
+        Type: String
+  Subdomain:
+        Description: The subdomain of the Gerrit cluster
+        Type: String
+        Default: gerrit-master-demo
 
 Resources:
     Service:
@@ -61,6 +68,9 @@
                   Essential: true
                   Image: !Ref DockerImage
                   Environment:
+                    - Name: "CANONICAL_WEB_URL"
+                      Value: !Join [ '', [ 'http://', !Ref 'Subdomain', '.', !Ref 'HostedZoneName' ] ]
+                  Environment:
                     - Name: "region"
                       Value: !Ref AWS::Region
                   Cpu: 1024
@@ -166,8 +176,28 @@
                   - 'logs:PutLogEvents'
                 Resource: '*'
 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 ['', ['http://', !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' ] ]