{
    "Parameters": {
        "datazoneEnvironmentEnvironmentId": {
            "Type": "String",
            "Description": "EnvironmentId for which the resource will be created for."
        },
        "datazoneEnvironmentProjectId": {
            "Type": "String",
            "Description": "DZ projectId for which project the resource will be created for."
        },
        "userRoleArn": {
            "Type": "String",
            "Description": "Project Role ARN"
        },
        "s3BucketArn": {
            "Type": "String",
            "Description": "Project S3 Bucket ARN"
        },
        "privateSubnets": {
            "Type": "String",
            "Description": "Project Private Subnets"
        },
        "glueDbName": {
            "Type": "String",
            "Default": "gluedb",
            "Description": "Glue DB name"
        },
        "redshiftWorkgroupName": {
            "Type": "String",
            "Default": "datazone-workgroup",
            "Description": "Redshift workgroup name"
        },
        "redshiftWorkgroupNamespaceName": {
            "Type": "String",
            "Default": "datazone-namespace",
            "Description": "Redshift workgroup namespace name"
        }
    },
    "Resources": {
        "GlueDatabase": {
            "Type": "AWS::Glue::Database",
            "Properties": {
                "CatalogId": {
                    "Ref": "AWS::AccountId"
                },
                "DatabaseInput": {
                    "CreateTableDefaultPermissions": [],
                    "Description": {
                        "Fn::Join": [
                            "",
                            [
                                "Created by DataZone for project ",
                                {
                                    "Ref": "datazoneEnvironmentProjectId"
                                }
                            ]
                        ]
                    },
                    "LocationUri": {
                        "Fn::Join": [
                            "",
                            [
                                "s3://",
                                {
                                    "Fn::Select": [
                                        5,
                                        {
                                            "Fn::Split": [
                                                ":",
                                                {
                                                    "Ref": "s3BucketArn"
                                                }
                                            ]
                                        }
                                    ]
                                },
                                "data/catalogs/"
                            ]
                        ]
                    },
                    "Name": {
                        "Fn::Sub": "${glueDbName}-${datazoneEnvironmentEnvironmentId}"
                    }
                }
            }
        },
        "GlueAccessManagedPolicy": {
            "Type": "AWS::IAM::ManagedPolicy",
            "Properties": {
                "ManagedPolicyName": {
                    "Fn::Sub": "GlueAccess-${glueDbName}-${datazoneEnvironmentEnvironmentId}-Policy"
                },
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "glue:GetDatabase",
                                "glue:GetTables",
                                "glue:GetTable",
                                "glue:CreateTable",
                                "glue:UpdateTable",
                                "glue:DeleteTable",
                                "glue:BatchDeleteTable",
                                "glue:GetPartitions",
                                "glue:GetPartition",
                                "glue:BatchCreatePartition",
                                "glue:BatchDeletePartition"
                            ],
                            "Resource": [
                                {
                                    "Fn::Sub": "arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog"
                                },
                                {
                                    "Fn::Sub": "arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/${glueDbName}-${datazoneEnvironmentEnvironmentId}"
                                },
                                {
                                    "Fn::Sub": "arn:aws:glue:${AWS::Region}:${AWS::AccountId}:table/${glueDbName}-${datazoneEnvironmentEnvironmentId}/*"
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "LakeFormationGlueDatabasePermissions": {
            "Type": "AWS::LakeFormation::Permissions",
            "Properties": {
                "DataLakePrincipal": {
                    "DataLakePrincipalIdentifier": {
                        "Ref": "userRoleArn"
                    }
                },
                "Resource": {
                    "DatabaseResource": {
                        "CatalogId": {
                            "Ref": "AWS::AccountId"
                        },
                        "Name": {
                            "Fn::Sub": "${glueDbName}-${datazoneEnvironmentEnvironmentId}"
                        }
                    }
                },
                "Permissions": [
                    "DESCRIBE",
                    "CREATE_TABLE"
                ]
            },
            "DependsOn": [
                "GlueDatabase"
            ]
        },
        "LakeFormationGlueTablePermissions": {
            "Type": "AWS::LakeFormation::Permissions",
            "Properties": {
                "DataLakePrincipal": {
                    "DataLakePrincipalIdentifier": {
                        "Ref": "userRoleArn"
                    }
                },
                "Resource": {
                    "TableResource": {
                        "CatalogId": {
                            "Ref": "AWS::AccountId"
                        },
                        "DatabaseName": {
                            "Fn::Sub": "${glueDbName}-${datazoneEnvironmentEnvironmentId}"
                        },
                        "TableWildcard": {}
                    }
                },
                "Permissions": [
                    "ALL"
                ]
            },
            "DependsOn": [
                "GlueDatabase"
            ]
        },
        "RedshiftServerlessNamespace": {
            "Type": "AWS::RedshiftServerless::Namespace",
            "Properties": {
                "NamespaceName": {
                    "Fn::Join": [
                        "",
                        [
                            {
                                "Ref": "redshiftWorkgroupNamespaceName"
                            },
                            "-",
                            {
                                "Ref": "datazoneEnvironmentEnvironmentId"
                            }
                        ]
                    ]
                },
                "Tags": [
                    {
                        "Key": "AmazonDataZoneProject",
                        "Value": {
                            "Ref": "datazoneEnvironmentProjectId"
                        }
                    },
                    {
                        "Key": "AmazonDataZoneEnvironment",
                        "Value": {
                            "Ref": "datazoneEnvironmentEnvironmentId"
                        }
                    }
                ]
            }
        },
        "RedshiftServerlessWorkgroup": {
            "Type": "AWS::RedshiftServerless::Workgroup",
            "Properties": {
                "WorkgroupName": {
                    "Fn::Join": [
                        "",
                        [
                            {
                                "Ref": "redshiftWorkgroupName"
                            },
                            "-",
                            {
                                "Ref": "datazoneEnvironmentEnvironmentId"
                            }
                        ]
                    ]
                },
                "NamespaceName": {
                    "Fn::Join": [
                        "",
                        [
                            {
                                "Ref": "redshiftWorkgroupNamespaceName"
                            },
                            "-",
                            {
                                "Ref": "datazoneEnvironmentEnvironmentId"
                            }
                        ]
                    ]
                },
                "SecurityGroupIds": [
                    {
                        "Fn::ImportValue": {
                            "Fn::Join": [
                                "",
                                [
                                    "securityGroup-",
                                    {
                                        "Ref": "datazoneEnvironmentProjectId"
                                    },
                                    "-dev"
                                ]
                            ]
                        }
                    }
                ],
                "SubnetIds": {
                    "Fn::Split": [
                        ",",
                        {
                            "Ref": "privateSubnets"
                        }
                    ]
                },
                "PubliclyAccessible": false,
                "Tags": [
                    {
                        "Key": "AmazonDataZoneProject",
                        "Value": {
                            "Ref": "datazoneEnvironmentProjectId"
                        }
                    },
                    {
                        "Key": "AmazonDataZoneEnvironment",
                        "Value": {
                            "Ref": "datazoneEnvironmentEnvironmentId"
                        }
                    }
                ]
            },
            "DependsOn": [
                "RedshiftServerlessNamespace"
            ]
        },
        "RedshiftAccessManagedPolicy": {
            "Type": "AWS::IAM::ManagedPolicy",
            "Properties": {
                "ManagedPolicyName": {
                    "Fn::Sub": "RedshiftAccess-${redshiftWorkgroupName}-${datazoneEnvironmentEnvironmentId}-Policy"
                },
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "redshift-serverless:GetCredentials",
                                "redshift-serverless:GetWorkgroup",
                                "redshift-serverless:ListWorkgroups",
                                "redshift-serverless:GetNamespace",
                                "redshift-serverless:ListNamespaces",
                                "redshift-data:BatchExecuteStatement",
                                "redshift-data:ExecuteStatement",
                                "redshift-data:CancelStatement",
                                "redshift-data:ListStatements",
                                "redshift-data:GetStatementResult",
                                "redshift-data:DescribeStatement"
                            ],
                            "Resource": [
                                {
                                    "Fn::Sub": "arn:aws:redshift-serverless:${AWS::Region}:${AWS::AccountId}:namespace/${redshiftWorkgroupNamespaceName}-${datazoneEnvironmentEnvironmentId}"
                                },
                                {
                                    "Fn::Sub": "arn:aws:redshift-serverless:${AWS::Region}:${AWS::AccountId}:workgroup/${redshiftWorkgroupName}-${datazoneEnvironmentEnvironmentId}"
                                }
                            ]
                        }
                    ]
                }
            }
        }
    },
    "Outputs": {
        "GlueDatabaseName": {
            "Description": "Name of the created Glue Database",
            "Value": {
                "Ref": "GlueDatabase"
            },
            "Export": {
                "Name": {
                    "Fn::Sub": "${glueDbName}-${datazoneEnvironmentEnvironmentId}"
                }
            }
        },
        "RedshiftNamespaceName": {
            "Description": "Name of the created Redshift Serverless namespace",
            "Value": {
                "Ref": "RedshiftServerlessNamespace"
            },
            "Export": {
                "Name": {
                    "Fn::Sub": "redshift-namespace-${datazoneEnvironmentEnvironmentId}"
                }
            }
        },
        "RedshiftWorkgroupName": {
            "Description": "Name of the created Redshift Serverless workgroup",
            "Value": {
                "Ref": "RedshiftServerlessWorkgroup"
            },
            "Export": {
                "Name": {
                    "Fn::Sub": "redshift-workgroup-${datazoneEnvironmentEnvironmentId}"
                }
            }
        },
        "GlueAccessManagedPolicy": {
            "Description": "ARN of the created managed policy",
            "Value": {
                "Ref": "GlueAccessManagedPolicy"
            },
            "Export": {
                "Name": {
                    "Fn::Sub": "datazone-managed-policy-glue-${glueDbName}-${datazoneEnvironmentEnvironmentId}"
                }
            }
        },
        "RedshiftAccessManagedPolicy": {
            "Description": "ARN of the created Redshift managed policy",
            "Value": {
                "Ref": "RedshiftAccessManagedPolicy"
            },
            "Export": {
                "Name": {
                    "Fn::Sub": "datazone-managed-policy-redshift-${redshiftWorkgroupName}-${datazoneEnvironmentEnvironmentId}"
                }
            }
        }
    }
}