---
## Amazon DocumentDB Sagemaker Canvas Integration
## Creates  Sagemaker Domain and Required Components
##
## Changelog:
##
## Dependencies: TBD
##
## This sample code is made available under the MIT-0 license. See the LICENSE file.

AWSTemplateFormatVersion: "2010-09-09"
Description: Sagemaker Canvas Stack

## Parameters
Parameters:
  TemplateName:
    Type: String
    Description: Name used for different elements created.
  VPCID:
    Type: String
    Description: Enter ID of the your DocumentDB VPC
  PrivateSubnets:
    Type: String
    Description: Enter comma seperated list of ID's of private subnets of your DocumentDB VPC
  DocumentDBSG:
    Type: String
    Description: Enter ID of Security Group for your DocumentDB Cluster
  PrivateRouteTable:
    Type: String
    Description: Enter ID for your Private Route Table
  CreateEndpoints:
    Description: Specify if you want to create VPC endpoints. select false if you already have endpoints in your environment
    Type: String
    Default: "true"
    AllowedValues:
      - "true"
      - "false"

Conditions:
  createEndpoints: !Equals [ !Ref CreateEndpoints, "true" ]

# ## Resources
Resources:
  
  SecretsManagerVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.secretsmanager
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  AthenaVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.athena
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  SagemakerApiVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.sagemaker.api
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  SagemakerRuntimeVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.sagemaker.runtime
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  SagemakerNotebookVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub aws.sagemaker.${AWS::Region}.notebook
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  STSVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.sts
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  EcrApiVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ecr.api
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  EcrDkrVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ecr.dkr
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  EC2VPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  S3VPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
      VpcEndpointType: Gateway
      VpcId: !Ref VPCID
      RouteTableIds:
        - !Ref PrivateRouteTable
  RedshiftDataVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.redshift-data
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  SSMEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  MonitoringEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.monitoring
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  LogsVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.logs
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  ForecastVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.forecast
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  ForecastQueryEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.forecastquery
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  GlueVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.glue
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  ApplicationAutoscalingVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.application-autoscaling
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  RDSVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.rds
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  BedrockRuntimeVPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Condition: createEndpoints
    Properties: 
      PrivateDnsEnabled: true
      ServiceName: !Sub com.amazonaws.${AWS::Region}.bedrock-runtime
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcEndpointType: Interface
      VpcId: !Ref VPCID
      SecurityGroupIds:
        - !Ref DocumentDBSG
  SageMakerRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${TemplateName}-SagemakerFullAccessRole
      Description: Role for Sagemaker Canvas and DocumentDB
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSageMakerCanvasAIServicesAccess
        - arn:aws:iam::aws:policy/AmazonSageMakerCanvasFullAccess
        - arn:aws:iam::aws:policy/AmazonSageMakerFullAccess
        - !Ref SagemakerPolicy
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service: 
            - sagemaker.amazonaws.com
          Action:
          - 'sts:AssumeRole'
  SagemakerPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub ${TemplateName}-SagemakerVPCEPolicy
      Description: Managed policy for Sagemaker access to VPC endpoint
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
            - 'ec2:DescribeVpcEndpoints'
            - 'ec2:DescribeDhcpOptions'
            - 'ec2:DescribeVpcs'
            - 'ec2:DescribeSubnets'
            - 'ec2:DescribeSecurityGroups'
            - 'ec2:DescribeNetworkInterfaces'
            - 'ec2:DeleteNetworkInterfacePermission'
            - 'ec2:DeleteNetworkInterface'
            - 'ec2:CreateNetworkInterfacePermission'
            - 'ec2:CreateNetworkInterface'
            Resource: '*'
  SageMakerDomain:
    Type: AWS::SageMaker::Domain
    Properties:
      AppNetworkAccessType: VpcOnly
      AppSecurityGroupManagement: Customer
      AuthMode: IAM
      DefaultUserSettings: 
        ExecutionRole: !GetAtt SageMakerRole.Arn
        SecurityGroups:
          - !Ref DocumentDBSG
      DomainName: DocumentDBSagemakerDomain
      SubnetIds: !Split [',',!Ref PrivateSubnets]
      VpcId: !Ref VPCID
  SageMakerUser:
    Type: AWS::SageMaker::UserProfile
    Properties:
      DomainId: !Ref SageMakerDomain
      UserProfileName: SagemakerUserProfile
      UserSettings: 
        ExecutionRole: !GetAtt SageMakerRole.Arn
     