diff --git a/services/search-index-lambda/.gitignore b/services/search-index-lambda/.gitignore
new file mode 100644
diff --git a/services/terraform/dev/main.tf b/services/terraform/dev/main.tf
--- a/services/terraform/dev/main.tf
+++ b/services/terraform/dev/main.tf
@@ -45,8 +45,8 @@
 module "shared" {
   source = "../modules/shared"
   is_dev = true
-    
-  vpc_id = null
+
+  vpc_id     = null
   cidr_block = null
   subnet_ids = []
 }
diff --git a/services/terraform/modules/shared/dynamodb.tf b/services/terraform/modules/shared/dynamodb.tf
--- a/services/terraform/modules/shared/dynamodb.tf
+++ b/services/terraform/modules/shared/dynamodb.tf
@@ -83,7 +83,7 @@
   name         = "tunnelbroker-undelivered-messages"
   hash_key     = "deviceID"
   range_key    = "messageID"
-  billing_mode = "PAY_PER_REQUEST" 
+  billing_mode = "PAY_PER_REQUEST"
 
   attribute {
     name = "deviceID"
@@ -97,9 +97,9 @@
 }
 
 resource "aws_dynamodb_table" "identity-users" {
-  name         = "identity-users"
-  hash_key     = "userID"
-  billing_mode = "PAY_PER_REQUEST" 
+  name             = "identity-users"
+  hash_key         = "userID"
+  billing_mode     = "PAY_PER_REQUEST"
   stream_enabled   = true
   stream_view_type = "NEW_AND_OLD_IMAGES"
 
diff --git a/services/terraform/modules/shared/opensearch.tf b/services/terraform/modules/shared/opensearch.tf
--- a/services/terraform/modules/shared/opensearch.tf
+++ b/services/terraform/modules/shared/opensearch.tf
@@ -3,8 +3,13 @@
 }
 
 resource "aws_security_group" "identity-search" {
+<<<<<<< HEAD
   count = var.is_dev ? 0 : 1 
   name        = "${var.vpc_id}-opensearch-service-${var.domain}"
+=======
+  count       = var.is_dev ? 0 : 1
+  name        = "${var.vpc_id}-opensearch-${var.domain}"
+>>>>>>> 4c897e8d3 ([terraform] [4/n] search_index_lambda terraform configuration options)
   description = "Managed by Terraform"
   vpc_id      = var.is_dev ? null : var.vpc_id
 
@@ -29,7 +34,7 @@
   engine_version = "OpenSearch_1.0"
 
   cluster_config {
-    instance_type          = "t3.medium.search"
+    instance_type = "t3.medium.search"
   }
 
   vpc_options {
diff --git a/services/terraform/modules/shared/outputs.tf b/services/terraform/modules/shared/outputs.tf
--- a/services/terraform/modules/shared/outputs.tf
+++ b/services/terraform/modules/shared/outputs.tf
@@ -4,6 +4,7 @@
     aws_dynamodb_table.backup-service-backup,
     aws_dynamodb_table.reports-service-reports,
     aws_dynamodb_table.tunnelbroker-undelivered-messages,
+    aws_dynamodb_table.identity-users,
   ]
 }
 
diff --git a/services/terraform/modules/shared/search_index_lambda.tf b/services/terraform/modules/shared/search_index_lambda.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/modules/shared/search_index_lambda.tf
@@ -0,0 +1,62 @@
+variable "search_index_lambda_iam_role_arn" {
+  default = "arn:aws:iam::000000000000:role/lambda-role"
+}
+
+
+variable "lambda_zip_dir" {
+  type    = string
+  default = "../../search-index-lambda/target/lambda/search-index-lambda"
+}
+
+resource "aws_lambda_function" "search_index_lambda" {
+  function_name    = "search-index-lambda-function"
+  filename         = "${var.lambda_zip_dir}/bootstrap.zip"
+  source_code_hash = filebase64sha256("${var.lambda_zip_dir}/bootstrap.zip")
+  handler          = "bootstrap"
+  role             = var.search_index_lambda_iam_role_arn
+  runtime          = "provided.al2"
+  architectures    = ["arm64"]
+  timeout          = 300
+
+  vpc_config {
+    subnet_ids         = var.subnet_ids
+    security_group_ids = [aws_security_group.search_index_lambda.id]
+  }
+
+  environment {
+    variables = {
+      RUST_BACKTRACE      = "1"
+      OPENSEARCH_ENDPOINT = aws_opensearch_domain.identity-search.endpoint
+    }
+  }
+
+  tracing_config {
+    mode = "Active"
+  }
+}
+
+resource "aws_lambda_event_source_mapping" "trigger" {
+  count             = var.is_dev ? 0 : 1
+  event_source_arn  = aws_dynamodb_table.identity-users.stream_arn
+  function_name     = aws_lambda_function.search_index_lambda.arn
+  starting_position = "LATEST"
+}
+
+resource "aws_security_group" "search_index_lambda" {
+  name   = "search_index_lambda_sg"
+  vpc_id = var.vpc_id
+
+  egress {
+    from_port   = 443
+    to_port     = 443
+    protocol    = "tcp"
+    cidr_blocks = ["0.0.0.0/0"]
+  }
+}
+
+
+resource "aws_lambda_function_event_invoke_config" "example" {
+  function_name                = aws_lambda_function.search_index_lambda.function_name
+  maximum_event_age_in_seconds = 60
+  maximum_retry_attempts       = 2
+}
diff --git a/services/terraform/remote/aws_iam.tf b/services/terraform/remote/aws_iam.tf
--- a/services/terraform/remote/aws_iam.tf
+++ b/services/terraform/remote/aws_iam.tf
@@ -195,13 +195,88 @@
   ]
 }
 
+
+data "aws_iam_policy_document" "assume_identity_search_role" {
+  statement {
+    effect = "Allow"
+
+    principals {
+      type        = "Service"
+      identifiers = ["lambda.amazonaws.com"]
+    }
+
+    actions = ["sts:AssumeRole"]
+  }
+}
+
+resource "aws_iam_role" "search_index_lambda" {
+  name               = "search_index_lambda"
+  assume_role_policy = data.aws_iam_policy_document.assume_identity_search_role.json
+
+  managed_policy_arns = [
+    aws_iam_policy.manage_cloudwatch_logs.arn,
+    aws_iam_policy.read_identity_users_stream.arn,
+  ]
+}
+
+data "aws_iam_policy_document" "read_identity_users_stream" {
+  statement {
+    effect = "Allow"
+
+    actions = [
+      "dynamodb:GetRecords",
+      "dynamodb:GetShardIterator",
+      "dynamodb:DescribeStream",
+      "dynamodb:ListStreams",
+    ]
+    resources = [
+      module.shared.dynamodb_tables["identity-users"].arn,
+      module.shared.dynamodb_tables["identity-users"].stream_arn,
+      "${module.shared.dynamodb_tables["identity-users"].arn}/stream/*",
+    ]
+  }
+}
+
+resource "aws_iam_policy" "read_identity_users_stream" {
+  name        = "read-identity-users-stream"
+  path        = "/"
+  description = "IAM policy for managing identity-users stream"
+  policy      = data.aws_iam_policy_document.read_identity_users_stream.json
+}
+
+data "aws_iam_policy_document" "manage_cloudwatch_logs" {
+  statement {
+    effect = "Allow"
+
+    actions = [
+      "logs:CreateLogGroup",
+      "logs:CreateLogStream",
+      "logs:PutLogEvents",
+    ]
+
+    resources = ["arn:aws:logs:*:*:*"]
+  }
+}
+
+resource "aws_iam_policy" "manage_cloudwatch_logs" {
+  name        = "manage-cloudwatch-logs"
+  path        = "/"
+  description = "IAM policy for managing cloudwatch logs"
+  policy      = data.aws_iam_policy_document.manage_cloudwatch_logs.json
+}
+
+resource "aws_iam_role_policy_attachment" "AWSLambdaVPCAccessExecutionRole" {
+  role       = aws_iam_role.search_index_lambda.name
+  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
+}
+
 data "aws_iam_policy_document" "opensearch_domain_access" {
   statement {
     effect = "Allow"
 
     principals {
       type        = "*"
-      identifiers = []
+      identifiers = ["${aws_iam_role.search_index_lambda.arn}"]
     }
 
     actions = [
@@ -220,3 +295,4 @@
   domain_name     = module.shared.opensearch_domain_identity.domain_name
   access_policies = data.aws_iam_policy_document.opensearch_domain_access.json
 }
+
diff --git a/services/terraform/remote/main.tf b/services/terraform/remote/main.tf
--- a/services/terraform/remote/main.tf
+++ b/services/terraform/remote/main.tf
@@ -52,8 +52,9 @@
   source             = "../modules/shared"
   bucket_name_suffix = local.s3_bucket_name_suffix
 
-  vpc_id     = aws_vpc.default.id
-  cidr_block = aws_vpc.default.cidr_block
+  vpc_id                           = aws_vpc.default.id
+  search_index_lambda_iam_role_arn = aws_iam_role.search_index_lambda.arn
+  cidr_block                       = aws_vpc.default.cidr_block
   subnet_ids = [
     aws_subnet.public_a.id,
   ]