AWSTemplateFormatVersion: 2010-09-09
Description: Companion infrastructure for the "Building a Knowledge Graph in Neptune with unstructured data" blog post
Parameters:
  Env:
    Description: 'Environment tag, e.g. prod, nonprod.'
    Default: test
    Type: String
    AllowedPattern: '[a-z0-9]+'
    MaxLength: 15
  DbInstanceType:
    Description: Neptune DB instance type
    Type: String
    Default: db.r6g.large
    AllowedValues:
      - db.t3.medium
      - db.t4g.medium
      - db.r5.large
      - db.r5.xlarge
      - db.r5.2xlarge
      - db.r5.4xlarge
      - db.r5.8xlarge
      - db.r6g.large
      - db.r6g.xlarge
      - db.r6g.2xlarge
      - db.r6g.4xlarge
      - db.r6g.8xlarge
      - db.x2g.large
      - db.x2g.xlarge
      - db.x2g.2xlarge
      - db.x2g.4xlarge
      - db.x2g.8xlarge
    ConstraintDescription: >-
      Must be a valid Neptune instance type.
  DBReplicaIdentifierSuffix:
    Description: >-
      OPTIONAL: The ID for the Neptune Replica to use. Empty means no read
      replica.
    Type: String
    Default: ''
  DBClusterPort:
    Type: String
    Default: '8182'
    Description: Enter the port of your Neptune cluster
  NeptuneQueryTimeout:
    Type: Number
    Default: 120000
    Description: Neptune Query Time out (in milliseconds)
  NeptuneEnableAuditLog:
    Type: Number
    Default: 0
    AllowedValues:
      - 0
      - 1
    Description: Enable Audit Log. 0 means disable and 1 means enable.
  IamAuthEnabled:
    Type: String
    Default: 'false'
    AllowedValues:
      - 'true'
      - 'false'
    Description: Enable IAM Auth for Neptune.
  NotebookInstanceType:
    Description: >-
      SageMaker Notebook instance type. Please refer
      https://aws.amazon.com/sagemaker/pricing/ for uptodate allowed instance
      type in aws region and https://aws.amazon.com/neptune/pricing/ for
      pricing.
    Type: String
    Default: ml.t3.medium
    AllowedValues:
      - ml.t2.medium
      - ml.t2.large
      - ml.t2.xlarge
      - ml.t2.2xlarge
      - ml.t3.medium        
      - ml.m4.xlarge
      - ml.m4.2xlarge
      - ml.m4.4xlarge
      - ml.m4.10xlarge
      - ml.m4.16xlarge
      - ml.m5.large
      - ml.m5.xlarge
      - ml.m5.2xlarge
      - ml.m5.4xlarge
      - ml.m5.12xlarge
      - ml.m5.24xlarge
      - ml.m5d.large
      - ml.m5d.xlarge
      - ml.m5d.2xlarge
      - ml.m5d.4xlarge
      - ml.m5d.12xlarge
      - ml.m5d.24xlarge
      - ml.c4.large
      - ml.c4.xlarge
      - ml.c4.2xlarge
      - ml.c4.4xlarge
      - ml.c4.8xlarge
    ConstraintDescription: Must be a valid SageMaker instance type.
Rules:
  DBInstanceTypeVsRegion:
    RuleCondition: !Or 
      - !Equals 
        - !Ref 'AWS::Region'
        - eu-north-1
      - !Equals 
        - !Ref 'AWS::Region'
        - us-gov-east-1
      - !Equals 
        - !Ref 'AWS::Region'
        - us-west-1
      - !Equals 
        - !Ref 'AWS::Region'
        - sa-east-1
      - !Equals 
        - !Ref 'AWS::Region'
        - ap-east-1
      - !Equals 
        - !Ref 'AWS::Region'
        - ca-central-1
      - !Equals 
        - !Ref 'AWS::Region'
        - me-south-1
      - !Equals 
        - !Ref 'AWS::Region'
        - cn-northwest-1
    Assertions:
      - Assert:
          'Fn::Contains':
            - - db.t3.medium
              - db.r5.large
              - db.r5.xlarge
              - db.r5.2xlarge
              - db.r5.4xlarge
              - db.r5.12xlarge
            - !Ref DbInstanceType
        AssertDescription: >-
          Only R5 and T3 Instances are available in eu-north-1 (ARN),
          us-gov-east-1 (OSU), ca-central-1 (YUL), us-west-1 (SFO), me-south-1
          (BAH), ap-east-1 (HKG), sa-east-1 (GRU) and cn-northwest-1 (ZHY)
  SagemakerNotebookInstanceTypeVsRegion:
    RuleCondition: !Or 
      - !Equals 
        - !Ref 'AWS::Region'
        - us-gov-east-1
      - !Equals 
        - !Ref 'AWS::Region'
        - us-gov-west-1
      - !Equals 
        - !Ref 'AWS::Region'
        - cn-northwest-1
    Assertions:
      - Assert:
          'Fn::Contains':
            - - none
            - !Ref NotebookInstanceType
        AssertDescription: >-
          Neptune Sagemaker notebooks are not available in us-gov-east-1 (OSU),
          us-gov-west-1 (PDT) and cn-northwest-1 (ZHY)
Conditions:
  CreateDBReplicaInstance: !Not 
    - !Equals 
      - !Ref DBReplicaIdentifierSuffix
      - ''
  AZ3NotPresent: !Or 
    - !Equals 
      - !Ref 'AWS::Region'
      - ca-central-1
    - !Equals 
      - !Ref 'AWS::Region'
      - us-west-1
  AZ3Present: !Not 
    - !Condition AZ3NotPresent
  CreateSagemakerNotebook: !Not 
    - !Equals 
      - !Ref NotebookInstanceType
      - none
Resources:
  S3WorkingBucket:
    Type: AWS::S3::Bucket
  NeptuneStack:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      TemplateURL: !Join 
        - ''
        - - >-
            https://aws-neptune-customer-samples.s3.amazonaws.com/knowledge-graph-unstructured/neptune-base-stack.yml
      TimeoutInMinutes: '60'
      Parameters:
        Env: !Ref Env
        DBReplicaIdentifierSuffix: !Ref DBReplicaIdentifierSuffix
        DBClusterPort: !Ref DBClusterPort
        DbInstanceType: !Ref DbInstanceType
        NeptuneQueryTimeout: !Ref NeptuneQueryTimeout
        NeptuneEnableAuditLog: !Ref NeptuneEnableAuditLog
        IamAuthEnabled: !Ref IamAuthEnabled
        NeptuneBulkLoadBucket: !Ref S3WorkingBucket
    Metadata:
      'AWS::CloudFormation::Designer':
        id: 28423686-cbd6-498b-b5f8-9ea9d1e9d52b
  NeptuneSagemakerNotebook:
    Type: 'AWS::CloudFormation::Stack'
    Condition: CreateSagemakerNotebook
    Properties:
      TemplateURL: !Join 
        - ''
        - - >-
            https://aws-neptune-customer-samples.s3.amazonaws.com/knowledge-graph-unstructured/neptune-workbench-stack.yml
      TimeoutInMinutes: '30'
      Parameters:
        Env: !Ref Env
        NotebookInstanceType: !Ref NotebookInstanceType
        NeptuneClusterEndpoint: !GetAtt 
          - NeptuneStack
          - Outputs.DBClusterEndpoint
        NeptuneClusterPort: !GetAtt 
          - NeptuneStack
          - Outputs.DBClusterPort
        NeptuneClusterVpc: !GetAtt 
          - NeptuneStack
          - Outputs.VPC
        NeptuneClusterSubnetId: !GetAtt 
          - NeptuneStack
          - Outputs.PrivateSubnet1
        NeptuneClientSecurityGroup: !GetAtt 
          - NeptuneStack
          - Outputs.NeptuneSG
        NeptuneLoadFromS3RoleArn: !GetAtt 
          - NeptuneStack
          - Outputs.NeptuneLoadFromS3IAMRoleArn
        StartupScript: ''
        BulkLoadS3BucketName: !Ref S3WorkingBucket
    Metadata:
      'AWS::CloudFormation::Designer':
        id: a7e5773f-2c86-4ce7-a591-9ec69ffd0576
Outputs:
  DBClusterId:
    Description: Neptune Cluster Identifier
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBClusterId
  DBSubnetGroupId:
    Description: Neptune DBSubnetGroup Identifier
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBSubnetGroupId
  DBClusterResourceId:
    Description: Neptune Cluster Resource Identifier
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBClusterResourceId
  DBClusterEndpoint:
    Description: Master Endpoint for Neptune Cluster
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBClusterEndpoint
  DBInstanceEndpoint:
    Description: Master Instance Endpoint
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBInstanceEndpoint
  DBReplicaInstanceEndpoint:
    Description: ReadReplica Instance Endpoint
    Condition: CreateDBReplicaInstance
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBReplicaInstanceEndpoint
  SparqlEndpoint:
    Description: Sparql Endpoint for Neptune
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.SparqlEndpoint
  GremlinEndpoint:
    Description: Gremlin Endpoint for Neptune
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.GremlinEndpoint
  LoaderEndpoint:
    Description: Loader Endpoint for Neptune
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.LoaderEndpoint
  DBClusterReadEndpoint:
    Description: DB cluster Read Endpoint
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBClusterReadEndpoint
  DBClusterPort:
    Description: Port for the Neptune Cluster
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.DBClusterPort
  NeptuneLoadFromS3IAMRoleArn:
    Description: IAM Role for loading data in Neptune
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.NeptuneLoadFromS3IAMRoleArn
  VPC:
    Description: VPC
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.VPC
  Subnet1:
    Description: Private Subnet1
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.PrivateSubnet1
  Subnet2:
    Description: Private Subnet2
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.PrivateSubnet2
  Subnet3:
    Description: Private Subnet3
    Condition: AZ3Present
    Value: !GetAtt 
      - NeptuneStack
      - Outputs.PrivateSubnet3
  NeptuneSagemakerNotebook:
    Condition: CreateSagemakerNotebook
    Description: Neptune Sagemaker Notebook Name
    Value: !GetAtt 
      - NeptuneSagemakerNotebook
      - Outputs.NeptuneSagemakerNotebook
  NeptuneNotebookInstanceLifecycleConfigId:
    Condition: CreateSagemakerNotebook
    Description: Neptune Sagemaker Notebook Instance Lifecycle ConfigId
    Value: !GetAtt 
      - NeptuneSagemakerNotebook
      - Outputs.NeptuneNotebookInstanceLifecycleConfigId
  BulkLoadS3BucketName:
    Condition: CreateSagemakerNotebook
    Description: Arn of the Working S3 Bucket
    Value: !Ref S3WorkingBucket
Metadata:
  'AWS::CloudFormation::Designer':
    28423686-cbd6-498b-b5f8-9ea9d1e9d52b:
      size:
        width: 60
        height: 60
      position:
        x: 60
        'y': 90
      z: 1
      embeds: []
    a7e5773f-2c86-4ce7-a591-9ec69ffd0576:
      size:
        width: 60
        height: 60
      position:
        x: 180
        'y': 90
      z: 1
      embeds: []
