AWSTemplateFormatVersion: 2010-09-09
Description: 'Master manifest for ADP Base Platform'
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: General configuration
        Parameters:
          - ResourcePrefix
          - AvailabilityZones
          - ADPS3BucketName
          - ADPS3BucketRegion
          - BasePlatformVersion
          - QSS3BucketName
          - QSS3KeyPrefix
          - QSS3BucketRegion
          - DockerRegistry
          - KubernetesVersion
          - EKSAdminUser
          - PlatformOwner
      - Label:
          default: Access configuration
        Parameters:
          - KeyPairName
          - Route53HostedZoneName
          - DnsZoneType
          - EnableExternalAccess
          - RemoteAccessCIDR1
          - RemoteAccessCIDR2
          - RemoteAccessCIDR3
          - RemoteAccessCIDR4
          - RemoteAccessCIDR5
      - Label:
          default: Lambda Components configuration (Don't change this values unnecessarily)
        Parameters:
          - EnableAirflow
          - EnableMlflow
          - EnableElastic
          - EnableKibana
          - EnableEMR
          - EnableKinesis
          - EnableKubernetes
          - EnableKubernetesExtra
          - EnableRedshift
          - EnableSagemaker
          - EnableZooKeeper
          - EnableKafka
          - EnableCassandra
          - EnableAtlas
          - EnableGrafana

Parameters:
  # Platform components (Don't change this values unnecessarily)
  EnableAirflow:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableMlflow:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableElastic:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableKibana:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableEMR:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableKinesis:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableKubernetes:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableKubernetesExtra:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableRedshift:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableSagemaker:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableZooKeeper:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableKafka:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableCassandra:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableAtlas:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  EnableGrafana:
    Type: String
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'

  # Platform parameters
  AvailabilityZones:
    Type: List<AWS::EC2::AvailabilityZone::Name>
    Description:
      'List of Availability Zones to use for the subnets in the VPC. Three
      Availability Zones are used for this deployment, and the logical order of your
      selections is preserved. Possible problems due to the choice of us-east-1e zone.'
  ResourcePrefix:
    Type: String
    AllowedPattern: ^[0-9a-z]+([0-9a-z\-]*[0-9a-z])*$
    MinLength: '2'
    MaxLength: '9'
    ConstraintDescription:
      'Bucket names can consist only of lowercase letters, numbers, dots (.), and hyphens (-).
      Bucket names must begin and end with a letter or number.'
    Description:
      'Base Platform deployment identifier.
      This variable is part of S3 state bucket name, so it should follow S3 naming restrictions.
      Also this prefix will be using at some names of roles, lambdas and other resources.
      Length from 2 to 9 symbols.
      Prefix can consist only of lowercase letters, numbers, dots (.), and hyphens (-)
      and must begin and end with a letter or number.'
  BasePlatformVersion:
    Type: String
    Description: 'BasePlatform build version.'
    Default: '2023-02-16-marketplace'
  ADPS3BucketName:
    Type: String
    AllowedPattern: ^[0-9a-z]+([0-9a-z\-]*[0-9a-z])*$
    ConstraintDescription:
      'Bucket name can include numbers, lowercase letters, and hyphens (-).
       It cannot start or end with a hyphen (-).'
    Description:
      'ADP bucket name with cloudformation scripts can include numbers,
      lowercase letters, and hyphens (-). It cannot start or end with a hyphen (-).'
    Default: 'griddynamics-analytical-data-platform-releases'
  ADPS3BucketRegion:
    Type: String
    Description: 'The AWS Region where the source ADP S3 bucket (ADPS3BucketName) is hosted.'
    Default: 'us-east-1'
  QSS3BucketName:
    Type: String
    AllowedPattern: ^[0-9a-z]+([0-9a-z\-]*[0-9a-z])*$
    ConstraintDescription:
      'Bucket name can include numbers, lowercase letters, and hyphens (-).
       It cannot start or end with a hyphen (-).'
    Description:
      'S3 bucket name for the Quick Start assets. This string can include numbers, lowercase letters,
      and hyphens (-). It cannot start or end with a hyphen (-).'
    Default: 'griddynamics-analytical-data-platform-releases'
  QSS3KeyPrefix:
    Type: String
    AllowedPattern: ^[0-9a-z]+[0-9a-z\.\-\/]*/$
    ConstraintDescription:
      Quick Start key prefix can include numbers, lowercase letters,
      hyphens (-), and forward slash (/).
    Description:
      'S3 key prefix for the Quick Start assets. Quick Start key prefix
      can include numbers, lowercase letters, hyphens (-), and  must have
      forward slash (/) at the end.'
    Default: 'quickstart-amazon-eks-v-3-1-0/'
  QSS3BucketRegion:
    Type: String
    Description:
      'The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is
      hosted. When using your own bucket, you must specify this value.'
    Default: 'us-east-1'
  DockerRegistry:
    Type: String
    Description: 'Docker Registry/AWS Elastic Container Registry.'
    Default: '125667932402.dkr.ecr.us-east-1.amazonaws.com'
  Route53HostedZoneName:
    Type: String
    Description: 'Route53 Zone Name'
    Default: 'adp.local'
  DnsZoneType:
    Type: String
    Description:
      'Choose public if you already delegated responsibility for the subdomain to Route 53. This subdomain
      should be configured in Route53HostedZoneName. Otherwise choose a private DNS zone to be created in Route 53.'
    AllowedValues: [ "public", "private" ]
    Default: 'private'
  KubernetesVersion:
    Type: String
    AllowedValues: [ "1.20", "1.21" ]
    Default: "1.21"
  EKSAdminUser:
    Type: String
    Description: '[OPTIONAL] Enter Platform Admin IAM User for attaching fully access to EKS Cluster'
  PlatformOwner:
    Type: String
    Description: 'Enter your platform owner for checking costs'
    Default: "gdadp"

  # Access
  KeyPairName:
    Type: AWS::EC2::KeyPair::KeyName
    Description:
      'The name of an existing public/private key pair, which allows you
      to securely connect to your instance after it launches'
    Default: ''
  EnableExternalAccess:
    Type: String
    Description:
      'Allow or deny access to UIs from outside of VPC (disables ELB for EKS-based applications).
      Disabled by default to minimize unauthorized access.'
    AllowedValues: [ "Enabled", "Disabled" ]
    Default: 'Disabled'
  RemoteAccessCIDR1:
    Type: String
    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])(\/([0-9]|[1-2][0-9]|3[0-2]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x
    Description:
      'CIDR address notation. Required to limit access to Bastion host.
      Highly recommended to limit access due to security reasons.'
  RemoteAccessCIDR2:
    Type: String
    Description:
      '[OPTIONAL] Second CIDR address notation.'
    Default: ""
  RemoteAccessCIDR3:
    Type: String
    Description:
      '[OPTIONAL] Third CIDR address notation.'
    Default: ""
  RemoteAccessCIDR4:
    Type: String
    Description:
      '[OPTIONAL] Fourth CIDR address notation.'
    Default: ""
  RemoteAccessCIDR5:
    Type: String
    Description:
      '[OPTIONAL] Fifth CIDR address notation.'
    Default: ""

Conditions:
  RunningInAnotherRegion: !Not [!Equals [!Ref ADPS3BucketRegion, !Ref "AWS::Region"]]
  EnableExternalAccessCondition: !And
    - !Equals [!Ref DnsZoneType, 'private']
    - !Equals [!Ref EnableExternalAccess, 'Enabled']
  EnablePublicDNSTypeCondition: !Equals [ !Ref DnsZoneType, 'public' ]
  EnableKibanaELBOutput: !And
    - !Condition EnableDependenciesKibanaStack
    - !Condition EnableExternalAccessCondition
  EnableAirflowELBOutput: !And
    - !Condition EnableDependenciesAirflowStack
    - !Condition EnableExternalAccessCondition
  EnableMlflowELBOutput: !And
    - !Condition EnableDependenciesMlflowStack
    - !Condition EnableExternalAccessCondition
  EnableAtlasELBOutput: !And
    - !Condition EnableDependenciesAtlasStack
    - !Condition EnableExternalAccessCondition
  EnableGrafanaELBOutput: !And
    - !Condition EnableDependenciesGrafanaStack
    - !Condition EnableExternalAccessCondition
  EnableDependenciesSagemakerStack: !Equals [!Ref EnableSagemaker, 'Enabled']
  EnableDependenciesKubernetesStack: !Equals [!Ref EnableKubernetes, 'Enabled']
  EnableDependenciesKubernetesExtraStack: !Equals [!Ref EnableKubernetesExtra, 'Enabled']
  EnableDependenciesKinesisStack: !Equals [!Ref EnableKinesis, 'Enabled']
  EnableDependenciesEMRStack: !Equals [!Ref EnableEMR, 'Enabled']
  EnableDependenciesRedshiftStack: !Equals [!Ref EnableRedshift, 'Enabled']
  EnableDependenciesElasticStack: !Equals [!Ref EnableElastic, 'Enabled']
  EnableDependenciesKibanaStack: !Equals [ !Ref EnableKibana, 'Enabled' ]
  EnableDependenciesAirflowStack: !Equals [!Ref EnableAirflow, 'Enabled']
  EnableDependenciesMlflowStack: !Equals [ !Ref EnableMlflow, 'Enabled' ]
  EnableDependenciesZooKeeperStack: !Equals [ !Ref EnableZooKeeper, 'Enabled' ]
  EnableDependenciesKafkaStack: !Equals [ !Ref EnableKafka, 'Enabled' ]
  EnableDependenciesCassandraStack: !Equals [ !Ref EnableCassandra, 'Enabled' ]
  EnableDependenciesAtlasStack: !Equals [ !Ref EnableAtlas, 'Enabled' ]
  EnableDependenciesGrafanaStack: !Equals [ !Ref EnableGrafana, 'Enabled' ]
  IfAddEKSUser: !Not [ !Equals [ !Ref EKSAdminUser, "" ] ]
  UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart']

  EnableSecondCIDR: !Not [ !Equals [ !Ref RemoteAccessCIDR2, "" ] ]
  EnableThirdCIDR: !Not [ !Equals [ !Ref RemoteAccessCIDR3, "" ] ]
  EnableFourthCIDR: !Not [ !Equals [ !Ref RemoteAccessCIDR4, "" ] ]
  EnableFifthCIDR: !Not [ !Equals [ !Ref RemoteAccessCIDR5, "" ] ]

Resources:
  InitDeploymentBucket:
    Condition: RunningInAnotherRegion
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'InitDeploymentBucket'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/init_bucket/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        ADPS3BucketName: !Ref ADPS3BucketName
        ADPS3BucketRegion: !Ref ADPS3BucketRegion
        BasePlatformVersion: !Ref BasePlatformVersion
        QSS3BucketName: !Ref QSS3BucketName
        QSS3KeyPrefix: !Ref QSS3KeyPrefix

  # S3 bucket for storing state
  PlatformStateBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    Properties:
      BucketName: !Sub "${ResourcePrefix}-platform-state-${AWS::AccountId}"
      AccessControl: "Private"
      Tags:
        - Key: 'Name'
          Value: 'PlatformStateBucket'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'

  # Base-platform resources
  BasePlatformLambdaRole:
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'BasePlatformLambdaRole'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/iamroles/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        QSS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [ RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref QSS3BucketName ]
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [ RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName ]

  BasePlatformLambdaInitialization:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]
        S3Key: !Sub 'platform/${BasePlatformVersion}/functions/packages/basePlatformInit/lambda.zip'
      Handler: initialize.lambda_handler
      Runtime: python3.7
      Timeout: 300
      Role: !GetAtt BasePlatformLambdaRole.Outputs.BasePlatformLambdaRoleArn
      Tags:
        - Key: 'Name'
          Value: 'BasePlatformLambdaInitialization'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'

  BasePlatformLambdaOperate:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]
        S3Key: !Sub 'platform/${BasePlatformVersion}/functions/packages/basePlatformOperator/lambda.zip'
      Handler: operating.lambda_handler
      Runtime: python3.7
      Timeout: 900
      Role: !GetAtt BasePlatformLambdaRole.Outputs.BasePlatformLambdaRoleArn
      Tags:
        - Key: 'Name'
          Value: 'BasePlatformLambdaOperate'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'

  BasePlatformSecretsLambda:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]
        S3Key: !Sub 'platform/${BasePlatformVersion}/functions/packages/basePlatformUtils/lambda.zip'
      Handler: utils.secret_handler
      Runtime: python3.7
      Timeout: 15
      Role: !GetAtt BasePlatformLambdaRole.Outputs.BasePlatformLambdaRoleArn
      Tags:
        - Key: 'Name'
          Value: 'BasePlatformSecretsLambda'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'

  BasePlatformInitialization:
    DependsOn: BasePlatformLambdaOperate
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt BasePlatformLambdaInitialization.Arn
      TimeoutWaitSc: '400'
      OperationLambdaArn: !GetAtt BasePlatformLambdaOperate.Arn
      BpLambdaRoleArn: !GetAtt BasePlatformLambdaRole.Outputs.BasePlatformLambdaRoleArn
      BpStateBucket: !Ref PlatformStateBucket
      SelfStackName: !Sub "${AWS::StackName}"

  BasePlatformLambdaFunctions:
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'BasePlatformLambdaFunctions'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/functions/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        BasePlatformVersion: !Ref BasePlatformVersion
        QSS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref QSS3BucketName]
        QSS3KeyPrefix: !Ref QSS3KeyPrefix
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]

  BasePlatformIAMGroups:
    DependsOn: BasePlatformLambdaInitialization
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'BasePlatformIAMGroups'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/iamgroups/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix

  # Platform resources
  VPCStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'VPC'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub
        - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template.yaml'
        - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion]
          S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName]
      Parameters:
        AvailabilityZones: !Join [",", !Ref AvailabilityZones]
        NumberOfAZs: '3'
        VPCCIDR: "10.0.0.0/16"
        PrivateSubnet1ACIDR: "10.0.0.0/19"
        PrivateSubnet2ACIDR: "10.0.32.0/19"
        PrivateSubnet3ACIDR: "10.0.64.0/19"
        PrivateSubnetATag2: "kubernetes.io/role/internal-elb="
        PublicSubnet1CIDR: "10.0.128.0/20"
        PublicSubnet2CIDR: "10.0.144.0/20"
        PublicSubnet3CIDR: "10.0.160.0/20"
        PublicSubnetTag2: "kubernetes.io/role/elb="

  CloudMapStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'CloudMap'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/cloudmap/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix

  RedshiftStack:
    Condition: EnableDependenciesRedshiftStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Redshift'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/redshift/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        NodeType: 'dc2.large'
        NumberOfNodes: '1'
        SubnetId1: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID'
        SubnetId2: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID'
        SubnetId3: !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID'
        VPCID: !GetAtt 'VPCStack.Outputs.VPCID'
        EmptyBucketLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.EmptyBucketLambdaArn
        MLEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupName
        BigDataEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupName
        DQEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupName
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
        PlatformOwner: !Ref PlatformOwner

  Route53Stack:
    Condition: EnableDependenciesKubernetesStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Route53'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l0/route53/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        Route53HostedZoneName: !Ref Route53HostedZoneName
        VPCID: !GetAtt 'VPCStack.Outputs.VPCID'
        DnsZoneType: !Ref DnsZoneType

  KubernetesStack:
    DependsOn: Route53Stack
    Condition: EnableDependenciesKubernetesStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Kubernetes'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/eks/eks.yaml'
      Parameters:
        VPCID: !GetAtt 'VPCStack.Outputs.VPCID'
        PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID'
        PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID'
        PrivateSubnet3ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID'
        PublicSubnet1ID: !GetAtt 'VPCStack.Outputs.PublicSubnet1ID'
        PublicSubnet2ID: !GetAtt 'VPCStack.Outputs.PublicSubnet2ID'
        PublicSubnet3ID: !GetAtt 'VPCStack.Outputs.PublicSubnet3ID'
        QSS3BucketName: !Ref QSS3BucketName
        QSS3KeyPrefix: !Ref QSS3KeyPrefix
        QSS3BucketRegion: !Ref QSS3BucketRegion
        RemoteAccessCIDR: !Ref RemoteAccessCIDR1
        KeyPairName: !Ref KeyPairName
        AdditionalEKSAdminUserArn: !If [ IfAddEKSUser, !Sub 'arn:aws:iam::${AWS::AccountId}:user/${EKSAdminUser}', !Ref "AWS::NoValue" ]
        KubernetesVersion: !Ref KubernetesVersion
        ResourcePrefix: !Ref ResourcePrefix
        PlatformOwner: !Ref PlatformOwner

  KubernetesExtraStack:
    DependsOn: KubernetesStack
    Condition: EnableDependenciesKubernetesExtraStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'KubernetesExtra'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/eks/extra.yaml'
      Parameters:
        BasePlatformVersion: !Ref BasePlatformVersion
        ADPS3BucketName: !Ref ADPS3BucketName
        ADPS3BucketRegion: !Ref ADPS3BucketRegion
        ResourcePrefix: !Ref ResourcePrefix
        EKSClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        OIDCIssuerURL: !GetAtt KubernetesStack.Outputs.OIDCIssuerURL
        Route53HostedZoneName: !Ref Route53HostedZoneName
        DnsZoneType: !Ref DnsZoneType
        Route53DnsID: !If [EnablePublicDNSTypeCondition, !Ref "AWS::NoValue", !GetAtt Route53Stack.Outputs.Route53DnsID]
        SourceSecurityGroupId: !GetAtt KubernetesStack.Outputs.BastionSecurityGroup
        RemoteAccessCIDR2: !Ref RemoteAccessCIDR2
        RemoteAccessCIDR3: !Ref RemoteAccessCIDR3
        RemoteAccessCIDR4: !Ref RemoteAccessCIDR4
        RemoteAccessCIDR5: !Ref RemoteAccessCIDR5
        NodeGroupSecurityGroup: !GetAtt KubernetesStack.Outputs.NodeGroupSecurityGroup
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn

  ElasticStack:
    Condition: EnableDependenciesElasticStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Elastic'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/elastic/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        Route53HostedZoneName: !Ref Route53HostedZoneName
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
        EKSNodeInstanceRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/eks-quickstart-ManagedNodeInstance'
        ADPS3BucketName: !Ref ADPS3BucketName
        BasePlatformVersion: !Ref BasePlatformVersion
        DockerRegistry: !Ref DockerRegistry

  KinesisStack:
    Condition: EnableDependenciesKinesisStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Kinesis'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/kinesis/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        MLEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupName
        BigDataEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupName
        DQEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupName
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName

  AirflowStack:
    Condition: EnableDependenciesAirflowStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Airflow'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/airflow/airflow.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        ADPS3BucketName: !Ref ADPS3BucketName
        ADPS3BucketRegion: !Ref ADPS3BucketRegion
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn
        ClusterOID: !GetAtt KubernetesStack.Outputs.ClusterOID
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        VPCID: !GetAtt 'VPCStack.Outputs.VPCID'
        SubnetId1: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID'
        SubnetId2: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID'
        SubnetId3: !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID'
        BPGetSecretLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.BPGetSecretLambdaArn
        BasePlatformVersion: !Ref BasePlatformVersion
        EKSNodeInstanceRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/eks-quickstart-ManagedNodeInstance'
        MLEngineerGroupArn: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupArn
        BigDataEngineerGroupArn: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupArn
        DQEngineerGroupArn: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupArn
        DevOpsEngineerGroupArn: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupArn
        MLEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupName
        BigDataEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupName
        DQEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupName
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
        EmptyBucketLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.EmptyBucketLambdaArn
        EnableExternalAccess: !Ref EnableExternalAccess
        DnsZoneType: !Ref DnsZoneType
        Route53HostedZoneName: !Ref Route53HostedZoneName
        DockerRegistry: !Ref DockerRegistry
        RemoteAccessCIDR: !Join [ ', ', [!Ref RemoteAccessCIDR1, !If [EnableSecondCIDR, !Ref RemoteAccessCIDR2, !Ref "AWS::NoValue"]  , !If [EnableThirdCIDR, !Ref RemoteAccessCIDR3, !Ref "AWS::NoValue"], !If [EnableFourthCIDR, !Ref RemoteAccessCIDR4, !Ref "AWS::NoValue"], !If [EnableFifthCIDR, !Ref RemoteAccessCIDR5, !Ref "AWS::NoValue"] ]]

  MlflowStack:
    Condition: EnableDependenciesMlflowStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Mlflow'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/mlflow/main.yaml'
      Parameters:
        EmptyBucketLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.EmptyBucketLambdaArn
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        Route53HostedZoneName: !Ref Route53HostedZoneName
        DnsZoneType: !Ref DnsZoneType
        EnableExternalAccess: !Ref EnableExternalAccess
        ADPS3BucketName: !Ref ADPS3BucketName
        ADPS3BucketRegion: !Ref ADPS3BucketRegion
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        ClusterOID: !GetAtt KubernetesStack.Outputs.ClusterOID
        VPCID: !GetAtt 'VPCStack.Outputs.VPCID'
        SubnetId1: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID'
        SubnetId2: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID'
        SubnetId3: !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID'
        BPGetSecretLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.BPGetSecretLambdaArn
        BasePlatformVersion: !Ref BasePlatformVersion
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
        RemoteAccessCIDR: !Join [ ', ', [!Ref RemoteAccessCIDR1, !If [EnableSecondCIDR, !Ref RemoteAccessCIDR2, !Ref "AWS::NoValue"]  , !If [EnableThirdCIDR, !Ref RemoteAccessCIDR3, !Ref "AWS::NoValue"], !If [EnableFourthCIDR, !Ref RemoteAccessCIDR4, !Ref "AWS::NoValue"], !If [EnableFifthCIDR, !Ref RemoteAccessCIDR5, !Ref "AWS::NoValue"] ]]
        DockerRegistry: !Ref DockerRegistry

  EMRStack:
    Condition: EnableDependenciesEMRStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'EMR'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/emr/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]
        VPCID: !GetAtt 'VPCStack.Outputs.VPCID'
        SubnetId: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID'
        Ec2KeyName: !Ref KeyPairName
        EmptyBucketLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.EmptyBucketLambdaArn
        BasePlatformVersion: !Ref BasePlatformVersion
        MLEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupName
        BigDataEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupName
        DQEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupName
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
        PlatformOwner: !Ref PlatformOwner

  KibanaStack:
    Condition: EnableDependenciesKibanaStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Kibana'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/kibana/main.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        Route53HostedZoneName: !Ref Route53HostedZoneName
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        DevOpsEngineerGroupName: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
        EKSNodeInstanceRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/eks-quickstart-ManagedNodeInstance'
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [ RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName ]
        BasePlatformVersion: !Ref BasePlatformVersion
        DockerRegistry: !Ref DockerRegistry
        EnableExternalAccess: !Ref EnableExternalAccess
        DnsZoneType: !Ref DnsZoneType
        RemoteAccessCIDR: !Join [ ', ', [!Ref RemoteAccessCIDR1, !If [EnableSecondCIDR, !Ref RemoteAccessCIDR2, !Ref "AWS::NoValue"]  , !If [EnableThirdCIDR, !Ref RemoteAccessCIDR3, !Ref "AWS::NoValue"], !If [EnableFourthCIDR, !Ref RemoteAccessCIDR4, !Ref "AWS::NoValue"], !If [EnableFifthCIDR, !Ref RemoteAccessCIDR5, !Ref "AWS::NoValue"] ]]

  ZooKeeperStack:
    Condition: EnableDependenciesZooKeeperStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'ZooKeeper'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/zookeeper/zookeeper.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [ RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName ]
        BasePlatformVersion: !Ref BasePlatformVersion

  KafkaStack:
    Condition: EnableDependenciesKafkaStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Kafka'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/kafka/kafka.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        ZooKeeperURL: !GetAtt ZooKeeperStack.Outputs.InternalDNS
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [ RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName ]
        BasePlatformVersion: !Ref BasePlatformVersion

  CassandraStack:
    Condition: EnableDependenciesCassandraStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Cassandra'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/cassandra/cassandra.yaml'
      Parameters:
        ResourcePrefix: !Ref ResourcePrefix
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [ RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName ]
        BasePlatformVersion: !Ref BasePlatformVersion

  AtlasStack:
    Condition: EnableDependenciesAtlasStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'Atlas'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/atlas/atlas.yaml'
      Parameters:
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]
        BasePlatformVersion: !Ref BasePlatformVersion
        DockerRegistry: !Ref DockerRegistry
        DnsZoneType: !Ref DnsZoneType
        EnableExternalAccess: !Ref EnableExternalAccess
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        ClusterOID: !GetAtt KubernetesStack.Outputs.ClusterOID
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        ResourcePrefix: !Ref ResourcePrefix
        Route53HostedZoneName: !Ref Route53HostedZoneName
        EKSNodeInstanceRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/eks-quickstart-ManagedNodeInstance'
        BigDataEngineerGroupArn: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupArn
        DevOpsEngineerGroupArn: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupArn
        CassandraUsername: !Join ['', ['{{resolve:secretsmanager:', !GetAtt CassandraStack.Outputs.CassandraSecret, ':SecretString:username}}' ]]
        CassandraPassword: !Join ['', ['{{resolve:secretsmanager:', !GetAtt CassandraStack.Outputs.CassandraSecret, ':SecretString:password}}' ]]
        RemoteAccessCIDR: !Join [ ', ', [!Ref RemoteAccessCIDR1, !If [EnableSecondCIDR, !Ref RemoteAccessCIDR2, !Ref "AWS::NoValue"]  , !If [EnableThirdCIDR, !Ref RemoteAccessCIDR3, !Ref "AWS::NoValue"], !If [EnableFourthCIDR, !Ref RemoteAccessCIDR4, !Ref "AWS::NoValue"], !If [EnableFifthCIDR, !Ref RemoteAccessCIDR5, !Ref "AWS::NoValue"] ]]

  GrafanaBigDataStack:
    Condition: EnableDependenciesGrafanaStack
    Type: AWS::CloudFormation::Stack
    Properties:
      Tags:
        - Key: 'Name'
          Value: 'GrafanaBigData'
        - Key: 'Owner'
          Value: !Ref PlatformOwner
        - Key: 'Project'
          Value: 'ADP'
      TemplateURL: !Sub 'https://${ADPS3BucketName}.s3.${ADPS3BucketRegion}.${AWS::URLSuffix}/platform/${BasePlatformVersion}/cloudformation/l1/bigdata/apps/grafana/main.yaml'
      Parameters:
        ADPS3BucketName: !Sub
          - '${BucketName}'
          - BucketName: !If [RunningInAnotherRegion, !GetAtt InitDeploymentBucket.Outputs.FilesBucket, !Ref ADPS3BucketName]
        BasePlatformVersion: !Ref BasePlatformVersion
        BPGetSecretLambdaArn: !GetAtt BasePlatformLambdaFunctions.Outputs.BPGetSecretLambdaArn
        CloudMapNamespaceId: !GetAtt CloudMapStack.Outputs.CloudMapNamespaceId
        ClusterOID: !GetAtt KubernetesStack.Outputs.ClusterOID
        DnsZoneType: !Ref DnsZoneType
        EnableExternalAccess: !Ref EnableExternalAccess
        KubeClusterName: !GetAtt KubernetesStack.Outputs.EKSClusterName
        KubeManifestLambdaArn: !GetAtt KubernetesStack.Outputs.KubeManifestLambdaArn
        KubeGetLambdaArn: !GetAtt KubernetesStack.Outputs.KubeGetLambdaArn
        Route53HostedZoneName: !Ref Route53HostedZoneName
        RemoteAccessCIDR: !Join [ ', ', [!Ref RemoteAccessCIDR1, !If [EnableSecondCIDR, !Ref RemoteAccessCIDR2, !Ref "AWS::NoValue"]  , !If [EnableThirdCIDR, !Ref RemoteAccessCIDR3, !Ref "AWS::NoValue"], !If [EnableFourthCIDR, !Ref RemoteAccessCIDR4, !Ref "AWS::NoValue"], !If [EnableFifthCIDR, !Ref RemoteAccessCIDR5, !Ref "AWS::NoValue"] ]]
        ResourcePrefix: !Ref ResourcePrefix

Outputs:
  KibanaELB:
    Condition: EnableKibanaELBOutput
    Value: !GetAtt KibanaStack.Outputs.KibanaELB
  KibanaFQDN:
    Condition: EnableDependenciesKibanaStack
    Value: !GetAtt KibanaStack.Outputs.KibanaFQDN
    Description: Kibana service DNS address (private zone will not be accessible form outside)
  AirflowELB:
    Condition: EnableAirflowELBOutput
    Value: !GetAtt AirflowStack.Outputs.AirflowELB
    Description: Airflow service ELB address (Make sure that you use a correct port. By default, 8080)
  AirflowFQDN:
    Condition: EnableDependenciesAirflowStack
    Value: !GetAtt AirflowStack.Outputs.AirflowFQDN
    Description: Airflow service DNS address (private zone will not be accessible form outside)
  AirflowSecret:
    Condition: EnableDependenciesAirflowStack
    Value: !GetAtt AirflowStack.Outputs.AirflowSecret
    Description: Airflow service secret
  AirflowDagsBucket:
    Condition: EnableDependenciesAirflowStack
    Value: !GetAtt AirflowStack.Outputs.SyncerDagS3Bucket
    Description: Bucket for Airflow Dags
  MlflowELB:
    Condition: EnableMlflowELBOutput
    Value: !GetAtt MlflowStack.Outputs.MlflowELB
    Description: Mlflow service ELB address
  MlflowFQDN:
    Condition: EnableDependenciesMlflowStack
    Value: !GetAtt MlflowStack.Outputs.MlflowFQDN
    Description: Mlflow service DNS address (private zone will not be accessible form outside)
  ZooKeeperInternalDNS:
    Condition: EnableDependenciesZooKeeperStack
    Value: !GetAtt ZooKeeperStack.Outputs.InternalDNS
  ZooKeeperClusterIP:
    Condition: EnableDependenciesZooKeeperStack
    Value: !GetAtt ZooKeeperStack.Outputs.ClusterIP
  KafkaInternalDNS:
    Condition: EnableDependenciesKafkaStack
    Value: !GetAtt KafkaStack.Outputs.InternalDNS
  KafkaClusterIP:
    Condition: EnableDependenciesKafkaStack
    Value: !GetAtt KafkaStack.Outputs.ClusterIP
  CassandraInternalDNS:
    Condition: EnableDependenciesCassandraStack
    Value: !GetAtt CassandraStack.Outputs.InternalDNS
  CassandraClusterIP:
    Condition: EnableDependenciesCassandraStack
    Value: !GetAtt CassandraStack.Outputs.ClusterIP
  CassandraSecret:
    Condition: EnableDependenciesCassandraStack
    Value: !GetAtt CassandraStack.Outputs.CassandraSecret
  AtlasELB:
    Condition: EnableAtlasELBOutput
    Value: !GetAtt AtlasStack.Outputs.AtlasELB
    Description: Atlas service ELB address (will not work if external access is disabled)
  AtlasFQDN:
    Condition: EnableDependenciesAtlasStack
    Value: !GetAtt AtlasStack.Outputs.AtlasFQDN
    Description: Atlas service DNS address (private zone will not be accessible form outside)
  AtlasSecret:
    Condition: EnableDependenciesAtlasStack
    Value: !GetAtt AtlasStack.Outputs.AtlasSecret
    Description: Atlas service secret
  GrafanaELB:
    Condition: EnableGrafanaELBOutput
    Value: !GetAtt GrafanaBigDataStack.Outputs.GrafanaELB
  GrafanaFQDN:
    Condition: EnableDependenciesGrafanaStack
    Value: !GetAtt GrafanaBigDataStack.Outputs.GrafanaFQDN
  GrafanaSecret:
    Condition: EnableDependenciesGrafanaStack
    Value: !GetAtt GrafanaBigDataStack.Outputs.GrafanaSecret
  BastionIP:
    Condition: EnableDependenciesKubernetesStack
    Value: !GetAtt KubernetesStack.Outputs.BastionIP
    Description: Bastion host IP address.
  ADPS3BucketAnotherRegion:
    Condition: RunningInAnotherRegion
    Value: !GetAtt InitDeploymentBucket.Outputs.FilesBucket
    Description: Copy of ADP s3 bucket in a new region
    Export:
      Name: ADPS3BucketAnotherRegion
  ADPResourcePrefix:
    Value: !Ref ResourcePrefix
    Description: Exporting ResourcePrefix variable value for Usecase deployments
    Export:
      Name: ADPResourcePrefix
  PlatformOwner:
    Value: !Ref PlatformOwner
    Export:
      Name: ADPPlatformOwner
  KeyPairName:
    Value: !Ref KeyPairName
    Export:
      Name: ADPKeyPairName
  RemoteAccessCIDR:
    Value: !Join [ ', ', [!Ref RemoteAccessCIDR1, !If [EnableSecondCIDR, !Ref RemoteAccessCIDR2, !Ref "AWS::NoValue"]  , !If [EnableThirdCIDR, !Ref RemoteAccessCIDR3, !Ref "AWS::NoValue"], !If [EnableFourthCIDR, !Ref RemoteAccessCIDR4, !Ref "AWS::NoValue"], !If [EnableFifthCIDR, !Ref RemoteAccessCIDR5, !Ref "AWS::NoValue"] ]]
    Export:
      Name: ADPRemoteAccessCIDR
  MLEngineerGroupArn:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupArn
  MLEngineerGroupName:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.MLEngineerGroupName
  BigDataEngineerGroupArn:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupArn
  BigDataEngineerGroupName:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.BigDataEngineerGroupName
  DQEngineerGroupArn:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupArn
  DQEngineerGroupName:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.DQEngineerGroupName
  DevOpsEngineerGroupArn:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupArn
  DevOpsEngineerGroupName:
    Value: !GetAtt BasePlatformIAMGroups.Outputs.DevOpsEngineerGroupName
