Retain Network stack in primary-replica

Blue/green deployment of the primary-replica recipe requires that the
blue and the green stacks are deployed within the same VPC.

In order to preserve the VPC, the IGW and the subnet upon deletion of
the blue stack, the nested network cloudformation template needs to be
protected from deletion.

Change-Id: Icad6d6af4b753f23a7febe4d266d45d611bc4fae
diff --git a/Makefile.common b/Makefile.common
index 4c166c5..e34c0d0 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1,6 +1,7 @@
 SHELL := /bin/bash
 
 ROOT_DIR=$(dir $(realpath $(filter %Makefile.common,$(MAKEFILE_LIST))))
+AWS_FC_COMMAND=export AWS_PAGER=;aws cloudformation
 include $(ROOT_DIR)common.env
 
 cluster-keys:
@@ -105,4 +106,26 @@
 endif
 ifdef REPLICA_FILESYSTEM_PROVISIONED_THROUGHPUT_IN_MIBPS
 		$(eval GERRIT_OPTIONAL_PARAMS_REPLICA_FILESYSTEM := $(GERRIT_OPTIONAL_PARAMS_REPLICA_FILESYSTEM) ParameterKey=ReplicaProvisionedThroughputInMibps,ParameterValue=$(REPLICA_FILESYSTEM_PROVISIONED_THROUGHPUT_IN_MIBPS))
-endif
\ No newline at end of file
+endif
+
+confirm-persistent-stack-deletion:
+	@echo ""
+	@echo "* * * * WARNING * * * * this is going to completely destroy the stack, including git data."
+	@echo ""
+	@echo -n "Are you sure you want to continue? [y/N] " && read ans && [ $${ans:-N} = y ]
+
+delete-network-persistent-stack:
+	$(eval NETWORK_STACK_NAME=$(shell $(AWS_FC_COMMAND) list-stacks --stack-status-filter CREATE_COMPLETE --query "StackSummaries[*].StackName" | jq -r '.[]| select(startswith("$(CLUSTER_STACK_NAME)-ECSTaskNetworkStack"))'))
+
+	$(if $(NETWORK_STACK_NAME), \
+		$(AWS_FC_COMMAND) delete-stack \
+			--stack-name $(NETWORK_STACK_NAME) \
+			--region $(AWS_REGION) && \
+		echo "*** Wait for Network stack '$(NETWORK_STACK_NAME)' deletion" && \
+		$(AWS_FC_COMMAND) wait stack-delete-complete \
+			--stack-name $(NETWORK_STACK_NAME) \
+			--region $(AWS_REGION) && \
+		echo "*** Network stack '$(NETWORK_STACK_NAME)' deleted" \
+		, \
+		echo "No network stack found. Nothing to do." \
+	)
\ No newline at end of file
diff --git a/dual-primary/Makefile b/dual-primary/Makefile
index 7f44c6f..6be1334 100644
--- a/dual-primary/Makefile
+++ b/dual-primary/Makefile
@@ -489,12 +489,6 @@
 						$(optional_git_gc_targets_deletion) \
 						delete-cluster wait-for-cluster-deletion
 
-confirm-persistent-stack-deletion:
-	@echo ""
-	@echo "* * * * WARNING * * * * this is going to completely destroy the stack, including git data."
-	@echo ""
-	@echo -n "Are you sure you want to continue? [y/N] " && read ans && [ $${ans:-N} = y ]
-
 delete-all-including-retained-stack: confirm-persistent-stack-deletion delete-all delete-git-primary-persistent-stack delete-git-replica-persistent-stack delete-network-persistent-stack
 
 delete-git-primary-persistent-stack:
@@ -531,22 +525,6 @@
 		echo "No Git persistent stack for replicas found. Nothing to do." \
 	)
 
-delete-network-persistent-stack:
-	$(eval NETWORK_STACK_NAME=$(shell $(AWS_FC_COMMAND) list-stacks --stack-status-filter CREATE_COMPLETE --query "StackSummaries[*].StackName" | jq -r '.[]| select(startswith("$(CLUSTER_STACK_NAME)-ECSTaskNetworkStack"))'))
-
-	$(if $(NETWORK_STACK_NAME), \
-		$(AWS_FC_COMMAND) delete-stack \
-			--stack-name $(NETWORK_STACK_NAME) \
-			--region $(AWS_REGION) && \
-		echo "*** Wait for Network stack '$(NETWORK_STACK_NAME)' deletion" && \
-		$(AWS_FC_COMMAND) wait stack-delete-complete \
-			--stack-name $(NETWORK_STACK_NAME) \
-			--region $(AWS_REGION) && \
-		echo "*** Network stack '$(NETWORK_STACK_NAME)' deleted" \
-		, \
-		echo "No network stack found. Nothing to do." \
-	)
-
 gerrit-publish:
 ifeq ($(MULTISITE_ENABLED),true)
 	$(MAKE) -C ../gerrit gerrit-publish RECIPE=dual-primary PLUGINS="$(MULTI_SITE_PLUGINS)" PLUGINS_LIBS_LINKS="$(MULTI_SITE_PLUGINS_LIBS_LINKS)" MAVEN_LIBS="$(MULTI_SITE_MAVEN_LIBS)"
diff --git a/primary-replica/Makefile b/primary-replica/Makefile
index 16883aa..2e7bd7f 100644
--- a/primary-replica/Makefile
+++ b/primary-replica/Makefile
@@ -172,6 +172,7 @@
 		@echo "METRICS_CLOUDWATCH_ENABLED is set to false. Dashboard creation skipped".
 endif
 
+delete-all-including-retained-stack: confirm-persistent-stack-deletion delete-all delete-network-persistent-stack
 
 wait-for-cluster-creation:
 	@echo "*** Wait for cluster stack '$(CLUSTER_STACK_NAME)' creation"
diff --git a/primary-replica/README.md b/primary-replica/README.md
index a6f7e73..33008ff 100644
--- a/primary-replica/README.md
+++ b/primary-replica/README.md
@@ -123,6 +123,40 @@
 * Secrets stored in Secret Manager
 * SSL certificates
 * ECR repositories
+* VPC and subnets (if created as part of this deployment, rather than externally
+provided)
+
+### Persistent stacks
+
+Blue/green deployment of the primary-replica recipe requires that the blue and
+the green stacks are deployed within the same VPC.
+
+In order to preserve the VPC, the IGW and the subnet upon deletion of
+the blue stack, the nested network cloudformation template needs to be
+protected from deletion.
+
+Note that you can completely delete the stack, including explicitly retained
+resources such as the EFS Git filesystem, VPC and subnets, by issuing the more
+aggressive command:
+
+```
+make [AWS_REGION=a-valid-aws-region] [AWS_PREFIX=some-cluster-prefix] delete-all-including-retained-stack
+```
+
+Note that this will execute a prompt to confirm your choice:
+
+```
+* * * * WARNING * * * * this is going to completely destroy the stack, including git data.
+
+Are you sure you want to continue? [y/N]
+```
+
+If you want to automate this programmatically you can just pipe the `yes`
+command to the make:
+
+```
+yes | make [AWS_REGION=a-valid-aws-region] [AWS_PREFIX=some-cluster-prefix] delete-all-including-retained-stack
+```
 
 ### Access your Gerrit instances
 
diff --git a/primary-replica/cf-cluster.yml b/primary-replica/cf-cluster.yml
index cbd7279..5cbb44c 100644
--- a/primary-replica/cf-cluster.yml
+++ b/primary-replica/cf-cluster.yml
@@ -337,6 +337,7 @@
             Resource: '*'
   ECSTaskNetworkStack:
     Type: AWS::CloudFormation::Stack
+    DeletionPolicy: Retain
     Condition: NetworkStackNeeded
     Properties:
       TemplateURL: !Join [ '', ['https://', !Ref TemplateBucketName, '.s3.amazonaws.com/cf-gerrit-network-stack.yml'] ]