Allow to deploy dual-master with existing EFS

Currently the creation of a dual-master stack always creates a new,
empty EFS filesystem. Whilst this is good for the first deployment of a
stack, it is not suited for deploying a stack leveraging existing data.

Being able to specify an EFS stack (together with the ability of
specifying an existing EBS snapshot), allows to recover stacks from a
specific point in time, as well as performing a blue/green deployment in
which the two co-existing stacks point to the same data.

Feature: Issue 13765
Change-Id: I4a62f7a4becce4edcc1a487df300f09f70704024
diff --git a/dual-master/Makefile b/dual-master/Makefile
index 6545d07..6e90cfb 100644
--- a/dual-master/Makefile
+++ b/dual-master/Makefile
@@ -57,6 +57,9 @@
 ifdef FILESYSTEM_PROVISIONED_THROUGHPUT_IN_MIBPS
 		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=ProvisionedThroughputInMibps,ParameterValue=$(FILESYSTEM_PROVISIONED_THROUGHPUT_IN_MIBPS))
 endif
+ifdef FILESYSTEM_ID
+		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=FileSystemID,ParameterValue=$(FILESYSTEM_ID))
+endif
 ifdef SUBNET_CIDR
 		$(eval CLUSTER_OPTIONAL_PARAMS := $(CLUSTER_OPTIONAL_PARAMS) ParameterKey=SubnetCIDR,ParameterValue=$(SUBNET_CIDR))
 endif
diff --git a/dual-master/README.md b/dual-master/README.md
index 6343fba..b69434c 100644
--- a/dual-master/README.md
+++ b/dual-master/README.md
@@ -126,6 +126,11 @@
 * `GERRIT_VOLUME_SNAPSHOT_ID` : Optional. Ignored if GERRIT_VOLUME_ID is not empty. Id of
 the EBS volume snapshot used to create new EBS volume for Gerrit data.
 * `GERRIT_VOLUME_SIZE_IN_GIB`: Optional. The size of the Gerrit data volume, in GiBs. `10` by default.
+* `FILESYSTEM_ID`: Optional. An existing EFS filesystem id.
+
+    If empty, a new EFS will be created to store git data.
+    Setting this value is required when deploying a dual-master cluster using
+    existing data as well as performing blue/green deployments.
 
 #### REPLICATION SERVICE
 
diff --git a/dual-master/cf-cluster.yml b/dual-master/cf-cluster.yml
index 90b898a..63d122c 100644
--- a/dual-master/cf-cluster.yml
+++ b/dual-master/cf-cluster.yml
@@ -53,6 +53,10 @@
     Type: String
     Default: bursting
     AllowedValues: [bursting, provisioned]
+  FileSystemID:
+    Description: the id of the EFS filesystem to mount
+    Type: String
+    Default: ""
   ProvisionedThroughputInMibps:
     Description:  The fs throughput, measured in MiB/s. Valid values are 1-1024.
     Type: Number
@@ -96,6 +100,7 @@
 
 Conditions:
   isProvisionedThroughput: !Equals [!Ref FileSystemThroughputMode, "provisioned"]
+  CreateEFS: !Equals [!Ref FileSystemID, ""]
 
 Resources:
   # ECS Resources
@@ -214,7 +219,7 @@
         ECSCluster: !Ref ECSCluster
         EC2SecurityGroup: !Ref EcsHostSecurityGroup
         EC2InstanceProfile: !Ref EC2InstanceProfile
-        FileSystem: !Ref FileSystem
+        FileSystem: !If [CreateEFS, !Ref FileSystem, !Ref FileSystemID ]
         SubnetId: !GetAtt ECSTaskNetworkStack.Outputs.PublicSubnetOneRef
         LogGroupName: !Ref AWS::StackName
         MasterMaxCount: !Ref MasterMaxCount
@@ -239,7 +244,7 @@
         ECSCluster: !Ref ECSCluster
         EC2SecurityGroup: !Ref EcsHostSecurityGroup
         EC2InstanceProfile: !Ref EC2InstanceProfile
-        FileSystem: !Ref FileSystem
+        FileSystem: !If [CreateEFS, !Ref FileSystem, !Ref FileSystemID ]
         SubnetId: !GetAtt ECSTaskNetworkStack.Outputs.PublicSubnetOneRef
         LogGroupName: !Ref AWS::StackName
         MasterMaxCount: !Ref MasterMaxCount
@@ -292,6 +297,7 @@
             Resource: '*'
   FileSystem:
     Type: AWS::EFS::FileSystem
+    Condition: CreateEFS
     Properties:
       ThroughputMode: !Ref FileSystemThroughputMode
       ProvisionedThroughputInMibps: !If [isProvisionedThroughput, !Ref ProvisionedThroughputInMibps, !Ref "AWS::NoValue"]
@@ -300,6 +306,7 @@
           Value: "multi-master-git-repo"
   GitMountTarget:
     Type: AWS::EFS::MountTarget
+    Condition: CreateEFS
     Properties:
       FileSystemId: !Ref FileSystem
       SubnetId: !GetAtt ECSTaskNetworkStack.Outputs.PublicSubnetOneRef
@@ -307,6 +314,7 @@
         - !Ref MountTargetSecurityGroup
   MountTargetSecurityGroup:
     Type: AWS::EC2::SecurityGroup
+    Condition: CreateEFS
     Properties:
       VpcId: !GetAtt ECSTaskNetworkStack.Outputs.VPCRef
       GroupDescription: "Security group for mount target"