From 74b0014803428f9813491c9c99366093eca96a75 Mon Sep 17 00:00:00 2001 From: vijay-stephen Date: Thu, 14 Nov 2024 10:34:18 +0000 Subject: [PATCH] Merge pull request #29 from sourcefuse/feature/refactor-opensearch Opensearch module refactor --- .../terraform-aws-arc-opensearch/README.md | 214 ++++++++++++------ 1 file changed, 141 insertions(+), 73 deletions(-) diff --git a/docs/arc-iac-docs/modules/terraform-aws-arc-opensearch/README.md b/docs/arc-iac-docs/modules/terraform-aws-arc-opensearch/README.md index 1a542f393..7abc9ff69 100644 --- a/docs/arc-iac-docs/modules/terraform-aws-arc-opensearch/README.md +++ b/docs/arc-iac-docs/modules/terraform-aws-arc-opensearch/README.md @@ -8,7 +8,7 @@ [![Known Vulnerabilities](https://github.com/sourcefuse/terraform-aws-arc-opensearch/actions/workflows/snyk.yaml/badge.svg)](https://github.com/sourcefuse/terraform-aws-arc-opensearch/actions/workflows/snyk.yaml) ## Overview -Terraform module for supporting AWS OpenSearch. Creates an admin role and outputs parameters to SSM for downstream utilization or additional automation. +Terraform module for Amazon OpenSearch provides a flexible and scalable way to deploy and manage OpenSearch clusters, with support for both serverless and managed (provisioned) deployment options. ## Usage @@ -19,20 +19,45 @@ See the `example/vpc` folder for a working module example. ## opensearch ################################################################################ module "opensearch" { - source = "sourcefuse/arc-opensearch/aws" - version = "0.1.2" - environment = var.environment - namespace = var.namespace - vpc_id = data.aws_vpc.default.id - create_iam_service_linked_role = false # set to false if a cluster already exists - subnet_ids = local.private_subnet_ids - availability_zones = local.private_subnet_azs + source = "sourcefuse/arc-opensearch/aws" + version = "0.1.2" + namespace = var.namespace + environment = var.environment + name = var.name + engine_version = var.engine_version + instance_type = var.instance_type + instance_count = var.instance_count + enable_vpc_options = true + vpc_id = data.aws_vpc.default.id + subnet_ids = local.private_subnet_ids + ingress_rules = local.ingress_rules + egress_rules = local.egress_rules tags = module.tags.tags } +################################################################################ +## opensearch serverless +################################################################################ + module "opensearch_serverless" { + source = "sourcefuse/arc-opensearch/aws" + version = "0.1.2" + enable_serverless = true + namespace = var.namespace + environment = var.environment + name = var.name + ingress_rules = local.ingress_rules + egress_rules = local.egress_rules + subnet_ids = local.private_subnet_ids + vpc_id = data.aws_vpc.default.id + data_lifecycle_policy_rules = local.data_lifecycle_policy_rules + access_policy_rules = local.access_policy_rules + tags = module.tags.tags + +} + ``` -See the `example/non-vpc` folder if you want your os to be public +See the `example/public` folder if you want your os to be public ```hcl ################################################################################ @@ -41,16 +66,32 @@ See the `example/non-vpc` folder if you want your os to be public module "opensearch" { source = "sourcefuse/arc-opensearch/aws" version = "1.0.3" - environment = var.environment namespace = var.namespace - create_iam_service_linked_role = false # set to false if a cluster already exists - instance_count = var.instance_count + environment = var.environment + name = var.name + engine_version = var.engine_version instance_type = var.instance_type - ebs_volume_size = var.ebs_volume_size - vpc_enabled = false - allowed_cidr_blocks = [""] // non VPC ES to allow anonymous access from whitelisted IP ranges without requests signing - anonymous_iam_actions = ["es:ESHttpGet", "es:ESHttpPut", "es:ESHttpPost"] // Actions for anonymous user - iam_actions = ["es:ESHttpGet", "es:ESHttpPut", "es:ESHttpPost"] // Actions for user + instance_count = var.instance_count + enable_encrypt_at_rest = true + enable_domain_endpoint_options = true + advanced_security_enabled = true + + tags = module.tags.tags +} + +################################################################################ +## opensearch serverless +################################################################################ +module "opensearch_serverless" { + source = "sourcefuse/arc-opensearch/aws" + version = "1.0.3" + enable_serverless = true + namespace = var.namespace + environment = var.environment + name = var.name + enable_public_access = true + data_lifecycle_policy_rules = local.data_lifecycle_policy_rules + access_policy_rules = local.access_policy_rules tags = module.tags.tags } @@ -62,88 +103,115 @@ module "opensearch" { | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.5, < 2.0.0 | -| [aws](#requirement\_aws) | >= 4.0, < 6.0 | -| [null](#requirement\_null) | >= 3.2 | -| [random](#requirement\_random) | >= 3.4 | +| [terraform](#requirement\_terraform) | >= 1.5.0 | +| [aws](#requirement\_aws) | ~> 5.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | 4.54.0 | -| [random](#provider\_random) | 3.4.3 | +| [aws](#provider\_aws) | 5.74.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [opensearch](#module\_opensearch) | cloudposse/elasticsearch/aws | 0.47.0 | +| [opensearch](#module\_opensearch) | ./modules/opensearch-domain | n/a | +| [opensearch\_serverless](#module\_opensearch\_serverless) | ./modules/opensearch-serverless | n/a | ## Resources | Name | Type | |------|------| -| [aws_iam_role.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role.read_only](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | -| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_iam_role_policy_attachment.read_only](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | -| [aws_ssm_parameter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | -| [random_password.admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [additional\_iam\_role\_arns](#input\_additional\_iam\_role\_arns) | List of additional IAM role ARNs to permit access to the Elasticsearch domain | `list(string)` | `[]` | no | -| [admin\_username](#input\_admin\_username) | Admin username when fine grained access control | `string` | `"os_admin"` | no | -| [advanced\_options](#input\_advanced\_options) | Key-value string pairs to specify advanced configuration options | `map(any)` |
{
"override_main_response_version": false,
"rest.action.multi.allow_explicit_index": "true"
}
| no | -| [advanced\_security\_options\_enabled](#input\_advanced\_security\_options\_enabled) | AWS Elasticsearch Kibana enchanced security plugin enabling (forces new resource) | `bool` | `true` | no | -| [advanced\_security\_options\_internal\_user\_database\_enabled](#input\_advanced\_security\_options\_internal\_user\_database\_enabled) | Whether to enable or not internal Kibana user database for ELK OpenDistro security plugin | `bool` | `true` | no | -| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks to be allowed to connect to the cluster | `list(string)` | `[]` | no | -| [anonymous\_iam\_actions](#input\_anonymous\_iam\_actions) | List of actions to allow for the anonymous (`*`) IAM roles, _e.g._ `es:ESHttpGet`, `es:ESHttpPut`, `es:ESHttpPost` | `list(string)` | `[]` | no | -| [availability\_zones](#input\_availability\_zones) | List of availability zones to deploy the cluster in. | `list(string)` |
[
"us-east-1a",
"us-east-1b"
]
| no | -| [cognito\_authentication\_enabled](#input\_cognito\_authentication\_enabled) | Whether to enable Amazon Cognito authentication with Kibana | `bool` | `false` | no | -| [cognito\_iam\_role\_arn](#input\_cognito\_iam\_role\_arn) | ARN of the IAM role that has the AmazonESCognitoAccess policy attached | `string` | `""` | no | -| [cognito\_identity\_pool\_id](#input\_cognito\_identity\_pool\_id) | The ID of the Cognito Identity Pool to use | `string` | `""` | no | -| [cognito\_user\_pool\_id](#input\_cognito\_user\_pool\_id) | The ID of the Cognito User Pool to use | `string` | `""` | no | -| [create\_iam\_service\_linked\_role](#input\_create\_iam\_service\_linked\_role) | Whether to create `AWSServiceRoleForAmazonElasticsearchService` service-linked role. Set it to `false` if you already have an ElasticSearch cluster created in the AWS account and AWSServiceRoleForAmazonElasticsearchService already exists. See https://github.com/terraform-providers/terraform-provider-aws/issues/5218 for more info | `bool` | `true` | no | -| [custom\_endpoint](#input\_custom\_endpoint) | Fully qualified domain for custom endpoint. | `string` | `""` | no | -| [custom\_endpoint\_certificate\_arn](#input\_custom\_endpoint\_certificate\_arn) | ACM certificate ARN for custom endpoint. | `string` | `""` | no | -| [custom\_endpoint\_enabled](#input\_custom\_endpoint\_enabled) | Whether to enable custom endpoint for the Elasticsearch domain. | `bool` | `false` | no | -| [custom\_opensearch\_password](#input\_custom\_opensearch\_password) | Custom Administrator password to be assigned to `var.admin_username`. If undefined, it will be a randomly generated password. Does not work if `var.generate_random_password` is `true`. | `string` | `""` | no | -| [ebs\_volume\_size](#input\_ebs\_volume\_size) | EBS volumes for data storage in GB | `number` | `10` | no | -| [elasticsearch\_version](#input\_elasticsearch\_version) | Version of ElasticSearch or OpenSearch to deploy (\_e.g.\_ OpenSearch\_2.3, OpenSearch\_1.3, OpenSearch\_1.2, OpenSearch\_1.1, OpenSearch\_1.0, 7.4, 7.1, etc. | `string` | `"OpenSearch_2.3"` | no | -| [enable\_public\_access](#input\_enable\_public\_access) | Set to false if ES should be deployed outside of VPC. | `bool` | `false` | no | -| [encrypt\_at\_rest\_enabled](#input\_encrypt\_at\_rest\_enabled) | Whether to enable encryption at rest | `bool` | `true` | no | +| [access\_policies](#input\_access\_policies) | Custom access policy for OpenSearch domain. If empty, default policy will be used | `string` | `""` | no | +| [access\_policy\_rules](#input\_access\_policy\_rules) | List of rules for the access policy. |
list(object({
resource_type = string
resource = list(string)
permissions = list(string)
}))
| `[]` | no | +| [advanced\_security\_enabled](#input\_advanced\_security\_enabled) | Enable advanced security options (fine-grained access control) | `bool` | `false` | no | +| [anonymous\_auth\_enabled](#input\_anonymous\_auth\_enabled) | Enable anonymous authentication | `bool` | `false` | no | +| [auto\_software\_update\_enabled](#input\_auto\_software\_update\_enabled) | Enable automatic software updates for OpenSearch | `bool` | `false` | no | +| [auto\_tune\_cron\_expression](#input\_auto\_tune\_cron\_expression) | Cron expression for Auto-Tune maintenance schedule | `string` | `"0 1 * * ?"` | no | +| [auto\_tune\_desired\_state](#input\_auto\_tune\_desired\_state) | Desired state of Auto-Tune | `string` | `"ENABLED"` | no | +| [auto\_tune\_duration\_unit](#input\_auto\_tune\_duration\_unit) | Duration unit for Auto-Tune maintenance | `string` | `"HOURS"` | no | +| [auto\_tune\_duration\_value](#input\_auto\_tune\_duration\_value) | Duration value for Auto-Tune maintenance | `number` | `1` | no | +| [auto\_tune\_start\_at](#input\_auto\_tune\_start\_at) | Start time for Auto-Tune maintenance | `string` | `"2024-10-23T01:00:00Z"` | no | +| [availability\_zone\_count](#input\_availability\_zone\_count) | The number of availability zones to use for zone awareness. | `number` | `2` | no | +| [cognito\_identity\_pool\_id](#input\_cognito\_identity\_pool\_id) | Cognito Identity Pool ID | `string` | `""` | no | +| [cognito\_user\_pool\_id](#input\_cognito\_user\_pool\_id) | Cognito User Pool ID | `string` | `""` | no | +| [create\_access\_policy](#input\_create\_access\_policy) | Flag to determine if access policy should be created. | `bool` | `true` | no | +| [create\_data\_lifecycle\_policy](#input\_create\_data\_lifecycle\_policy) | Flag to determine if data lifecycle policy should be created. | `bool` | `true` | no | +| [create\_encryption\_policy](#input\_create\_encryption\_policy) | Flag to determine if encryption policy should be created. | `bool` | `true` | no | +| [custom\_certificate\_arn](#input\_custom\_certificate\_arn) | ARN of the ACM certificate for the custom endpoint | `string` | `""` | no | +| [custom\_hostname](#input\_custom\_hostname) | Custom domain name for the OpenSearch endpoint | `string` | `""` | no | +| [data\_lifecycle\_policy\_rules](#input\_data\_lifecycle\_policy\_rules) | Data lifecycle policy rules for the indices. |
list(object({
indexes = list(string)
retention = string
}))
|
[
{
"indexes": [
"*"
],
"retention": "Unlimited"
}
]
| no | +| [dedicated\_master\_count](#input\_dedicated\_master\_count) | Number of dedicated master instances | `number` | `3` | no | +| [dedicated\_master\_enabled](#input\_dedicated\_master\_enabled) | Whether dedicated master is enabled | `bool` | `false` | no | +| [dedicated\_master\_type](#input\_dedicated\_master\_type) | Instance type for the dedicated master node | `string` | `"m5.large.search"` | no | +| [description](#input\_description) | A description for the OpenSearch collection. | `string` | `"OpenSearch collection domain for logs and search"` | no | +| [ebs\_enabled](#input\_ebs\_enabled) | Whether EBS is enabled for the domain | `bool` | `true` | no | +| [egress\_rules](#input\_egress\_rules) | A list of egress rules for the security group. |
list(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
| `[]` | no | +| [enable\_auto\_tune](#input\_enable\_auto\_tune) | Enable Auto-Tune for the domain | `bool` | `false` | no | +| [enable\_cognito\_options](#input\_enable\_cognito\_options) | Enable Cognito authentication for the OpenSearch domain | `bool` | `false` | no | +| [enable\_custom\_endpoint](#input\_enable\_custom\_endpoint) | Enable custom domain endpoint | `bool` | `false` | no | +| [enable\_domain\_endpoint\_options](#input\_enable\_domain\_endpoint\_options) | Enable custom domain endpoint options for the OpenSearch domain. | `bool` | `false` | no | +| [enable\_encrypt\_at\_rest](#input\_enable\_encrypt\_at\_rest) | Enable encryption at rest for the OpenSearch domain. | `bool` | `false` | no | +| [enable\_off\_peak\_window\_options](#input\_enable\_off\_peak\_window\_options) | Enable off-peak window options for the domain | `bool` | `false` | no | +| [enable\_public\_access](#input\_enable\_public\_access) | Enable public access for the OpenSearch collection. If false, private access will be used. | `bool` | `false` | no | +| [enable\_serverless](#input\_enable\_serverless) | Enable OpenSearch Serverless. If true, creates the serverless module; if false, creates the standard module. | `bool` | `false` | no | +| [enable\_snapshot\_options](#input\_enable\_snapshot\_options) | Enable snapshot options for the domain | `bool` | `false` | no | +| [enable\_vpc\_options](#input\_enable\_vpc\_options) | Enable VPC options for the OpenSearch domain. | `bool` | `false` | no | +| [enable\_zone\_awareness](#input\_enable\_zone\_awareness) | Enable zone awareness for the OpenSearch domain. | `bool` | `false` | no | +| [encrypt\_at\_rest\_enabled](#input\_encrypt\_at\_rest\_enabled) | Enable encryption at rest | `bool` | `true` | no | +| [enforce\_https](#input\_enforce\_https) | Force HTTPS on the OpenSearch endpoint | `bool` | `true` | no | +| [engine\_version](#input\_engine\_version) | OpenSearch or Elasticsearch engine version | `string` | `"OpenSearch_1.0"` | no | | [environment](#input\_environment) | Name of the environment, i.e. dev, stage, prod | `string` | n/a | yes | -| [generate\_random\_password](#input\_generate\_random\_password) | Generate a random password for the OpenSearch Administrator.
If this value is `true` and `var.custom_opensearch_password` is defined, `var.custom_opensearch_password` will be ignored. | `bool` | `true` | no | -| [iam\_actions](#input\_iam\_actions) | List of actions to allow for the IAM roles, e.g. es:ESHttpGet, es:ESHttpPut, es:ESHttpPost | `list(string)` | `[]` | no | -| [instance\_count](#input\_instance\_count) | Number of data nodes in the cluster. | `number` | `2` | no | -| [instance\_type](#input\_instance\_type) | ElasticSearch or OpenSearch instance type for data nodes in the cluster | `string` | `"t3.medium.elasticsearch"` | no | -| [kibana\_subdomain\_name](#input\_kibana\_subdomain\_name) | The name of the subdomain for Kibana in the DNS zone (\_e.g.\_ kibana, ui, ui-es, search-ui, kibana.elasticsearch) | `string` | `""` | no | -| [name](#input\_name) | Name of the OpenSearch resource | `string` | n/a | yes | +| [ingress\_rules](#input\_ingress\_rules) | A list of ingress rules for the security group. |
list(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
| `[]` | no | +| [instance\_count](#input\_instance\_count) | Number of instances in the cluster | `number` | `2` | no | +| [instance\_type](#input\_instance\_type) | Instance type for the OpenSearch domain | `string` | `"m5.large.search"` | no | +| [internal\_user\_database\_enabled](#input\_internal\_user\_database\_enabled) | Enable internal user database for fine-grained access control | `bool` | `true` | no | +| [iops](#input\_iops) | Provisioned IOPS for the volume | `number` | `null` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | KMS key ID for encryption at rest | `string` | `""` | no | +| [log\_publishing\_enabled](#input\_log\_publishing\_enabled) | Whether to enable the log publishing option. | `bool` | `true` | no | +| [log\_types](#input\_log\_types) | List of log types to publish to CloudWatch (Valid values: INDEX\_SLOW\_LOGS, SEARCH\_SLOW\_LOGS, ES\_APPLICATION\_LOGS, AUDIT\_LOGS) | `list(string)` |
[
"INDEX_SLOW_LOGS",
"SEARCH_SLOW_LOGS"
]
| no | +| [master\_user\_arn](#input\_master\_user\_arn) | The ARN of the IAM role for fine-grained access control. Required if use\_iam\_arn\_as\_master\_user is true. | `string` | `""` | no | +| [master\_user\_name](#input\_master\_user\_name) | Master user name for OpenSearch | `string` | `"admin"` | no | +| [name](#input\_name) | Name of the OpenSearch domain | `string` | n/a | yes | | [namespace](#input\_namespace) | Namespace of the project, i.e. arc | `string` | n/a | yes | -| [node\_to\_node\_encryption\_enabled](#input\_node\_to\_node\_encryption\_enabled) | Whether to enable node-to-node encryption | `bool` | `true` | no | -| [security\_group\_ids](#input\_security\_group\_ids) | List of security groups to assign OpenSearch | `list(string)` | `[]` | no | -| [subnet\_ids](#input\_subnet\_ids) | List of Subnet IDs to assign OpenSearch | `list(string)` | `[]` | no | -| [tags](#input\_tags) | Default tags to apply to every resource | `map(string)` | n/a | yes | -| [vpc\_id](#input\_vpc\_id) | ID of the VPC where resources will be deployed to | `string` | `null` | no | -| [zone\_awareness\_enabled](#input\_zone\_awareness\_enabled) | Enable zone awareness for Elasticsearch cluster | `bool` | `true` | no | +| [node\_to\_node\_encryption\_enabled](#input\_node\_to\_node\_encryption\_enabled) | Enable node-to-node encryption | `bool` | `true` | no | +| [off\_peak\_hours](#input\_off\_peak\_hours) | Off-peak window start time (hours) | `number` | `0` | no | +| [off\_peak\_minutes](#input\_off\_peak\_minutes) | Off-peak window start time (minutes) | `number` | `0` | no | +| [retention\_in\_days](#input\_retention\_in\_days) | The number of days to retain log events in the log group | `number` | `7` | no | +| [saml\_options](#input\_saml\_options) | Configuration block for SAML options in the OpenSearch domain. |
object({
enabled = bool
idp_entity_id = optional(string)
idp_metadata_content = optional(string)
roles_key = optional(string)
session_timeout_minutes = optional(number)
subject_key = optional(string)
})
|
{
"enabled": false,
"idp_entity_id": null,
"idp_metadata_content": null,
"roles_key": null,
"session_timeout_minutes": null,
"subject_key": null
}
| no | +| [security\_group\_name](#input\_security\_group\_name) | Name for the security group | `string` | `""` | no | +| [snapshot\_start\_hour](#input\_snapshot\_start\_hour) | Start hour for the automated snapshot | `number` | `0` | no | +| [subnet\_ids](#input\_subnet\_ids) | List of subnet IDs for the OpenSearch domain | `list(string)` | `[]` | no | +| [tags](#input\_tags) | Tags to apply to resources | `map(string)` | n/a | yes | +| [throughput](#input\_throughput) | Provisioned throughput for the volume | `number` | `null` | no | +| [tls\_security\_policy](#input\_tls\_security\_policy) | TLS security policy for HTTPS endpoints | `string` | `"Policy-Min-TLS-1-2-PFS-2023-10"` | no | +| [type](#input\_type) | The type of OpenSearch collection. | `string` | `"TIMESERIES"` | no | +| [use\_iam\_arn\_as\_master\_user](#input\_use\_iam\_arn\_as\_master\_user) | Set to true to use IAM ARN as the master user, false to create a master user. | `bool` | `false` | no | +| [use\_standby\_replicas](#input\_use\_standby\_replicas) | Flag to enable or disable standby replicas. | `bool` | `true` | no | +| [use\_ultrawarm](#input\_use\_ultrawarm) | Whether to enable UltraWarm nodes | `bool` | `false` | no | +| [volume\_size](#input\_volume\_size) | EBS volume size in GB | `number` | `20` | no | +| [volume\_type](#input\_volume\_type) | EBS volume type | `string` | `"gp2"` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC for OpenSearch domain | `string` | `null` | no | +| [warm\_count](#input\_warm\_count) | Number of UltraWarm instances | `number` | `2` | no | +| [warm\_type](#input\_warm\_type) | UltraWarm node instance type | `string` | `"ultrawarm1.medium.search"` | no | +| [zone\_awareness\_enabled](#input\_zone\_awareness\_enabled) | Whether zone awareness is enabled | `bool` | `true` | no | ## Outputs | Name | Description | |------|-------------| -| [domain\_arn](#output\_domain\_arn) | ARN of the OpenSearch domain | -| [domain\_endpoint](#output\_domain\_endpoint) | Domain-specific endpoint used to submit index, search, and data upload requests | -| [domain\_hostname](#output\_domain\_hostname) | OpenSearch domain hostname to submit index, search, and data upload requests | -| [domain\_id](#output\_domain\_id) | Unique identifier for the OpenSearch domain | -| [kibana\_endpoint](#output\_kibana\_endpoint) | Domain-specific endpoint for Kibana without https scheme | -| [kibana\_hostname](#output\_kibana\_hostname) | Kibana hostname | -| [opensearch\_user\_iam\_role\_arn](#output\_opensearch\_user\_iam\_role\_arn) | The ARN of the IAM role to allow access to OpenSearch cluster | -| [opensearch\_user\_iam\_role\_name](#output\_opensearch\_user\_iam\_role\_name) | The name of the IAM role to allow access to OpenSearch cluster | -| [security\_group\_id](#output\_security\_group\_id) | Security Group ID to control access to the OpenSearch domain | +| [opensearch\_domain\_arn](#output\_opensearch\_domain\_arn) | The ARN of the OpenSearch domain. | +| [opensearch\_domain\_endpoint](#output\_opensearch\_domain\_endpoint) | The endpoint of the OpenSearch domain. | +| [opensearch\_domain\_id](#output\_opensearch\_domain\_id) | The unique identifier for the OpenSearch domain. | +| [opensearch\_serverless\_collection\_arn](#output\_opensearch\_serverless\_collection\_arn) | The ARN of the OpenSearch Serverless collection | +| [opensearch\_serverless\_collection\_id](#output\_opensearch\_serverless\_collection\_id) | The ID of the OpenSearch Serverless collection | ## Versioning