{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "IBM Spectrum Virtualize for Public Cloud on AWS.This template creates a SV cluster on AWS into an existing VPC with one public and one private subnets on same AZ.",
    "Metadata": {
        "AWS::CloudFormation::Interface": {
            "ParameterGroups": [
                {
                    "Label": {
                        "default": "Network Configuration"
                    },
                    "Parameters": [
                        "VPCID",
                        "VPCCidrBlock",
                        "PublicSubnet1ID",
                        "PrivateSubnet1ID",
                        "AllowedIPRange",
                        "EndpointReady"
                    ]
                },
                {
                    "Label": {
                        "default": "Amazon EC2 Configuration"
                    },
                    "Parameters": [
                        "NodeInstanceType",
                        "QuorumInstanceType",
                        "KeyPairName",
                        "CustomerNumber",
                        "NotificationEmail"
                    ]
                },
                {
                    "Label":{
                        "default":"GUI Configuration"
                    },
                    "Parameters": [
                        "SvcGuiPassword"
                    ]
                },
                {
                    "Label": {
                        "default": "I/O Group Configuration"
                    },
                    "Parameters":[
                        "IogrpNumber"
                    ]
                },
                {
                    "Label": {
                        "default": "Backend Storage Configuration"
                    },
                    "Parameters": [
                        "VolumeSize"
                    ]
                },
                {
                    "Label": {
                        "default": "License Information"
                    },
                    "Parameters": [
                        "LicenseAgreementTerms"
                    ]
                }
            ],
            "ParameterLabels": {
                "KeyPairName": {
                    "default": "Key Pair Name"
                },
                "SvcGuiPassword": {
                    "default": "Management GUI Password"
                },
                "NodeInstanceType": {
                    "default": "IBM Spectrum Virtualize for Public Cloud Node Instance Type"
                },
                "QuorumInstanceType": {
                    "default": "Quorum Instance Type"
                },
                "NotificationEmail": {
                    "default": "Notification Email"
                },
                "PublicSubnet1ID": {
                    "default": "Public Subnet 1 ID"
                },
                "PrivateSubnet1ID": {
                    "default": "Private Subnet 1 ID"
                },
                "VPCID": {
                    "default": "VPC ID"
                },
                "VPCCidrBlock": {
                    "default": "CIDR block of VPC"
                },
                "AllowedIPRange": {
                    "default": "The IP address range"
                },
                "EndpointReady": {
                    "default": "Are required VPC endpoints configured?"
                },
                "VolumeSize": {
                    "default": "Backend Storage Configuration"
                },
                "LicenseAgreementTerms": {
                    "default": "License Agreement Terms"
                },
                "CustomerNumber": {
                    "default": "IBM Passport Advantage customer number"
                },
                "IogrpNumber": {
                    "default": "I/O Group Configuration"
                }
            }
        }
    },
    "Parameters": {
        "KeyPairName": {
            "Description": "Select the name of an existing key pair that allows you to securely connect to your instance after it launches.",
            "Type": "AWS::EC2::KeyPair::KeyName"
        },
        "NodeInstanceType": {
            "AllowedValues": [
                "c5.4xlarge",
                "c5.9xlarge",
                "c5.18xlarge"
            ],
            "Default": "c5.9xlarge",
            "Type": "String",
            "Description": "Select the EC2 instance type for IBM Spectrum Virtualize for Public Cloud nodes. The c5.9xlarge instance type is the default selection and is recommended for deployment."
        },
        "QuorumInstanceType": {
            "AllowedValues": [
                "c5.large"
            ],
            "Default": "c5.large",
            "Type": "String",
            "Description": "Select the EC2 instance type for the quorum node. The c5.large instance type is the default selection and is recommended for quorum management."
        },
        "NotificationEmail": {
            "AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)",
            "ConstraintDescription": "Must be a valid email address.",
            "Description": "Enter a valid email address to which notifications are sent.",
            "Type": "String"
        },
        "PublicSubnet1ID": {
            "Description": "Select the corresponding ID for the public subnet that is used for IP quorum management.",
            "Type": "AWS::EC2::Subnet::Id"
        },
        "PrivateSubnet1ID": {
            "Description": "Select the corresponding ID of private subnet 1 that is used for workload management.",
            "Type": "AWS::EC2::Subnet::Id"
        },
        "VPCID": {
            "Description": "Select the identifier for the existing VPC to use for the installation.",
            "Type": "AWS::EC2::VPC::Id"
        },
        "VPCCidrBlock": {
            "AllowedPattern": "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/(1[6-9]|2[0-8]))$",
            "ConstraintDescription": "CIDR block parameter must be in the form x.x.x.x/16-28 (example: 172.31.0.0/16)",
            "Description": "Enter the CIDR block for the VPC that you selected. The CIDR block is displayed in parenthesis in the VPC ID.",
            "Type": "String"
        },
        "AllowedIPRange": {
            "Description": "Enter the IP address range used to connect IBM Spectrum Virtualize for Public Cloud (example for full access: 0.0.0.0/0).",
            "Type": "String",
            "MinLength": "9",
            "MaxLength": "18",
            "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
            "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
        },
        "VolumeSize": {
            "Description": "Enter the size of each volume. As part of the initial installation, two volumes are ordered and attached. Other volumes can be added after installation. The supported volume sizes are 512 - 16384 GB.",
            "Type": "Number",
            "Default": "512",
            "MinValue": "512",
            "MaxValue": "16384",
            "ConstraintDescription": "Allowed volume size are MIN=512,MAX=16384 (GB)"
        },
        "LicenseAgreementTerms": {
            "AllowedValues": [
                "Accept"
            ],
            "Description": "Review License Information documents and select Accept if you agree to the licensing terms. License Information documents: https://www.ibm.com/software/sla/sladb.nsf/displaylis/42B0DD56927424C98525841000178A9F?OpenDocument.",
            "Type": "String"
        },
        "EndpointReady": {
            "AllowedValues": [
                "Yes"
            ],
            "Description": "Private endpoints to several services are required for installation. Select Yes to verify these endpoints are configured. For information on these required services, see Planning an installation on Amazon Web Services (AWS) https://www.ibm.com/support/knowledgecenter/STHLEK_8.3.1/spectrum.virtualize.cloud.831.doc/svcl_planning_AWS.html",
            "Type": "String"
        },
        "CustomerNumber": {
            "AllowedPattern": "^[0-9a-zA-Z]*$",
            "Description": "Enter the IBM Passport Advantage customer number to validate entitlement for the BYOL offering.",
            "Type": "String",
            "MinLength": "1"
        },
        "IogrpNumber": {
            "AllowedValues": [
                "1",
                "2"
            ],
            "Description": "Select the number of I/O groups in the IBM Spectrum Virtualize for Public Cloud cluster.  Each I/O group contains two IBM Spectrum Virtualize for Public Cloud nodes.",
            "Type": "String"
        },
        "SvcGuiPassword": {
            "AllowedPattern": "^[0-9a-zA-Z]*$",
            "Description": "Enter a password for the Security Administrator user profile (superuser), who completes the configuration of the IBM Spectrum Virtualize for Public Cloud software with the management GUI. Passwords must be 6 - 64 ASCII characters in length. Note: You must enter a password.  Default passwords are not supported.",
            "Type": "String",
            "MinLength": "6",
            "MaxLength": "64",
            "NoEcho" : "true"
        }
    },
    "Mappings": {
        "IOGroupMap": {
            "1": {
                "S3URL": "https://cn-mp-cft.s3.cn-northwest-1.amazonaws.com.cn/CN-IBM-Spectrum-Virtualize-for-Public-Cloud/2node.nested.template"
            },
            "2": {
                "S3URL": "https://cn-mp-cft.s3.cn-northwest-1.amazonaws.com.cn/CN-IBM-Spectrum-Virtualize-for-Public-Cloud/4node.nested.template"
            }
        }
    },
    "Conditions": {
        "Twoiogrp": {
            "Fn::Equals": [
                {
                    "Ref": "IogrpNumber"
                },
                "2"
            ]
        }
    },
    "Resources": {
        "WorkloadStack": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": {
                    "Fn::FindInMap": [
                        "IOGroupMap",
                        {
                            "Ref": "IogrpNumber"
                        },
                        "S3URL"
                    ]
                },
                "Parameters": {
                    "KeyPairName": {
                        "Ref": "KeyPairName"
                    },
                    "SvcGuiPassword": {
                        "Ref": "SvcGuiPassword"
                    },
                    "NodeInstanceTypeIogrp0": {
                        "Ref": "NodeInstanceType"
                    },
                    "NodeInstanceTypeIogrp1": {
                        "Ref": "NodeInstanceType"
                    },
                    "QuorumInstanceType": {
                        "Ref": "QuorumInstanceType"
                    },
                    "NotificationEmail": {
                        "Ref": "NotificationEmail"
                    },
                    "PublicSubnet1ID": {
                        "Ref": "PublicSubnet1ID"
                    },
                    "PrivateSubnet1ID": {
                        "Ref": "PrivateSubnet1ID"
                    },
                    "VPCID": {
                        "Ref": "VPCID"
                    },
                    "VPCCidrBlock": {
                        "Ref": "VPCCidrBlock"
                    },
                    "AllowedIPRange": {
                        "Ref": "AllowedIPRange"
                    },
                    "VolumeSize": {
                        "Ref": "VolumeSize"
                    },
                    "LicenseAgreementTerms": {
                        "Ref": "LicenseAgreementTerms"
                    },
                    "CustomerNumber": {
                        "Ref": "CustomerNumber"
                    }
                }
            }
        }
    },
    "Outputs": {
        "IBMSVVersion": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVVersion"
                ]
            },
            "Description": "IBM SV Cloud version"
        },
        "IBMSVQuorumClientEC2IP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVQuorumClientEC2IP"
                ]
            },
            "Description": "IBM SV Quorum Client EC2 Private IP"
        },
        "IBMSVClusterIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVClusterIP"
                ]
            },
            "Description": "IBM SV Cloud Cluster IP"
        },
        "IBMSVNode1ServiceIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode1ServiceIP"
                ]
            },
            "Description": "IBM SV Node1 Service IP"
        },
        "IBMSVNode1Port1NodeIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode1Port1NodeIP"
                ]
            },
            "Description": "IBM SV Node1 Port1 Node IP"
        },
        "IBMSVNode1Port2NodeIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode1Port2NodeIP"
                ]
            },
            "Description": "IBM SV Node1 Port2 Node IP"
        },
        "IBMSVNode1PortIP1": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode1PortIP1"
                ]
            },
            "Description": "IBM SV Node1 Port IP1"
        },
        "IBMSVNode1PortIP2": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode1PortIP2"
                ]
            },
            "Description": "IBM SV Node1 Port IP2"
        },
        "IBMSVNode2ServiceIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode2ServiceIP"
                ]
            },
            "Description": "IBM SV Node2 Service IP"
        },
        "IBMSVNode2Port1NodeIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode2Port1NodeIP"
                ]
            },
            "Description": "IBM SV Node2 Port1 Node IP"
        },
        "IBMSVNode2Port2NodeIP": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode2Port2NodeIP"
                ]
            },
            "Description": "IBM SV Node2 Port2 Node IP"
        },
        "IBMSVNode2PortIP1": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode2PortIP1"
                ]
            },
            "Description": "IBM SV Node2 Port IP1"
        },
        "IBMSVNode2PortIP2": {
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode2PortIP2"
                ]
            },
            "Description": "IBM SV Node2 Port IP2"
        },
        "IBMSVNode3ServiceIP": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode3ServiceIP"
                ]
            },
            "Description": "IBM SV Node3 Service IP"
        },
        "IBMSVNode3Port1NodeIP": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode3Port1NodeIP"
                ]
            },
            "Description": "IBM SV Node3 Port1 Node IP"
        },
        "IBMSVNode3Port2NodeIP": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode3Port2NodeIP"
                ]
            },
            "Description": "IBM SV Node3 Port2 Node IP"
        },
        "IBMSVNode3PortIP1": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode3PortIP1"
                ]
            },
            "Description": "IBM SV Node3 Port IP1"
        },
        "IBMSVNode3PortIP2": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode3PortIP2"
                ]
            },
            "Description": "IBM SV Node3 Port IP2"
        },
        "IBMSVNode4ServiceIP": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode4ServiceIP"
                ]
            },
            "Description": "IBM SV Node4 Service IP"
        },
        "IBMSVNode4Port1NodeIP": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode4Port1NodeIP"
                ]
            },
            "Description": "IBM SV Node4 Port1 Node IP"
        },
        "IBMSVNode4Port2NodeIP": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode4Port2NodeIP"
                ]
            },
            "Description": "IBM SV Node4 Port2 Node IP"
        },
        "IBMSVNode4PortIP1": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode4PortIP1"
                ]
            },
            "Description": "IBM SV Node4 Port IP1"
        },
        "IBMSVNode4PortIP2": {
            "Condition": "Twoiogrp",
            "Value": {
                "Fn::GetAtt": [
                    "WorkloadStack",
                    "Outputs.IBMSVNode4PortIP2"
                ]
            },
            "Description": "IBM SV Node4 Port IP2"
        }
    }
}
