{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "This template creates a custom sql server RDS instance and uses the output from the Amazon RDS Custom for SQL Server using an AWS CloudFormation template (Network setup) link: https://aws.amazon.com/blogs/database/get-started-with-amazon-rds-custom-for-sql-server-using-an-aws-cloudformation-template-network-setup",
    "Parameters": {
        "CrossReferenceStackName": {
            "Description": "Name of an active CloudFormation stack that contains the networking resources, such as the subnet and security group, that will be used in this stack. Leave this option blank incase you would like to manually input the resources",
            "Type": "String"
        },
        "Engine": {
            "Type": "String",
            "Default": "custom-sqlserver-se",
            "AllowedValues": [
                "custom-sqlserver-ee",
                "custom-sqlserver-se",
                "custom-sqlserver-web"
            ],
            "Description": "Enter engine type custom-sqlserver-ee,custom-sqlserver-se,custom-sqlserver-web.Default is custom-sqlserver-se"
        },
        "StorageType": {
            "Type": "String",
            "Default": "gp2",
            "AllowedValues": [
                "gp2",
                "gp3",
                "io1"
            ],
            "Description": "Choose the type of storage, the only storage types supported are solid state drives (SSD) of types gp2, gp3 and io1."
        },
        "AllocatedStorage": {
            "Type": "String",
            "Description": "Enter the allocated storage.The maximum storage limit is 16 TiB."
        },
        "Iops": {
            "Type": "String",
            "Description": "If you specify io1 for the StorageType property, then you must also specify the Iops property"
        },
        "EngineVersion": {
            "Type": "String",
            "ConstraintDescription": "You can provide the engine version or the name of your CEV. The name format for the CEV is 19.*customized_string* . For example, a valid CEV name is 19.my_cev1 ."
        },
        "StorageThroughput": {
            "Type": "String",
            "Description": " Specifies the storage throughput value for the DB instance. This setting applies only to the gp3 storage type. "
        },
        "MasterUsername": {
            "Type": "String",
            "Description": "The database admin account username",
            "MinLength": "1",
            "MaxLength": "10",
            "ConstraintDescription": "Must begin with a letter and contain only alphanumeric characters."
        },
        "DBInstanceClass": {
            "Type": "String",
            "Description": "The instance class type for the custom sql server instance"
        },
        "CustomIAMInstanceProfile": {
            "Type": "String",
            "Description": "The instance profile associated with the underlying Amazon EC2 instance of an RDS Custom DB instance. You have to provide this value incase there is no cross-stack reference where this resource is created."
        },
        "VPCSecurityGroups": {
            "Type": "String",
            "Description": "VPC security group IDs to assign to the DB instance.You have to provide this value incase there is no cross-stack reference where this resource is created."
        },
        "KmsKeyId": {
            "Type": "String",
            "Description": "The ARN of the AWS KMS key that's used to encrypt the DB instance, such as arn:aws:kms:us-east-1:012345678910:key/abcd1234-a123-456a-a12b-a123b4cd56ef. You have to provide this value incase there is no cross-stack reference where this resource is created."
        },
        "DBSubnetGroupName": {
            "Type": "String",
            "Description": "A DB subnet group to associate with the DB instance.You have to provide this value incase there is no cross-stack reference where this resource is created."
        },
        "MultiAZ": {
            "Type": "String",
            "Description": "Specify whether the database instance is a Multi-AZ DB instance deployment. Please enter either true or false",
            "Default": "false",
            "AllowedValues": ["true","false"]   
        }
    },
    "Conditions": {
        "NumberofIops": {
            "Fn::Equals": [
                {
                    "Ref": "StorageType"
                },
                "io1"
            ]
        },
        "UseCrossStack": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "CrossReferenceStackName"
                        },
                        ""
                    ]
                }
            ]
        },
        "Throughput": {
            "Fn::Equals": [
                {
                    "Ref": "StorageThroughput"
                },
                "gp3"
            ]
        }
    },
    "Metadata": {
        "AWS::CloudFormation::Interface": {
            "ParameterGroups": [
                {
                    "Label": {
                        "default": "Cross Reference Stack Name"
                    },
                    "Parameters": [
                        "CrossReferenceStackName"
                    ]
                },
                {
                    "Label": {
                        "default": "Cross Reference Stack Parameters (Leave the rest of parameters blank if you pass the above CrossReferenceStackName)"
                    },
                    "Parameters": [
                        "CustomIAMInstanceProfile",
                        "KmsKeyId",
                        "DBSubnetGroupName",
                        "VPCSecurityGroups"
                    ]
                },
                {
                    "Label": {
                        "default": "Parameters for RDS Custom for SQL server"
                    },
                    "Parameters": [
                        "Engine",
                        "EngineVersion",
                        "DBInstanceClass",
                        "MultiAZ",
                        "StorageType",
                        "Iops",
                        "AllocatedStorage",
                        "StorageThroughput",
                        "MasterUsername"
                    ]
                }
            ]
        }
    },
    "Resources": {
        "RDSInstancePasswordSecret": {
            "Type": "AWS::SecretsManager::Secret",
            "Properties": {
                "KmsKeyId": {
                    "Ref": "KmsKeyId"
                },
                "GenerateSecretString": {
                    "SecretStringTemplate": {
                        "Fn::Join": [
                            "",
                            [
                                "{\"username\": \"",
                                {
                                    "Ref": "MasterUsername"
                                },
                                "\"}"
                            ]
                        ]
                    },
                    "GenerateStringKey": "password",
                    "PasswordLength": 16,
                    "ExcludeCharacters": "\"@/\\"
                }
            }
        },
        "customsqlsever": {
            "Type": "AWS::RDS::DBInstance",
            "Properties": {
                "AllocatedStorage": {
                    "Ref": "AllocatedStorage"
                },
                "StorageType": {
                    "Ref": "StorageType"
                },
                "DBInstanceClass": {
                    "Ref": "DBInstanceClass"
                },
                "Engine": {
                    "Ref": "Engine"
                },
                "Iops": {
                    "Fn::If": [
                        "NumberofIops",
                        {
                            "Ref": "Iops"
                        },
                        {
                            "Ref": "AWS::NoValue"
                        }
                    ]
                },
                "StorageEncrypted" : true,
                "MultiAZ" : {
                    "Ref": "MultiAZ"
                },
                "StorageThroughput": {
                    "Fn::If": [
                        "Throughput",
                        {
                            "Ref": "StorageThroughput"
                        },
                        {
                            "Ref": "AWS::NoValue"
                        }
                    ]
                },
                "CustomIAMInstanceProfile": {
                    "Fn::If": [
                        "UseCrossStack",
                        {
                            "Fn::ImportValue": {
                                "Fn::Sub": "${CrossReferenceStackName}-RDSCustomIAMInstanceProfile"
                            }
                        },
                        {
                            "Ref": "CustomIAMInstanceProfile"
                        }
                    ]
                },
                "KmsKeyId": {
                    "Fn::If": [
                        "UseCrossStack",
                        {
                            "Fn::ImportValue": {
                                "Fn::Sub": "${CrossReferenceStackName}-RDSCustomKMSKey"
                            }
                        },
                        {
                            "Ref": "KmsKeyId"
                        }
                    ]
                },
                "EngineVersion": {
                    "Ref": "EngineVersion"
                },
                "MasterUsername": {
                    "Ref": "MasterUsername"
                },
                "MasterUserPassword": {
                    "Fn::Join": [
                        "",
                        [
                            "{{resolve:secretsmanager:",
                            {
                                "Ref": "RDSInstancePasswordSecret"
                            },
                            ":SecretString:password}}"
                        ]
                    ]
                },
                "PubliclyAccessible": false,
                "VPCSecurityGroups": [
                    {
                        "Fn::If": [
                            "UseCrossStack",
                            {
                                "Fn::ImportValue": {
                                    "Fn::Sub": "${CrossReferenceStackName}-RDSCustomSecurityGroup"
                                }
                            },
                            {
                                "Ref": "VPCSecurityGroups"
                            }
                        ]
                    }
                ],
                "DBSubnetGroupName": {
                    "Fn::If": [
                        "UseCrossStack",
                        {
                            "Fn::ImportValue": {
                                "Fn::Sub": "${CrossReferenceStackName}-SubnetID"
                            }
                        },
                        {
                            "Ref": "DBSubnetGroupName"
                        }
                    ]
                },
                "AllowMajorVersionUpgrade": false
            }
        }
    },
    "Outputs": {
        "StackName": {
            "Description": "Stack Name",
            "Value": {
                "Fn::Sub": "${AWS::StackName}"
            }
        },
        "RDSInstancePasswordSecret": {
            "Description": "Secrets Manager with RDS master login.",
            "Value": {
                "Ref": "RDSInstancePasswordSecret"
            }
        },
        "DBInstanceIdentifier": {
            "Description": "The database instance identifier",
            "Value": {
                "Ref": "customsqlsever"
            },
            "Export": {
                "Name": {
                    "Fn::Sub": [
                        "${AWS::StackName}-${Engine}-identifier",
                        {
                            "engine": {
                                "Ref": "Engine"
                            }
                        }
                    ]
                }
            }
        }
    }
}