Repository: NVIDIA/NVFlare

Issue:
[BUG] aws default vpc should not be required. 
**Describe the bug**

nvflare commands bomb out, if no default VPC is defined in my AWS account. Many AWS accounts (per AWS recommendation) have no default VPC assigned, however they may have exactly one VPC assigned. In that case (check `aws ec2 describe-vpcs`) you do not have to ask the user and just pick that one. If there is none you can tell the user to create a default vpc if they have the permissions to do so:  `aws ec2 create-default-vpc` or have their admin create one 

**To Reproduce**

```
 dp@grammy:~/NVFlare$ nvflare dashboard --cloud aws
Dashboard launch script for cloud is written at /home/dp/NVFlare/aws_start_dsb.sh.  Now running the script.
This script requires aws (AWS CLI), sshpass, dig and jq.  Now checking if they are installed.
Checking if aws exists. => found
Checking if sshpass exists. => found
Checking if dig exists. => found
Checking if jq exists. => found
One initial user will be created when starting dashboard.
Please enter the email address for this user.
xxxxx@domain.edu
Generating key pair for VM

An error occurred (VPCIdNotSpecified) when calling the CreateSecurityGroup operation: No default VPC for this user
Security group id:

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: argument --group-id: expected one argument


usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: argument --group-id: expected one argument

```

**Desktop (please complete the following information):**
 - OS: [e.g. wsl  windows 11]
 - Python Version [e.g. 3.9]
 - NVFlare Version [e.g. 2.4]

**Other comments:**

Ask ChatGPT/Claude: 

Does aws recommend to not create a default vpc for enterprise aws accounts? 

Yes, AWS generally recommends not creating a default VPC for enterprise AWS accounts. Instead, they recommend creating custom VPCs tailored to your specific network requirements.
Here are a few reasons why:

Security: Default VPCs have predetermined settings, which might not align with your organization's security policies. Creating a custom VPC allows you to configure security groups, network ACLs, and other settings as per your needs.
IP Address Range: Default VPCs come with a predetermined IP address range. This might lead to IP address conflicts if you have multiple AWS accounts or if you need to connect your AWS resources with your on-premises network. With a custom VPC, you can choose your IP address range.
VPC Peering: If you need to set up VPC peering between multiple VPCs, using default VPCs can make the process more complex due to potential overlapping IP address ranges.
Compliance: Depending on your industry, you might have to adhere to certain compliance requirements. Default VPCs might not be set up to meet these requirements out of the box.
Customization: Custom VPCs give you complete control over your network setup, including subnets, route tables, gateways, and more. This level of customization is essential for many enterprise setups.

For these reasons, AWS recommends creating custom VPCs for enterprise accounts, as it provides more flexibility, security, and control over your network infrastructure. Cop




Discussion:

Resolving patch:
diff --git a/nvflare/dashboard/cli.py b/nvflare/dashboard/cli.py
--- a/nvflare/dashboard/cli.py
+++ b/nvflare/dashboard/cli.py
@@ -138,6 +138,8 @@ def stop():
 def cloud(args):
     lighter_folder = os.path.dirname(utils.__file__)
     template = utils.load_yaml(os.path.join(lighter_folder, "impl", "master_template.yml"))
+    template.update(utils.load_yaml(os.path.join(lighter_folder, "impl", "aws_template.yml")))
+    template.update(utils.load_yaml(os.path.join(lighter_folder, "impl", "azure_template.yml")))
     tplt = tplt_utils.Template(template)
     cwd = os.getcwd()
     csp = args.cloud


Test patch: