{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "A sample template to replicate data from source Neptune Cluster to target Neptune Cluster using Neptune Stream",
  "Metadata": {
    "AWS::CloudFormation::Interface": {
      "ParameterGroups": [
        {
          "Label": {
            "default": "Network Configuration"
          },
          "Parameters": [
            "VPC",
            "SubnetIds",
            "SecurityGroupIds",
            "RouteTableIds",
            "CreateDDBVPCEndPoint",
            "CreateMonitoringEndPoint"
          ]
        },
        {
          "Label": {
            "default": "Stream Poller"
          },
          "Parameters": [
            "ApplicationName",
            "LambdaMemorySize",
            "LambdaRuntime",
            "LambdaS3Bucket",
            "LambdaS3Key",
            "LambdaLoggingLevel",
            "ManagedPolicies",
            "StreamRecordsHandler",
            "StreamRecordsBatchSize",
            "MaxPollingWaitTime",
            "MaxPollingInterval",
            "StepFunctionFallbackPeriod",
            "StepFunctionFallbackPeriodUnit"
          ]
        },
        {
          "Label": {
            "default": "Neptune Stream"
          },
          "Parameters": [
            "NeptuneStreamEndpoint",
            "QueryEngine",
            "IAMAuthEnabledOnSourceStream",
            "StreamDBClusterResourceId"
          ]
        },
        {
          "Label": {
            "default": "Target Neptune Cluster"
          },
          "Parameters": [
            "TargetNeptuneClusterEndpoint",
            "TargetNeptuneClusterPort",
            "TargetSPARQLUpdateEndpoint",
            "IAMAuthEnabledOnTargetCluster",
            "TargetAWSRegion",
            "TargetNeptuneDBClusterResourceId",
            "SPARQLTripleOnlyMode",
            "BlockSparqlReplicationOnBlankNode"
          ]
        },
        {
          "Label": {
            "default": "Alarm"
          },
          "Parameters": [
            "CreateCloudWatchAlarm",
            "NotificationSNSTopicArn",
            "NotificationEmail"
          ]
        }
      ],
      "ParameterLabels": {
        "ApplicationName": {
          "default": "Application Name"
        },
        "LambdaMemorySize": {
          "default": "Memory size for Lambda Poller"
        },
        "LambdaRuntime": {
          "default": "Lambda Runtime"
        },
        "LambdaS3Bucket": {
          "default": "S3 Bucket having Lambda code artifacts"
        },
        "LambdaS3Key": {
          "default": "S3 Key corresponding to Lambda Code artifacts"
        },
        "LambdaLoggingLevel": {
          "default": "Logging level for Lambda"
        },
        "ManagedPolicies": {
          "default": "Managed Policies for Lambda Execution"
        },
        "StreamRecordsHandler": {
          "default": "Stream Records Handler"
        },
        "StreamRecordsBatchSize": {
          "default": "Maximum records Fetched from Stream"
        },
        "StepFunctionFallbackPeriod": {
          "default": "Step Function Fallback Period"
        },
        "StepFunctionFallbackPeriodUnit": {
          "default": "Step Function Fallback Period Unit"
        },
        "MaxPollingWaitTime": {
          "default": "Max wait time between two Polls (in Seconds)"
        },
        "NeptuneStreamEndpoint": {
          "default": "Endpoint of source Neptune Stream"
        },
        "QueryEngine": {
          "default": "Neptune Query Engine"
        },
        "IAMAuthEnabledOnSourceStream": {
          "default": "Is IAM Auth Enabled?"
        },
        "StreamDBClusterResourceId": {
          "default": "Neptune Cluster Resource Id"
        },
        "MaxPollingInterval": {
          "default": "Maximum Continuous polling period (in Seconds)"
        },
        "NotificationSNSTopicArn": {
          "default": "SNS Topic ARN for Cloudwatch Alarm Notifications"
        },
        "NotificationEmail": {
          "default": "Email for Cloudwatch Alarm Notifications"
        },
        "VPC": {
          "default": "VPC"
        },
        "TargetNeptuneClusterEndpoint": {
          "default": "Neptune Cluster Endpoint"
        },
        "TargetNeptuneClusterPort": {
          "default": "Neptune Cluster Port"
        },
        "TargetSPARQLUpdateEndpoint": {
          "default": "Target SPARQL Update Endpoint"
        },
        "IAMAuthEnabledOnTargetCluster": {
          "default": "Is IAM Auth Enabled?"
        },
        "SPARQLTripleOnlyMode": {
          "default": "Is SPARQL Triple Only Mode (No 'Named Graph' Replication) Enabled?"
        },
        "TargetNeptuneDBClusterResourceId": {
          "default": "Neptune Cluster Resource Id"
        },
        "RouteTableIds": {
          "default": "List of Route Table Ids"
        },
        "CreateDDBVPCEndPoint": {
          "default": "Require to create Dynamo DB VPC Endpoint"
        },
        "CreateMonitoringEndPoint": {
          "default": "Require to create Monitoring VPC Endpoint"
        },
        "CreateCloudWatchAlarm": {
          "default": "Require to create Cloud watch Alarm"
        },
        "SubnetIds": {
          "default": "List of Subnet Ids"
        },
        "SecurityGroupIds": {
          "default": "List of Security Group Ids"
        },
        "BlockSparqlReplicationOnBlankNode" : {
          "default": "Required to indicate whether replication should be blocked for Blanknode in Sparql"
        }
      }
    }
  },
  "Parameters": {
    "ApplicationName": {
      "Type": "String",
      "Default": "NeptuneStream",
      "AllowedPattern": "^[a-zA-Z0-9._-]{3,50}$",
      "ConstraintDescription": "Application name must be between 3-50 characters and should only contain characters [a-z], [A-Z], [0-9], _(underscore), .(dot), -(dash)",
      "Description": "Application Name used as a reference to create resources"
    },
    "LambdaMemorySize": {
      "Type": "Number",
      "Default": 2048,
      "MinValue": 128,
      "MaxValue": 10240,
      "Description": "Poller Lambda memory size (in MB). Should be between 128 MB and 10240 MB"
    },
    "LambdaRuntime": {
      "Type": "String",
      "Description": "Lambda Runtime",
      "Default": "python3.12",
      "AllowedValues": [
        "python3.12"
      ]
    },
    "LambdaS3Bucket": {
      "Type": "String",
      "Default": "",
      "Description": "S3 bucket having Lambda Artifact. Optional Parameter - If left blank artifact will be picked from default Bucket."
    },
    "LambdaS3Key": {
      "Type": "String",
      "Default": "",
      "Description": "S3 key for Lambda Artifact. Optional Parameter - If left blank default Lambda Artifact is used."
    },
    "LambdaLoggingLevel": {
      "Type": "String",
      "Default": "INFO",
      "AllowedValues": [
        "DEBUG",
        "INFO",
        "WARN",
        "ERROR",
        "FATAL"
      ],
      "Description": "Poller Lambda logging level."
    },
    "ManagedPolicies": {
      "Type": "CommaDelimitedList",
      "Default": "",
      "Description": "Comma-delimited list of ARNs of managed policies to be attached to Lambda execution role. Optional Parameter - If left blank policy with required access is created. "
    },
    "StreamRecordsHandler": {
      "Type": "String",
      "Default": "",
      "Description": "Handler for processing stream records. Optional Parameter - If left blank default Handler for Neptune is used."
    },
    "StreamRecordsBatchSize": {
      "Type": "Number",
      "Default": 5000,
      "MaxValue": 50000,
      "MinValue": 1,
      "Description": "Number of records to be read from stream in each batch. Should be between 1 to 50000."
    },
    "MaxPollingWaitTime": {
      "Type": "Number",
      "Default": 60,
      "MaxValue": 3600,
      "MinValue": 0,
      "Description": "Maximum wait time in seconds between two successive polling from stream. Set value to 0 sec for continuous polling. Maximum value can be 3600 sec (1 hour)."
    },
    "MaxPollingInterval": {
      "Type": "Number",
      "Default": 600,
      "MaxValue": 900,
      "MinValue": 5,
      "Description": "Period for which we can continuously poll stream for records on one Lambda instance. Should be between 5 sec to 900 sec. This parameter is used to set Poller Lambda Timeout."
    },
    "NeptuneStreamEndpoint": {
      "Type": "String",
      "AllowedPattern": "^(.+)$",
      "ConstraintDescription": "Must be a valid stream endpoint",
      "Description": "Endpoint for source Neptune Stream. This is of the form https://<cluster>:<port>/propertygraph/stream or https://<cluster>:<port>/sparql/stream."
    },
    "QueryEngine": {
      "Type": "String",
      "Default": "Gremlin",
      "AllowedValues": [
        "Gremlin",
        "Sparql"
      ],
      "ConstraintDescription": "Must be a either Gremlin or Sparql",
      "Description": "Neptune Query Engine."
    },
    "IAMAuthEnabledOnSourceStream": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag to determine if IAM Auth is Enabled for Source Neptune Cluster or not."
    },
    "StreamDBClusterResourceId": {
      "Type": "String",
      "Default": "",
      "Description": "Neptune DB Cluster Resource Id. Ex: cluster-5DSWZGISGVCHJPHOV5MK7QF2PY. Optional Parameter - Only needed when IAM Auth is Enabled."
    },
    "StepFunctionFallbackPeriod": {
      "Type": "Number",
      "Default": 5,
      "Description": " Period after which Step function is invoked using Cloud Watch Events to recover from failure. Unit for Step Function Fallback period is set separately."
    },
    "StepFunctionFallbackPeriodUnit": {
      "Type": "String",
      "Default": "minutes",
      "AllowedValues": [
        "minutes",
        "minute",
        "hours",
        "hour",
        "days",
        "day"
      ],
      "Description": "Step Function FallbackPeriod unit. Should be one of minutes, minute, hours, hour, days, day"
    },
    "NotificationSNSTopicArn": {
      "Type": "String",
      "Default": "",
      "Description": "SNS Topic ARN where CloudWatch Alarm Notifications would be sent. Eg. arn:aws:sns:<region>:<account-id>:<name>. Optional."
    },
    "NotificationEmail": {
      "Type": "String",
      "Default": "",
      "Description": "Email Address for CloudWatch Alarm Notification. Optional Parameter - Only needed when selecting option to create CloudWatch Alarm."
    },
    "VPC": {
      "Type": "AWS::EC2::VPC::Id",
      "Description": "The VPC in which Neptune Stream Instance is present",
      "ConstraintDescription": "Must be the id (for example, vpc-123a351e) of an existing VPC."
    },
    "SubnetIds": {
      "Type": "List<AWS::EC2::Subnet::Id>",
      "Description": "The subnets to which a network interface is established. Add subnets associated with both Neptune Stream Cluster & Neptune target Cluster.",
      "ConstraintDescription": "Must be the subnet id (for example, subnet-123a351e)."
    },
    "SecurityGroupIds": {
      "Type": "List<AWS::EC2::SecurityGroup::Id>",
      "Description": "The Security groups associated with the Neptune Stream Cluster and Neptune Target Cluster.",
      "ConstraintDescription": "Must be a security group ID (for example, sg-a123fd85)."
    },
    "RouteTableIds": {
      "Type": "String",
      "Default": "",
      "Description": "Comma Delimited list of Route table ids associated with the Subnets. For Example: rtb-a12345,rtba7863k1. Optional parameter - Only needed when creating DynamoDB VPC Endpoint."
    },
    "CreateDDBVPCEndPoint": {
      "Type": "String",
      "Default": "true",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag used to determine whether to create Dynamo DB VPC Endpoint or not. Select false only if Dynamo DB VPC endpoint already present."
    },
    "CreateMonitoringEndPoint": {
      "Type": "String",
      "Default": "true",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag used to determine whether to create Monitoring VPC Endpoint or not. Select false only if Monitoring VPC endpoint already present."
    },
    "CreateCloudWatchAlarm": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag used to determine whether to create Cloud watch alarm or not."
    },
    "TargetNeptuneClusterEndpoint": {
      "Type": "String",
      "Default": "",
      "Description": "Endpoint for Target Neptune Cluster. Ex : neptune-source.us-east-1.neptune.amazonaws.com. This field is optional and one of \"TargetNeptuneClusterEndpoint\" or \"TargetSPARQLUpdateEndpoint\" needs to be present."
    },
    "TargetAWSRegion": {
      "Type": "String",
      "Default": "",
      "Description": "Target Neptune cluster's AWS region. Ex: us-east-1. Optional Parameter - Only needed when AWS region is different from source Neptune cluster.  Note: value should be a valid region else process will fail. Refer to https://docs.aws.amazon.com/neptune/latest/userguide/limits.html#limits-regions for Neptune supported AWS regions"
    },
    "TargetNeptuneClusterPort": {
      "Type": "Number",
      "Default": 8182,
      "MaxValue": 65535,
      "MinValue": 0,
      "ConstraintDescription": "Value cannot be blank. Must be a valid cluster port",
      "Description": "Port for Target Neptune Cluster. Ex : 8182"
    },
    "TargetSPARQLUpdateEndpoint": {
      "Type": "String",
      "Default": "",
      "Description": "Endpoint for Target SPARQL update. Ex : https://abc.com/xyz. This endpoint can be any SPARQL store which supports quad or triples."
    },
    "IAMAuthEnabledOnTargetCluster": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be either true or false",
      "Description": "Flag to determine if IAM Auth is Enabled for Target Neptune Cluster or not."
    },
    "SPARQLTripleOnlyMode": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be either true or false",
      "Description": "Flag to determine if Triple only mode (no 'named graph' replication) is enabled or not."
    },
    "TargetNeptuneDBClusterResourceId": {
      "Type": "String",
      "Default": "",
      "Description": "Target Neptune Cluster Resource Id. Ex: cluster-5DSWZGISGVCHJPHOV5MK7QF2PY. Optional Parameter- Only needed when IAM Auth is Enabled for Target Neptune Cluster."
    },
    "StreamPollerInitialState": {
      "Type": "String",
      "Default": "ENABLED",
      "AllowedValues": [
         "DISABLED",
	 "ENABLED"
      ],
      "ConstraintDescription": "Must be a either DISABLED or ENABLED",
      "Description": "Initial state of poller."
   },
   "StartingCheckpoint": {
      "Type": "String",
      "Default": "0:0",
      "Description": "Starting checkpoint for stream poller."
   },
   "BlockSparqlReplicationOnBlankNode": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "false",
        "true"
      ],
      "ConstraintDescription": "Must be a either false or true",
      "Description": "Flag to stop replication for BlankNode in Sparql (RDF)"
   }
  },
  "Conditions": {
    "IsEmptyLambdaS3Bucket": {
      "Fn::Equals": [
        {
          "Ref": "LambdaS3Bucket"
        },
        ""
      ]
    },
    "IsEmptyLambdaS3Key": {
      "Fn::Equals": [
        {
          "Ref": "LambdaS3Key"
        },
        ""
      ]
    },
    "IsEmptyStreamRecordsHandler": {
      "Fn::Equals": [
        {
          "Ref": "StreamRecordsHandler"
        },
        ""
      ]
    },
    "IAMAuthEnabledOnTargetClusterCondition": {
      "Fn::Equals": [
        {
          "Ref": "IAMAuthEnabledOnTargetCluster"
        },
        "true"
      ]
    },
    "TargetAWSRegionIsValid": {
      "Fn::Not": [
        {
          "Fn::Equals": [
            {
              "Ref": "TargetAWSRegion"
            },
            ""
          ]
        }
      ]
    },
    "SPARQLTripleOnlyModeIsTrue": {
      "Fn::Equals": [
        {
          "Ref": "SPARQLTripleOnlyMode"
        },
        "true"
      ]
    },
     "BlockSparqlReplicationOnBlankNode": {
      "Fn::Equals": [
        {
          "Ref": "BlockSparqlReplicationOnBlankNode"
        },
        "true"
      ]
    },
    "CreateManagedPolicy": {
      "Fn::And": [
        {
          "Fn::Equals": [
            {
              "Fn::Join": [
                ",",
                {
                  "Ref": "ManagedPolicies"
                }
              ]
            },
            ""
          ]
        },
        {
          "Condition": "IAMAuthEnabledOnTargetClusterCondition"
        }
      ]
    },
    "CreateCloudWatchAlarmCondition": {
      "Fn::Equals": [
        {
          "Ref": "CreateCloudWatchAlarm"
        },
        "true"
      ]
    }
  },
  "Rules": {
    "ValidTargetClusterIdForIAMAuth": {
      "RuleCondition": {
        "Fn::Equals": [
          {
            "Ref": "IAMAuthEnabledOnTargetCluster"
          },
          "true"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Not": [
              {
                "Fn::Equals": [
                  "",
                  {
                    "Ref": "TargetNeptuneDBClusterResourceId"
                  }
                ]
              }
            ]
          },
          "AssertDescription": "Enter valid value for Cluster Resource Id to connect using IAMAuth."
        }
      ]
    },
    "ValidStreamClusterIdForIAMAuth": {
      "RuleCondition": {
        "Fn::Equals": [
          {
            "Ref": "IAMAuthEnabledOnSourceStream"
          },
          "true"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Not": [
              {
                "Fn::Equals": [
                  "",
                  {
                    "Ref": "StreamDBClusterResourceId"
                  }
                ]
              }
            ]
          },
          "AssertDescription": "Enter valid value for Cluster Resource Id to connect using IAMAuth."
        }
      ]
    },
    "DDBVPCEndpointRouteTableIdsCheck": {
      "RuleCondition": {
        "Fn::Equals": [
          {
            "Ref": "CreateDDBVPCEndPoint"
          },
          "true"
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Not": [
              {
                "Fn::Equals": [
                  "",
                  {
                    "Ref": "RouteTableIds"
                  }
                ]
              }
            ]
          },
          "AssertDescription": "Enter valid Route Table Id when creating DynamoDB VPC Endpoint."
        }
      ]
    },
    "SubnetsInVPC": {
      "Assertions": [
        {
          "Assert": {
            "Fn::EachMemberIn": [
              {
                "Fn::ValueOfAll": [
                  "AWS::EC2::Subnet::Id",
                  "VpcId"
                ]
              },
              {
                "Fn::RefAll": "AWS::EC2::VPC::Id"
              }
            ]
          },
          "AssertDescription": "All subnets must in the VPC"
        }
      ]
    },
    "ValidTargetSPARQLUpdateEndpoint": {
      "RuleCondition": {
        "Fn::Not": [
          {
            "Fn::Equals": [
              "",
              {
                "Ref": "TargetSPARQLUpdateEndpoint"
              }
            ]
          }
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Equals": [
              {
                "Ref": "TargetNeptuneClusterEndpoint"
              },
              ""
            ]
          },
          "AssertDescription": "Target Neptune Cluster is present, only one out of two can be present."
        }
      ]
    },
    "ValidTargetClusterEndpoint": {
      "RuleCondition": {
        "Fn::Not": [
          {
            "Fn::Equals": [
              "",
              {
                "Ref": "TargetNeptuneClusterEndpoint"
              }
            ]
          }
        ]
      },
      "Assertions": [
        {
          "Assert": {
            "Fn::Equals": [
              {
                "Ref": "TargetSPARQLUpdateEndpoint"
              },
              ""
            ]
          },
          "AssertDescription": "Needed one of Target SPARQL update endpoint or Target Neptune cluster endpoint but both are present. Must pass one of the value."
        }
      ]
    }
  },
  "Mappings": {
    "RuntimeMap": {
      "python3.12": {
        "keyname": "python312/release_2026_03_31"
      }
    },
    "ESHandler": {
      "python3.12": {
        "Gremlin": "neptune_to_neptune.neptune_to_neptune_gremlin_handler.NeptuneGremlinHandler",
        "Sparql": "neptune_to_neptune.neptune_to_neptune_sparql_handler.NeptuneSparqlHandler"
      }
    },
    "RegionalS3BucketMap": {
      "us-east-1": {
        "SamplesBucket": "aws-neptune-customer-samples-us-east-1"
      },
      "us-east-2": {
        "SamplesBucket": "aws-neptune-customer-samples-us-east-2"
      },
      "us-west-1": {
        "SamplesBucket": "aws-neptune-customer-samples-us-west-1"
      },
      "us-west-2": {
        "SamplesBucket": "aws-neptune-customer-samples-us-west-2"
      },
      "ca-central-1": {
        "SamplesBucket": "aws-neptune-customer-samples-ca-central-1"
      },
      "sa-east-1": {
        "SamplesBucket": "aws-neptune-customer-samples-sa-east-1"
      },
      "eu-north-1": {
        "SamplesBucket": "aws-neptune-customer-samples-eu-north-1"
      },
      "eu-west-1": {
        "SamplesBucket": "aws-neptune-customer-samples-eu-west-1"
      },
      "eu-west-2": {
        "SamplesBucket": "aws-neptune-customer-samples-eu-west-2"
      },
      "eu-west-3": {
        "SamplesBucket": "aws-neptune-customer-samples-eu-west-3"
      },
      "eu-central-1": {
        "SamplesBucket": "aws-neptune-customer-samples-eu-central-1"
      },
      "me-central-1": {
        "SamplesBucket": "aws-neptune-customer-samples-me-central-1"
      },
      "me-south-1": {
        "SamplesBucket": "aws-neptune-customer-samples-me-south-1"
      },
      "il-central-1": {
        "SamplesBucket": "aws-neptune-customer-samples-il-central-1"
      },
      "af-south-1": {
        "SamplesBucket": "aws-neptune-customer-samples-af-south-1"
      },
      "ap-east-1": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-east-1"
      },
      "ap-northeast-1": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-northeast-1"
      },
      "ap-northeast-2": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-northeast-2"
      },
      "ap-northeast-3": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-northeast-3"
      },
      "ap-southeast-1": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-southeast-1"
      },
      "ap-southeast-2": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-southeast-2"
      },
      "ap-southeast-3": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-southeast-3"
      },
      "ap-south-1": {
        "SamplesBucket": "aws-neptune-customer-samples-ap-south-1"
      },
      "cn-north-1": {
        "SamplesBucket": "aws-neptune-customer-samples-cn-north-1"
      },
      "cn-northwest-1": {
        "SamplesBucket": "aws-neptune-customer-samples-cn-northwest-1"
      },
      "us-gov-west-1": {
        "SamplesBucket": "aws-neptune-customer-samples-us-gov-west-1"
      },
      "us-gov-east-1": {
        "SamplesBucket": "aws-neptune-customer-samples-us-gov-east-1"
      }
    }
  },
  "Resources": {
    "ManagedPolicy": {
      "Type": "AWS::IAM::ManagedPolicy",
      "Condition": "CreateManagedPolicy",
      "Properties": {
        "Description": "Policy for Neptune Cluster Access for Neptune Lambda Poller",
        "Path": "/",
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": [
                "neptune-db:*"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Join": [
                  "",
                  [
                    {
                      "Fn::Sub": "arn:${AWS::Partition}:neptune-db"
                    },
                    ":",
                    {
                      "Fn::If": [
                        "TargetAWSRegionIsValid",
                        {
                          "Ref": "TargetAWSRegion"
                        },
                        {
                          "Ref": "AWS::Region"
                        }
                      ]
                    },
                    ":",
                    {
                      "Ref": "AWS::AccountId"
                    },
                    ":",
                    {
                      "Ref": "TargetNeptuneDBClusterResourceId"
                    },
                    "/*"
                  ]
                ]
              }
            }
          ]
        }
      }
    },
    "NeptuneStreamPoller": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "Parameters": {
          "AdditionalParams": {
            "Fn::Sub": [
              "{ \"NeptuneCluster\": \"${NeptuneCluster}\", \"TargetSPARQLUpdateEndpoint\": \"${TargetSPARQLUpdateEndpoint}\", \"IAMAuthEnabledOnTargetCluster\": \"${IAMAuthEnabledOnTargetCluster}\", \"targetRegion\": \"${TargetAWSRegion}\", \"SPARQLTripleOnlyMode\": \"${SPARQLTripleOnlyMode}\", \"BlockSparqlReplicationOnBlankNode\": \"${BlockSparqlReplicationOnBlankNode}\"}",
              {
                "NeptuneCluster": {
                  "Fn::Join": [
                    ":",
                    [
                      {
                        "Ref": "TargetNeptuneClusterEndpoint"
                      },
                      {
                        "Ref": "TargetNeptuneClusterPort"
                      }
                    ]
                  ]
                },
                "IAMAuthEnabledOnTargetCluster": {
                  "Fn::If": [
                    "IAMAuthEnabledOnTargetClusterCondition",
                    "true",
                    "false"
                  ]
                },
                "TargetAWSRegion": {
                  "Fn::If": [
                    "TargetAWSRegionIsValid",
                      {
                        "Ref": "TargetAWSRegion"
                      },
                      {
                        "Ref": "AWS::Region"
                      }
                  ]
                },
                "SPARQLTripleOnlyMode": {
                  "Fn::If": [
                    "SPARQLTripleOnlyModeIsTrue",
                    "true",
                    "false"
                  ]
                },
                "BlockSparqlReplicationOnBlankNode": {
                  "Fn::If": [
                    "BlockSparqlReplicationOnBlankNode",
                    "true",
                    "false"
                  ]
                }
              }
            ]
          },
          "ApplicationName": {
            "Ref": "ApplicationName"
          },
          "LambdaMemorySize": {
            "Ref": "LambdaMemorySize"
          },
          "LambdaRuntime": {
            "Ref": "LambdaRuntime"
          },
          "LambdaS3Bucket": {
            "Fn::If": [
              "IsEmptyLambdaS3Bucket",
              {
                "Fn::FindInMap": [
                  "RegionalS3BucketMap",
                  {
                    "Ref": "AWS::Region"
                  },
                  "SamplesBucket"
                ]
              },
              {
                "Ref": "LambdaS3Bucket"
              }
            ]
          },
          "LambdaS3Key": {
            "Fn::If": [
              "IsEmptyLambdaS3Key",
              {
                "Fn::Join": [
                  "/",
                  [
                    "neptune-stream",
                    "lambda",
                    {
                      "Fn::FindInMap": [
                        "RuntimeMap",
                        {
                          "Ref": "LambdaRuntime"
                        },
                        "keyname"
                      ]
                    },
                    "neptune-to-neptune.zip"
                  ]
                ]
              },
              {
                "Ref": "LambdaS3Key"
              }
            ]
          },
          "LambdaLoggingLevel": {
            "Ref": "LambdaLoggingLevel"
          },
          "ManagedPolicies": {
            "Fn::If": [
              "CreateManagedPolicy",
              {
                "Ref": "ManagedPolicy"
              },
              {
                "Fn::Join": [
                  ",",
                  {
                    "Ref": "ManagedPolicies"
                  }
                ]
              }
            ]
          },
          "StreamRecordsHandler": {
            "Fn::If": [
              "IsEmptyStreamRecordsHandler",
              {
                "Fn::FindInMap": [
                  "ESHandler",
                  {
                    "Ref": "LambdaRuntime"
                  },
                  {
                    "Ref": "QueryEngine"
                  }
                ]
              },
              {
                "Ref": "StreamRecordsHandler"
              }
            ]
          },
          "StreamRecordsBatchSize": {
            "Ref": "StreamRecordsBatchSize"
          },
          "StepFunctionFallbackPeriod": {
            "Ref": "StepFunctionFallbackPeriod"
          },
          "StepFunctionFallbackPeriodUnit": {
            "Ref": "StepFunctionFallbackPeriodUnit"
          },
          "MaxPollingWaitTime": {
            "Ref": "MaxPollingWaitTime"
          },
          "IAMAuthEnabledOnSourceStream": {
            "Ref": "IAMAuthEnabledOnSourceStream"
          },
          "StreamDBClusterResourceId": {
            "Ref": "StreamDBClusterResourceId"
          },
          "NeptuneStreamEndpoint": {
            "Ref": "NeptuneStreamEndpoint"
          },
          "MaxPollingInterval": {
            "Ref": "MaxPollingInterval"
          },
          "VPC": {
            "Ref": "VPC"
          },
          "RouteTableIds": {
            "Ref": "RouteTableIds"
          },
          "CreateDDBVPCEndPoint": {
            "Ref": "CreateDDBVPCEndPoint"
          },
          "CreateMonitoringEndPoint": {
            "Ref": "CreateMonitoringEndPoint"
          },
          "CreateCloudWatchAlarm": {
            "Ref": "CreateCloudWatchAlarm"
          },
          "NotificationSNSTopicArn": {
            "Ref": "NotificationSNSTopicArn"
          },
          "NotificationEmail": {
            "Ref": "NotificationEmail"
          },
          "SubnetIds": {
            "Fn::Join": [
              ",",
              {
                "Ref": "SubnetIds"
              }
            ]
          },
          "SecurityGroupIds": {
            "Fn::Join": [
              ",",
              {
                "Ref": "SecurityGroupIds"
              }
            ]
          },
          "StreamPollerInitialState": {
            "Ref" : "StreamPollerInitialState"
          },
          "StartingCheckpoint" : {
            "Ref" : "StartingCheckpoint"
          }
        },
        "TemplateURL": "https://s3.amazonaws.com/aws-neptune-customer-samples/neptune-stream/neptune_stream_poller_nested_full_stack.json"
      }
    }
  },
  "Outputs": {
    "HTTPSAccessSG": {
      "Description": "HTTPS Access Security Group Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.HTTPSAccessSG"
        ]
      }
    },
    "LeaseDynamoDBTable": {
      "Description": "Neptune Stream Poller Lease Table",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.LeaseDynamoDBTable"
        ]
      }
    },
    "StateMachineArn": {
      "Description": "Neptune Stream Poller State Machine Arn",
      "Condition" : "CreateCloudWatchAlarmCondition",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.StateMachineArn"
        ]
      }
    },
    "CronArn": {
      "Description": "Neptune Stream Poller Scheduler Cron Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.CronArn"
        ]
      }
    },
    "StateMachineAlarmArn": {
      "Description": "Neptune Stream Poller State Machine Alarm Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.StateMachineAlarmArn"
        ]
      }
    },
    "NeptuneStreamPollerLambdaArn": {
      "Description": "Neptune Stream Poller Lambda Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.NeptuneStreamPollerLambdaArn"
        ]
      }
    },
    "CloudWatchMetricsDashboardURI": {
      "Description": "CloudWatch Metrics Dashboard URI",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPoller",
          "Outputs.CloudWatchMetricsDashboardURI"
        ]
      }
    }
  }
}
