├── .gitignore ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples ├── advanced_security_options_master_user_arn │ ├── README.md │ ├── datasources.tf │ ├── main.tf │ ├── provider.tf │ ├── terraform.tfvars │ ├── variables.tf │ ├── versions.tf │ └── whitelits.tpl ├── advanced_security_options_master_user_name_pasword │ ├── README.md │ ├── datasources.tf │ ├── main.tf │ ├── provider.tf │ ├── terraform.tfstate │ ├── terraform.tfstate.backup │ ├── terraform.tfvars │ ├── variables.tf │ ├── versions.tf │ └── whitelits.tpl ├── public │ ├── README.md │ ├── datasources.tf │ ├── main.tf │ ├── provider.tf │ ├── terraform.tfvars │ ├── variables.tf │ ├── versions.tf │ └── whitelits.tpl ├── public_cold_storage │ ├── .terraform.lock.hcl │ ├── README.md │ ├── datasources.tf │ ├── main.tf │ ├── provider.tf │ ├── terraform.tfvars │ ├── variables.tf │ ├── versions.tf │ └── whitelits.tpl └── vpc │ ├── README.md │ ├── access_policies.tpl │ ├── datasources.tf │ ├── main.tf │ ├── provider.tf │ ├── terraform.tfvars │ ├── variable.tf │ └── versions.tf ├── iam.tf ├── kms.tf ├── main.tf ├── outputs.tf ├── variables.tf └── versions.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | # example.tfvars 16 | 17 | # Ignore override files as they are usually used to override resources locally and so 18 | # are not checked in 19 | override.tf 20 | override.tf.json 21 | *_override.tf 22 | *_override.tf.json 23 | 24 | # Include override files you do wish to add to version control using negated pattern 25 | # 26 | # !example_override.tf 27 | 28 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 29 | # example: *tfplan* 30 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v3.2.0 6 | hooks: 7 | - id: trailing-whitespace 8 | - id: end-of-file-fixer 9 | - id: check-added-large-files 10 | - id: detect-aws-credentials 11 | - repo: https://github.com/antonbabenko/pre-commit-terraform 12 | rev: v1.49.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases 13 | hooks: 14 | - id: terraform_fmt 15 | - id: terraform_validate 16 | - id: terraform_docs 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.14.1 (June 14, 2022) 2 | 3 | FIXES: 4 | 5 | * Add variables and parameters for `cold_storage` configuration (thanks @AlKapkone) 6 | 7 | ## 0.14.0 (June 10, 2022) 8 | 9 | ENHANCEMENTS: 10 | 11 | * Add support and example for `cold_storage_options` 12 | 13 | ## 0.13.0 (March 22, 2022) 14 | 15 | ENHANCEMENTS: 16 | 17 | * Add Ability to have random master password (thanks @serge-r) 18 | * Update pre-commit protocol repo to use https:// instead of git:// 19 | 20 | 21 | ## 0.12.2 (August 26, 2021) 22 | 23 | FIXES: 24 | 25 | * Fix "for_each" depends on resource attributes that cannot be determined until apply (thanks @venky999) 26 | 27 | ## 0.12.1 (August 26, 2021) 28 | 29 | FIXES: 30 | 31 | * Fix typo in examples 32 | 33 | ## 0.12.0 (August 26, 2021) 34 | 35 | ENHANCEMENTS: 36 | 37 | * Add multiple log types support 38 | 39 | ## 0.11.0 (June 8, 2021) 40 | 41 | ENHANCEMENTS: 42 | 43 | * Add support disabling CloudWatch Logs resources (thanks @AlexanderIakovlev) 44 | 45 | ## 0.10.0 (April 30, 2021) 46 | 47 | ENHANCEMENTS: 48 | 49 | * Update config variables to support objects instead of maps values 50 | * Update README & examples 51 | 52 | FIXES: 53 | 54 | * Remove `availability_zone_count` constraint 55 | 56 | ## 0.9.1 (April 22, 2021) 57 | 58 | ENHANCEMENTS: 59 | 60 | * Add pre-commit config file 61 | * Add .gitignore file 62 | * Update README 63 | 64 | FIXES: 65 | 66 | * Add AWS provider requirement (>= 3.35.0) 67 | 68 | ## 0.9.0 (April 12, 2021) 69 | 70 | ENHANCEMENTS: 71 | 72 | * Add `custom_endpoint` support 73 | * Update examples 74 | 75 | ## 0.8.0 (January 24, 2021) 76 | 77 | 78 | ENHANCEMENTS: 79 | 80 | * Add support for conditional creation 81 | 82 | FIXES: 83 | 84 | * Update examples 85 | 86 | ## 0.7.1 (January 24, 2021) 87 | 88 | FIXES: 89 | 90 | * Fix `master_user_name` reference in locals (thanks @rafaelmariotti) 91 | 92 | ## 0.7.0 (January 8, 2021) 93 | 94 | ENHANCEMENTS: 95 | 96 | * Add retention configuration variable for Cloudwatch log group (thanks @elpaquete) 97 | 98 | ## 0.6.1 (October 28, 2020) 99 | 100 | FIXES: 101 | 102 | * Change default values for warm storage 103 | 104 | ## 0.6.0 (October 26, 2020) 105 | 106 | ENHANCEMENTS: 107 | 108 | * Add support for warm storage (thanks @jlfowle and @neilsmith1000) 109 | 110 | ## 0.5.1 (September 17, 2020) 111 | 112 | FIXES: 113 | 114 | * Fix `advanced_security_options` example. In order to use `master_user_arn`, the value for `internal_user_database_enabled` must be set to `false`. 115 | 116 | ## 0.5.0 (September 3, 2020) 117 | 118 | ENHANCEMENTS: 119 | 120 | * Add `domain_endpoint_options` support 121 | * Update advaced security options examples 122 | * Move advaced security options examples to its own folders 123 | * Add READMEs to each example folder 124 | 125 | ## 0.4.1 (August 24, 2020) 126 | 127 | FIXES: 128 | 129 | * Bug/fix variable lookups for `master_user_password` and `dedicated_master_type` (thanks @mcook-bison) 130 | 131 | ## 0.4.0 (July 15, 2020) 132 | 133 | ENHANCEMENTS: 134 | 135 | * Add `advanced_security_options` block 136 | * Add examples for `advanced_security_options` block 137 | 138 | FIXES: 139 | 140 | * Change "false" for the bool value 141 | 142 | ## 0.3.0 (June 26, 2020) 143 | 144 | FIXES: 145 | 146 | * Add Service Link role creation flag (default to `true`) 147 | 148 | 149 | ## 0.2.1 (May 2, 2020) 150 | 151 | UPDATE: 152 | 153 | * Update README 154 | 155 | ## 0.2.0 (May 2, 2020) 156 | 157 | ENHANCEMENTS: 158 | 159 | * Add support for customizable update timeout 160 | 161 | UPDATES: 162 | 163 | * Update public and vpc examples 164 | 165 | 166 | ## 0.1.2 (April 1, 2020) 167 | 168 | UPDATES: 169 | 170 | * Add Terraform logo in README 171 | 172 | ## 0.1.1 (November 21, 2019) 173 | 174 | IMPROVEMENTS: 175 | 176 | * Fix deprecation warning for Terraform >= 0.12.14 177 | 178 | ## 0.1.0 (October 28, 2019) 179 | 180 | FEATURES: 181 | 182 | * Module implementation 183 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Terraform](https://lgallardo.com/images/terraform.jpg) 2 | # terraform-aws-elasticsearch 3 | 4 | Terraform module to create [Amazon Elasticsearch Service](https://aws.amazon.com/elasticsearch-service/) clusters, following the Well-Architected Framework and best AWS practices. 5 | 6 | Amazon Elasticsearch Service is a fully managed service that makes it easy to deploy, operate, and scale Elasticsearch clusters in the AWS Cloud. Elasticsearch is a popular open-source search and analytics engine for use cases such as log analytics, real-time application monitoring, and clickstream analysis. With Amazon ES, you get direct access to the Elasticsearch APIs; existing code and applications work seamlessly with the service. 7 | 8 | ## Examples 9 | 10 | Check the [examples](/examples/) folder where you can see how to configure a public ES cluster, and another example showing how to set it with VPC options. 11 | 12 | ## Usage 13 | 14 | You can use this module to create your Amazon ES cluster by defining each parameters blocks as follows: 15 | 16 | ``` 17 | module "aws_es" { 18 | 19 | source = "lgallard/elasticsearch/aws" 20 | 21 | domain_name = "elasticsearch_public" 22 | elasticsearch_version = "7.1" 23 | 24 | cluster_config = { 25 | dedicated_master_enabled = true 26 | instance_count = 3 27 | instance_type = "r5.large.elasticsearch" 28 | zone_awareness_enabled = true 29 | availability_zone_count = 3 30 | } 31 | 32 | ebs_options = { 33 | ebs_enabled = "true" 34 | volume_size = "25" 35 | } 36 | 37 | encrypt_at_rest = { 38 | enabled = true 39 | kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 40 | } 41 | 42 | log_publishing_options = { 43 | index_slow_logs = { 44 | enabled = true 45 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/index_slow_logs:*" 46 | log_publishing_options_retention = 90 47 | } 48 | search_slow_logs = { 49 | enabled = true 50 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/search_slow_logs:*" 51 | } 52 | es_application_logs = { 53 | enabled = true 54 | cloudwatch_log_group_name = "es_application_logs_dev" 55 | } 56 | audit_logs = { 57 | enabled = false 58 | cloudwatch_log_group_name = "audit_logs_dev" 59 | } 60 | } 61 | 62 | advanced_options = { 63 | "rest.action.multi.allow_explicit_index" = true 64 | } 65 | 66 | domain_endpoint_options = { 67 | enforce_https = true 68 | custom_endpoint_enabled = true 69 | custom_endpoint = "lgallardo.com" 70 | custom_endpoint_certificate_arn = "arn:aws:acm:us-east-1:123456789101:certificate/abcd1234-ef11-abcd-1234-abcd1234efef" 71 | } 72 | 73 | node_to_node_encryption_enabled = true 74 | snapshot_options_automated_snapshot_start_hour = 23 75 | 76 | tags = { 77 | Owner = "sysops" 78 | env = "dev" 79 | } 80 | 81 | ``` 82 | 83 | **Note:** You can also define the above ElasticSearch cluster using just the module variables. Instead of defining a `cluster_config` block (list of map), you can set each of the `cluster_config_*` variables, as shown below: 84 | 85 | ``` 86 | module "aws_es" { 87 | 88 | source = "lgallard/elasticsearch/aws" 89 | 90 | domain_name = "elasticsearch_public" 91 | elasticsearch_version = "7.1" 92 | 93 | cluster_config_dedicated_master_enabled = true 94 | cluster_config_instance_count = 3 95 | cluster_config_instance_type = "r5.large.elasticsearch" 96 | cluster_config_zone_awareness_enabled = "true" 97 | cluster_config_availability_zone_count = 3 98 | 99 | ebs_options_ebs_enabled = true 100 | ebs_options_volume_size = 25 101 | 102 | encrypt_at_rest_enabled = true 103 | encrypt_at_rest_kms_key_id = "alias/aws/es" 104 | 105 | log_publishing_options_enabled = true 106 | log_publishing_options_log_type = "INDEX_SLOW_LOGS" 107 | 108 | advanced_options = { 109 | "rest.action.multi.allow_explicit_index" = true 110 | } 111 | 112 | node_to_node_encryption_enabled = true 113 | snapshot_options_automated_snapshot_start_hour = 23 114 | 115 | tags = { 116 | Owner = "sysops" 117 | env = "dev" 118 | } 119 | 120 | ``` 121 | 122 | ## Requirements 123 | 124 | | Name | Version | 125 | |------|---------| 126 | | [terraform](#requirement\_terraform) | >= 0.12.9 | 127 | | [aws](#requirement\_aws) | >= 3.35.0 | 128 | | [random](#requirement\_random) | >=3.1.2 | 129 | 130 | ## Providers 131 | 132 | | Name | Version | 133 | |------|---------| 134 | | [aws](#provider\_aws) | 4.18.0 | 135 | | [random](#provider\_random) | 3.3.1 | 136 | 137 | ## Modules 138 | 139 | No modules. 140 | 141 | ## Resources 142 | 143 | | Name | Type | 144 | |------|------| 145 | | [aws_cloudwatch_log_group.es_cloudwatch_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | 146 | | [aws_cloudwatch_log_resource_policy.es_aws_cloudwatch_log_resource_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_resource_policy) | resource | 147 | | [aws_elasticsearch_domain.es_domain](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticsearch_domain) | resource | 148 | | [aws_iam_service_linked_role.es](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_service_linked_role) | resource | 149 | | [random_password.master_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource | 150 | | [aws_kms_key.aws_es](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/kms_key) | data source | 151 | 152 | ## Inputs 153 | 154 | | Name | Description | Type | Default | Required | 155 | |------|-------------|------|---------|:--------:| 156 | | [access\_policies](#input\_access\_policies) | IAM policy document specifying the access policies for the domain | `string` | `""` | no | 157 | | [advanced\_options](#input\_advanced\_options) | Key-value string pairs to specify advanced configuration options. Note that the values for these configuration options must be strings (wrapped in quotes) or they may be wrong and cause a perpetual diff, causing Terraform to want to recreate your Elasticsearch domain on every apply | `map(string)` | `{}` | no | 158 | | [advanced\_security\_options](#input\_advanced\_security\_options) | Options for fine-grained access control | `any` | `{}` | no | 159 | | [advanced\_security\_options\_create\_random\_master\_password](#input\_advanced\_security\_options\_create\_random\_master\_password) | Whether to create random master password for Elasticsearch master user | `bool` | `false` | no | 160 | | [advanced\_security\_options\_enabled](#input\_advanced\_security\_options\_enabled) | Whether advanced security is enabled (Forces new resource) | `bool` | `false` | no | 161 | | [advanced\_security\_options\_internal\_user\_database\_enabled](#input\_advanced\_security\_options\_internal\_user\_database\_enabled) | Whether the internal user database is enabled. If not set, defaults to false by the AWS API. | `bool` | `false` | no | 162 | | [advanced\_security\_options\_master\_user\_arn](#input\_advanced\_security\_options\_master\_user\_arn) | ARN for the master user. Only specify if `internal_user_database_enabled` is not set or set to `false`) | `string` | `null` | no | 163 | | [advanced\_security\_options\_master\_user\_password](#input\_advanced\_security\_options\_master\_user\_password) | The master user's password, which is stored in the Amazon Elasticsearch Service domain's internal database. Only specify if `internal_user_database_enabled` is set to `true`. | `string` | `null` | no | 164 | | [advanced\_security\_options\_master\_user\_username](#input\_advanced\_security\_options\_master\_user\_username) | The master user's username, which is stored in the Amazon Elasticsearch Service domain's internal database. Only specify if `internal_user_database_enabled` is set to `true`. | `string` | `null` | no | 165 | | [advanced\_security\_options\_random\_master\_password\_length](#input\_advanced\_security\_options\_random\_master\_password\_length) | Length of random master password to create | `number` | `16` | no | 166 | | [cloudwatch\_log\_enabled](#input\_cloudwatch\_log\_enabled) | Change to false to avoid deploying any Cloudwatch Logs resources | `bool` | `true` | no | 167 | | [cluster\_config](#input\_cluster\_config) | Cluster configuration of the domain | `any` | `{}` | no | 168 | | [cluster\_config\_availability\_zone\_count](#input\_cluster\_config\_availability\_zone\_count) | Number of Availability Zones for the domain to use with | `number` | `3` | no | 169 | | [cluster\_config\_cold\_storage\_options\_enabled](#input\_cluster\_config\_cold\_storage\_options\_enabled) | Indicates whether to enable cold storage for an Elasticsearch domain | `bool` | `false` | no | 170 | | [cluster\_config\_dedicated\_master\_count](#input\_cluster\_config\_dedicated\_master\_count) | Number of dedicated master nodes in the cluster | `number` | `3` | no | 171 | | [cluster\_config\_dedicated\_master\_enabled](#input\_cluster\_config\_dedicated\_master\_enabled) | Indicates whether dedicated master nodes are enabled for the cluster | `bool` | `true` | no | 172 | | [cluster\_config\_dedicated\_master\_type](#input\_cluster\_config\_dedicated\_master\_type) | Instance type of the dedicated master nodes in the cluster | `string` | `"r5.large.elasticsearch"` | no | 173 | | [cluster\_config\_instance\_count](#input\_cluster\_config\_instance\_count) | Number of instances in the cluster | `number` | `3` | no | 174 | | [cluster\_config\_instance\_type](#input\_cluster\_config\_instance\_type) | Instance type of data nodes in the cluster | `string` | `"r5.large.elasticsearch"` | no | 175 | | [cluster\_config\_warm\_count](#input\_cluster\_config\_warm\_count) | The number of warm nodes in the cluster | `number` | `null` | no | 176 | | [cluster\_config\_warm\_enabled](#input\_cluster\_config\_warm\_enabled) | Indicates whether to enable warm storage | `bool` | `false` | no | 177 | | [cluster\_config\_warm\_type](#input\_cluster\_config\_warm\_type) | The instance type for the Elasticsearch cluster's warm nodes | `string` | `null` | no | 178 | | [cluster\_config\_zone\_awareness\_enabled](#input\_cluster\_config\_zone\_awareness\_enabled) | Indicates whether zone awareness is enabled. To enable awareness with three Availability Zones | `bool` | `false` | no | 179 | | [cognito\_options](#input\_cognito\_options) | Options for Amazon Cognito Authentication for Kibana | `any` | `{}` | no | 180 | | [cognito\_options\_enabled](#input\_cognito\_options\_enabled) | Specifies whether Amazon Cognito authentication with Kibana is enabled or not | `bool` | `false` | no | 181 | | [cognito\_options\_identity\_pool\_id](#input\_cognito\_options\_identity\_pool\_id) | ID of the Cognito Identity Pool to use | `string` | `""` | no | 182 | | [cognito\_options\_role\_arn](#input\_cognito\_options\_role\_arn) | ARN of the IAM role that has the AmazonESCognitoAccess policy attached | `string` | `""` | no | 183 | | [cognito\_options\_user\_pool\_id](#input\_cognito\_options\_user\_pool\_id) | ID of the Cognito User Pool to use | `string` | `""` | no | 184 | | [create\_service\_link\_role](#input\_create\_service\_link\_role) | Create service link role for AWS Elasticsearch Service | `bool` | `true` | no | 185 | | [domain\_endpoint\_options](#input\_domain\_endpoint\_options) | Domain endpoint HTTP(S) related options. | `any` | `{}` | no | 186 | | [domain\_endpoint\_options\_custom\_endpoint](#input\_domain\_endpoint\_options\_custom\_endpoint) | Fully qualified domain for your custom endpoint | `string` | `null` | no | 187 | | [domain\_endpoint\_options\_custom\_endpoint\_certificate\_arn](#input\_domain\_endpoint\_options\_custom\_endpoint\_certificate\_arn) | ACM certificate ARN for your custom endpoint | `string` | `null` | no | 188 | | [domain\_endpoint\_options\_custom\_endpoint\_enabled](#input\_domain\_endpoint\_options\_custom\_endpoint\_enabled) | Whether to enable custom endpoint for the Elasticsearch domain | `bool` | `false` | no | 189 | | [domain\_endpoint\_options\_enforce\_https](#input\_domain\_endpoint\_options\_enforce\_https) | Whether or not to require HTTPS | `bool` | `false` | no | 190 | | [domain\_endpoint\_options\_tls\_security\_policy](#input\_domain\_endpoint\_options\_tls\_security\_policy) | The name of the TLS security policy that needs to be applied to the HTTPS endpoint. Valid values: `Policy-Min-TLS-1-0-2019-07` and `Policy-Min-TLS-1-2-2019-07` | `string` | `"Policy-Min-TLS-1-2-2019-07"` | no | 191 | | [domain\_name](#input\_domain\_name) | Name of the domain | `string` | n/a | yes | 192 | | [ebs\_enabled](#input\_ebs\_enabled) | Whether EBS volumes are attached to data nodes in the domain | `bool` | `true` | no | 193 | | [ebs\_options](#input\_ebs\_options) | EBS related options, may be required based on chosen instance size | `any` | `{}` | no | 194 | | [ebs\_options\_iops](#input\_ebs\_options\_iops) | The baseline input/output (I/O) performance of EBS volumes attached to data nodes. Applicable only for the Provisioned IOPS EBS volume type | `number` | `0` | no | 195 | | [ebs\_options\_volume\_size](#input\_ebs\_options\_volume\_size) | The size of EBS volumes attached to data nodes (in GB). Required if ebs\_enabled is set to true | `number` | `10` | no | 196 | | [ebs\_options\_volume\_type](#input\_ebs\_options\_volume\_type) | The type of EBS volumes attached to data nodes | `string` | `"gp2"` | no | 197 | | [elasticsearch\_version](#input\_elasticsearch\_version) | The version of Elasticsearch to deploy. | `string` | `"7.1"` | no | 198 | | [enabled](#input\_enabled) | Change to false to avoid deploying any AWS ElasticSearch resources | `bool` | `true` | no | 199 | | [encrypt\_at\_rest](#input\_encrypt\_at\_rest) | Encrypt at rest options. Only available for certain instance types | `any` | `{}` | no | 200 | | [encrypt\_at\_rest\_enabled](#input\_encrypt\_at\_rest\_enabled) | Whether to enable encryption at rest | `bool` | `true` | no | 201 | | [encrypt\_at\_rest\_kms\_key\_id](#input\_encrypt\_at\_rest\_kms\_key\_id) | The KMS key id to encrypt the Elasticsearch domain with. If not specified then it defaults to using the aws/es service KMS key | `string` | `"alias/aws/es"` | no | 202 | | [log\_publishing\_options](#input\_log\_publishing\_options) | Options for publishing slow logs to CloudWatch Logs | `any` | `{}` | no | 203 | | [log\_publishing\_options\_retention](#input\_log\_publishing\_options\_retention) | Retention in days for the created Cloudwatch log group | `number` | `90` | no | 204 | | [node\_to\_node\_encryption](#input\_node\_to\_node\_encryption) | Node-to-node encryption options | `any` | `{}` | no | 205 | | [node\_to\_node\_encryption\_enabled](#input\_node\_to\_node\_encryption\_enabled) | Whether to enable node-to-node encryption | `bool` | `true` | no | 206 | | [snapshot\_options](#input\_snapshot\_options) | Snapshot related options | `any` | `{}` | no | 207 | | [snapshot\_options\_automated\_snapshot\_start\_hour](#input\_snapshot\_options\_automated\_snapshot\_start\_hour) | Hour during which the service takes an automated daily snapshot of the indices in the domain | `number` | `0` | no | 208 | | [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(any)` | `{}` | no | 209 | | [timeouts](#input\_timeouts) | Timeouts map. | `map(any)` | `{}` | no | 210 | | [timeouts\_update](#input\_timeouts\_update) | How long to wait for updates. | `string` | `null` | no | 211 | | [vpc\_options](#input\_vpc\_options) | VPC related options, see below. Adding or removing this configuration forces a new resource | `any` | `{}` | no | 212 | | [vpc\_options\_security\_group\_ids](#input\_vpc\_options\_security\_group\_ids) | List of VPC Security Group IDs to be applied to the Elasticsearch domain endpoints. If omitted, the default Security Group for the VPC will be used | `list(any)` | `[]` | no | 213 | | [vpc\_options\_subnet\_ids](#input\_vpc\_options\_subnet\_ids) | List of VPC Subnet IDs for the Elasticsearch domain endpoints to be created in | `list(any)` | `[]` | no | 214 | 215 | ## Outputs 216 | 217 | | Name | Description | 218 | |------|-------------| 219 | | [arn](#output\_arn) | Amazon Resource Name (ARN) of the domain | 220 | | [domain\_id](#output\_domain\_id) | Unique identifier for the domain | 221 | | [endpoint](#output\_endpoint) | Domain-specific endpoint used to submit index, search, and data upload requests | 222 | | [kibana\_endpoint](#output\_kibana\_endpoint) | Domain-specific endpoint for kibana without https scheme | 223 | | [master\_password](#output\_master\_password) | Master password | 224 | | [master\_username](#output\_master\_username) | Master username | 225 | | [vpc\_options\_availability\_zones](#output\_vpc\_options\_availability\_zones) | If the domain was created inside a VPC, the names of the availability zones the configured subnet\_ids were created inside | 226 | | [vpc\_options\_vpc\_id](#output\_vpc\_options\_vpc\_id) | If the domain was created inside a VPC, the ID of the VPC | 227 | 228 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/README.md: -------------------------------------------------------------------------------- 1 | # AWS Elasticsearch domain with Advanced Security Options using master user ARN example 2 | 3 | ``` 4 | module "aws_es" { 5 | 6 | source = "lgallard/elasticsearch/aws" 7 | 8 | domain_name = var.es_domain_name 9 | elasticsearch_version = var.es_version 10 | 11 | cluster_config = { 12 | dedicated_master_enabled = "true" 13 | instance_count = "3" 14 | instance_type = "r5.large.elasticsearch" 15 | zone_awareness_enabled = "true" 16 | availability_zone_count = "3" 17 | } 18 | 19 | advanced_security_options = { 20 | enabled = true 21 | master_user_options = { 22 | master_user_arn = "arn:aws:iam::123456789101:user/lgallard" 23 | } 24 | } 25 | 26 | domain_endpoint_options = { 27 | enforce_https = true 28 | custom_endpoint_enabled = true 29 | custom_endpoint = "lgallardo.com" 30 | custom_endpoint_certificate_arn = "arn:aws:acm:us-east-1:123456789101:certificate/abcd1234-ef11-abcd-1234-abcd1234efef" 31 | } 32 | 33 | ebs_options = { 34 | ebs_enabled = "true" 35 | volume_size = "25" 36 | } 37 | 38 | encrypt_at_rest = { 39 | enabled = "true" 40 | kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 41 | } 42 | 43 | 44 | log_publishing_options = { 45 | enabled = "true" 46 | } 47 | 48 | advanced_options = { 49 | "rest.action.multi.allow_explicit_index" = "true" 50 | } 51 | 52 | access_policies = templatefile("${path.module}/whitelits.tpl", { 53 | region = data.aws_region.current.name, 54 | account = data.aws_caller_identity.current.account_id, 55 | domain_name = var.es_domain_name, 56 | whitelist = jsonencode(var.whitelist) 57 | }) 58 | 59 | node_to_node_encryption_enabled = "true" 60 | snapshot_options_automated_snapshot_start_hour = "23" 61 | 62 | #timeouts_update = "90m" 63 | 64 | tags = { 65 | Owner = "sysops" 66 | env = "dev" 67 | } 68 | } 69 | ``` 70 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/datasources.tf: -------------------------------------------------------------------------------- 1 | # Use this data source to get the access to the effective Account ID in which 2 | # Terraform is working. 3 | data "aws_caller_identity" "current" {} 4 | 5 | # To obtain the name of the AWS region configured on the provider 6 | data "aws_region" "current" {} 7 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/main.tf: -------------------------------------------------------------------------------- 1 | module "aws_es" { 2 | 3 | source = "lgallard/elasticsearch/aws" 4 | 5 | domain_name = var.es_domain_name 6 | elasticsearch_version = var.es_version 7 | 8 | cluster_config = { 9 | dedicated_master_enabled = true 10 | instance_count = 3 11 | instance_type = "r5.large.elasticsearch" 12 | zone_awareness_enabled = true 13 | availability_zone_count = 3 14 | } 15 | 16 | advanced_security_options = { 17 | enabled = true 18 | master_user_options = { 19 | master_user_arn = "arn:aws:iam::123456789101:user/lgallard" 20 | } 21 | } 22 | 23 | domain_endpoint_options = { 24 | enforce_https = true 25 | custom_endpoint_enabled = true 26 | custom_endpoint = "lgallardo.com" 27 | custom_endpoint_certificate_arn = "arn:aws:acm:us-east-1:123456789101:certificate/abcd1234-ef11-abcd-1234-abcd1234efef" 28 | } 29 | 30 | ebs_options = { 31 | ebs_enabled = true 32 | volume_size = 25 33 | } 34 | 35 | encrypt_at_rest = { 36 | enabled = true 37 | kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 38 | } 39 | 40 | log_publishing_options = { 41 | enabled = true 42 | } 43 | 44 | advanced_options = { 45 | "rest.action.multi.allow_explicit_index" = true 46 | } 47 | 48 | access_policies = templatefile("${path.module}/whitelits.tpl", { 49 | region = data.aws_region.current.name, 50 | account = data.aws_caller_identity.current.account_id, 51 | domain_name = var.es_domain_name, 52 | whitelist = jsonencode(var.whitelist) 53 | }) 54 | 55 | node_to_node_encryption_enabled = true 56 | snapshot_options_automated_snapshot_start_hour = 23 57 | 58 | #timeouts_update = "90m" 59 | 60 | tags = { 61 | Owner = "sysops" 62 | env = "dev" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.region 3 | profile = var.profile 4 | } 5 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/terraform.tfvars: -------------------------------------------------------------------------------- 1 | region = "us-east-1" 2 | profile = "default" 3 | es_domain_name = "elasticsearch-public" 4 | es_version = "7.1" 5 | whitelist = ["1.1.1.1", "2.2.2.2"] 6 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/variables.tf: -------------------------------------------------------------------------------- 1 | # Provider 2 | variable "region" {} 3 | variable "profile" {} 4 | 5 | 6 | # AWS Elasticsearch 7 | variable "es_domain_name" {} 8 | variable "es_version" {} 9 | 10 | 11 | # Whitelist (allow public IPs) 12 | variable "whitelist" { 13 | default = [] 14 | } 15 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | required_providers { 5 | aws = ">= 3.35.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_arn/whitelits.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "", 6 | "Effect": "Allow", 7 | "Principal": { 8 | "AWS": "*" 9 | }, 10 | "Action": "es:*", 11 | "Resource": "arn:aws:es:${region}:${account}:domain/${domain_name}/*", 12 | "Condition": { 13 | "IpAddress": { 14 | "aws:SourceIp": ${whitelist} 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/README.md: -------------------------------------------------------------------------------- 1 | # AWS Elasticsearch domain with Advanced Security Options using name and password example 2 | 3 | ``` 4 | module "aws_es" { 5 | 6 | source = "lgallard/elasticsearch/aws" 7 | 8 | domain_name = var.es_domain_name 9 | elasticsearch_version = var.es_version 10 | 11 | cluster_config = { 12 | dedicated_master_enabled = "true" 13 | instance_count = "3" 14 | instance_type = "r5.large.elasticsearch" 15 | zone_awareness_enabled = "true" 16 | availability_zone_count = "3" 17 | } 18 | 19 | advanced_security_options = { 20 | enabled = true 21 | internal_user_database_enabled = true 22 | master_user_options = { 23 | master_user_name = "username" 24 | master_user_password = "T0p$ecret" 25 | } 26 | } 27 | 28 | domain_endpoint_options = { 29 | enforce_https = true 30 | custom_endpoint_enabled = true 31 | custom_endpoint = "lgallardo.com" 32 | custom_endpoint_certificate_arn = "arn:aws:acm:us-east-1:123456789101:certificate/abcd1234-ef11-abcd-1234-abcd1234efef" 33 | } 34 | 35 | ebs_options = { 36 | ebs_enabled = "true" 37 | volume_size = "25" 38 | } 39 | 40 | encrypt_at_rest = { 41 | enabled = "true" 42 | kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 43 | } 44 | 45 | 46 | log_publishing_options = { 47 | enabled = "true" 48 | } 49 | 50 | advanced_options = { 51 | "rest.action.multi.allow_explicit_index" = "true" 52 | } 53 | 54 | access_policies = templatefile("${path.module}/whitelits.tpl", { 55 | region = data.aws_region.current.name, 56 | account = data.aws_caller_identity.current.account_id, 57 | domain_name = var.es_domain_name, 58 | whitelist = jsonencode(var.whitelist) 59 | }) 60 | 61 | node_to_node_encryption_enabled = "true" 62 | snapshot_options_automated_snapshot_start_hour = "23" 63 | 64 | #timeouts_update = "90m" 65 | 66 | tags = { 67 | Owner = "sysops" 68 | env = "dev" 69 | } 70 | } 71 | ``` 72 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/datasources.tf: -------------------------------------------------------------------------------- 1 | # Use this data source to get the access to the effective Account ID in which 2 | # Terraform is working. 3 | data "aws_caller_identity" "current" {} 4 | 5 | # To obtain the name of the AWS region configured on the provider 6 | data "aws_region" "current" {} 7 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/main.tf: -------------------------------------------------------------------------------- 1 | module "aws_es" { 2 | 3 | source = "lgallard/elasticsearch/aws" 4 | 5 | domain_name = var.es_domain_name 6 | elasticsearch_version = var.es_version 7 | 8 | cluster_config = { 9 | dedicated_master_enabled = true 10 | instance_count = 3 11 | instance_type = "r5.large.elasticsearch" 12 | zone_awareness_enabled = true 13 | availability_zone_count = 3 14 | } 15 | 16 | advanced_security_options = { 17 | enabled = true 18 | internal_user_database_enabled = true 19 | master_user_options = { 20 | master_user_name = "username" 21 | master_user_password = "T0p$ecret" 22 | } 23 | } 24 | 25 | domain_endpoint_options = { 26 | enforce_https = true 27 | custom_endpoint_enabled = true 28 | custom_endpoint = "lgallardo.com" 29 | custom_endpoint_certificate_arn = "arn:aws:acm:us-east-1:123456789101:certificate/abcd1234-ef11-abcd-1234-abcd1234efef" 30 | } 31 | 32 | ebs_options = { 33 | ebs_enabled = true 34 | volume_size = 25 35 | } 36 | 37 | encrypt_at_rest = { 38 | enabled = true 39 | kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 40 | } 41 | 42 | log_publishing_options = { 43 | enabled = true 44 | } 45 | 46 | advanced_options = { 47 | "rest.action.multi.allow_explicit_index" = true 48 | } 49 | 50 | access_policies = templatefile("${path.module}/whitelits.tpl", { 51 | region = data.aws_region.current.name, 52 | account = data.aws_caller_identity.current.account_id, 53 | domain_name = var.es_domain_name, 54 | whitelist = jsonencode(var.whitelist) 55 | }) 56 | 57 | node_to_node_encryption_enabled = true 58 | snapshot_options_automated_snapshot_start_hour = 23 59 | 60 | #timeouts_update = "90m" 61 | 62 | tags = { 63 | Owner = "sysops" 64 | env = "dev" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.region 3 | profile = var.profile 4 | } 5 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "terraform_version": "0.13.0", 4 | "serial": 16, 5 | "lineage": "cb22e4fa-cf57-f965-8222-a2633267fa49", 6 | "outputs": {}, 7 | "resources": [] 8 | } 9 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/terraform.tfstate.backup: -------------------------------------------------------------------------------- 1 | { 2 | "version": 4, 3 | "terraform_version": "0.13.0", 4 | "serial": 8, 5 | "lineage": "cb22e4fa-cf57-f965-8222-a2633267fa49", 6 | "outputs": {}, 7 | "resources": [ 8 | { 9 | "mode": "data", 10 | "type": "aws_caller_identity", 11 | "name": "current", 12 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 13 | "instances": [ 14 | { 15 | "schema_version": 0, 16 | "attributes": { 17 | "account_id": "758889637411", 18 | "arn": "arn:aws:iam::758889637411:user/lgallard", 19 | "id": "2020-09-03 23:31:19.06449963 +0000 UTC", 20 | "user_id": "AIDAICCKBWMAPSDFUM4BG" 21 | } 22 | } 23 | ] 24 | }, 25 | { 26 | "module": "module.aws_es", 27 | "mode": "data", 28 | "type": "aws_kms_key", 29 | "name": "aws_es", 30 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 31 | "instances": [ 32 | { 33 | "schema_version": 0, 34 | "attributes": { 35 | "arn": "arn:aws:kms:us-east-1:758889637411:key/ccab903a-4ba1-4993-9fc7-f7e538b25bd3", 36 | "aws_account_id": "758889637411", 37 | "creation_date": "2019-10-24T16:54:43Z", 38 | "customer_master_key_spec": "SYMMETRIC_DEFAULT", 39 | "deletion_date": null, 40 | "description": "Default master key that protects my Elasticsearch data when no other key is defined", 41 | "enabled": true, 42 | "expiration_model": "", 43 | "grant_tokens": null, 44 | "id": "ccab903a-4ba1-4993-9fc7-f7e538b25bd3", 45 | "key_id": "alias/aws/es", 46 | "key_manager": "AWS", 47 | "key_state": "Enabled", 48 | "key_usage": "ENCRYPT_DECRYPT", 49 | "origin": "AWS_KMS", 50 | "valid_to": null 51 | } 52 | } 53 | ] 54 | }, 55 | { 56 | "mode": "data", 57 | "type": "aws_region", 58 | "name": "current", 59 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 60 | "instances": [ 61 | { 62 | "schema_version": 0, 63 | "attributes": { 64 | "description": "US East (N. Virginia)", 65 | "endpoint": "ec2.us-east-1.amazonaws.com", 66 | "id": "us-east-1", 67 | "name": "us-east-1" 68 | } 69 | } 70 | ] 71 | }, 72 | { 73 | "module": "module.aws_es", 74 | "mode": "managed", 75 | "type": "aws_cloudwatch_log_group", 76 | "name": "es_cloudwatch_log_group", 77 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 78 | "instances": [ 79 | { 80 | "schema_version": 0, 81 | "attributes": { 82 | "arn": "arn:aws:logs:us-east-1:758889637411:log-group:elasticsearch-public-log_group", 83 | "id": "elasticsearch-public-log_group", 84 | "kms_key_id": "", 85 | "name": "elasticsearch-public-log_group", 86 | "name_prefix": null, 87 | "retention_in_days": 0, 88 | "tags": { 89 | "Owner": "sysops", 90 | "env": "dev" 91 | } 92 | }, 93 | "private": "bnVsbA==" 94 | } 95 | ] 96 | }, 97 | { 98 | "module": "module.aws_es", 99 | "mode": "managed", 100 | "type": "aws_cloudwatch_log_resource_policy", 101 | "name": "es_aws_cloudwatch_log_resource_policy", 102 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 103 | "instances": [ 104 | { 105 | "schema_version": 0, 106 | "attributes": { 107 | "id": "elasticsearch-public-policy", 108 | "policy_document": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"es.amazonaws.com\"},\"Action\":[\"logs:PutLogEvents\",\"logs:PutLogEventsBatch\",\"logs:CreateLogStream\"],\"Resource\":\"arn:aws:logs:*\"}]}", 109 | "policy_name": "elasticsearch-public-policy" 110 | }, 111 | "private": "bnVsbA==" 112 | } 113 | ] 114 | }, 115 | { 116 | "module": "module.aws_es", 117 | "mode": "managed", 118 | "type": "aws_elasticsearch_domain", 119 | "name": "es_domain", 120 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 121 | "instances": [ 122 | { 123 | "schema_version": 0, 124 | "attributes": { 125 | "access_policies": "{\"Statement\":[{\"Action\":\"es:*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":[\"1.1.1.1\",\"2.2.2.2\"]}},\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Resource\":\"arn:aws:es:us-east-1:758889637411:domain/elasticsearch-public/*\",\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}", 126 | "advanced_options": { 127 | "rest.action.multi.allow_explicit_index": "true" 128 | }, 129 | "advanced_security_options": [ 130 | { 131 | "enabled": true, 132 | "internal_user_database_enabled": true, 133 | "master_user_options": [ 134 | { 135 | "master_user_arn": "", 136 | "master_user_name": "username", 137 | "master_user_password": "T0p$ecret" 138 | } 139 | ] 140 | } 141 | ], 142 | "arn": "arn:aws:es:us-east-1:758889637411:domain/elasticsearch-public", 143 | "cluster_config": [ 144 | { 145 | "dedicated_master_count": 3, 146 | "dedicated_master_enabled": true, 147 | "dedicated_master_type": "r5.large.elasticsearch", 148 | "instance_count": 3, 149 | "instance_type": "r5.large.elasticsearch", 150 | "warm_count": 0, 151 | "warm_enabled": false, 152 | "warm_type": "", 153 | "zone_awareness_config": [ 154 | { 155 | "availability_zone_count": 3 156 | } 157 | ], 158 | "zone_awareness_enabled": true 159 | } 160 | ], 161 | "cognito_options": [ 162 | { 163 | "enabled": false, 164 | "identity_pool_id": "", 165 | "role_arn": "", 166 | "user_pool_id": "" 167 | } 168 | ], 169 | "domain_endpoint_options": [ 170 | { 171 | "enforce_https": true, 172 | "tls_security_policy": "Policy-Min-TLS-1-2-2019-07" 173 | } 174 | ], 175 | "domain_id": "758889637411/elasticsearch-public", 176 | "domain_name": "elasticsearch-public", 177 | "ebs_options": [ 178 | { 179 | "ebs_enabled": true, 180 | "iops": 0, 181 | "volume_size": 25, 182 | "volume_type": "gp2" 183 | } 184 | ], 185 | "elasticsearch_version": "7.1", 186 | "encrypt_at_rest": [ 187 | { 188 | "enabled": true, 189 | "kms_key_id": "arn:aws:kms:us-east-1:758889637411:key/ccab903a-4ba1-4993-9fc7-f7e538b25bd3" 190 | } 191 | ], 192 | "endpoint": "search-elasticsearch-public-jcmrqqvbfmxe2sfy5i3rsaebhy.us-east-1.es.amazonaws.com", 193 | "id": "arn:aws:es:us-east-1:758889637411:domain/elasticsearch-public", 194 | "kibana_endpoint": "search-elasticsearch-public-jcmrqqvbfmxe2sfy5i3rsaebhy.us-east-1.es.amazonaws.com/_plugin/kibana/", 195 | "log_publishing_options": [ 196 | { 197 | "cloudwatch_log_group_arn": "arn:aws:logs:us-east-1:758889637411:log-group:elasticsearch-public-log_group", 198 | "enabled": true, 199 | "log_type": "INDEX_SLOW_LOGS" 200 | } 201 | ], 202 | "node_to_node_encryption": [ 203 | { 204 | "enabled": true 205 | } 206 | ], 207 | "snapshot_options": [ 208 | { 209 | "automated_snapshot_start_hour": 23 210 | } 211 | ], 212 | "tags": { 213 | "Owner": "sysops", 214 | "env": "dev" 215 | }, 216 | "timeouts": null, 217 | "vpc_options": [] 218 | }, 219 | "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsidXBkYXRlIjozNjAwMDAwMDAwMDAwfX0=", 220 | "dependencies": [ 221 | "data.aws_caller_identity.current", 222 | "data.aws_region.current", 223 | "module.aws_es.aws_cloudwatch_log_group.es_cloudwatch_log_group", 224 | "module.aws_es.aws_iam_service_linked_role.es", 225 | "module.aws_es.data.aws_kms_key.aws_es" 226 | ] 227 | } 228 | ] 229 | }, 230 | { 231 | "module": "module.aws_es", 232 | "mode": "managed", 233 | "type": "aws_iam_service_linked_role", 234 | "name": "es", 235 | "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", 236 | "instances": [ 237 | { 238 | "index_key": 0, 239 | "schema_version": 0, 240 | "attributes": { 241 | "arn": "arn:aws:iam::758889637411:role/aws-service-role/es.amazonaws.com/AWSServiceRoleForAmazonElasticsearchService", 242 | "aws_service_name": "es.amazonaws.com", 243 | "create_date": "2020-09-03T22:54:54Z", 244 | "custom_suffix": "", 245 | "description": "Service-linked role to give Amazon ES permissions to access your VPC", 246 | "id": "arn:aws:iam::758889637411:role/aws-service-role/es.amazonaws.com/AWSServiceRoleForAmazonElasticsearchService", 247 | "name": "AWSServiceRoleForAmazonElasticsearchService", 248 | "path": "/aws-service-role/es.amazonaws.com/", 249 | "unique_id": "AROA3BMKY4YR4LCCVEFMH" 250 | }, 251 | "private": "bnVsbA==" 252 | } 253 | ] 254 | } 255 | ] 256 | } 257 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/terraform.tfvars: -------------------------------------------------------------------------------- 1 | region = "us-east-1" 2 | profile = "default" 3 | es_domain_name = "elasticsearch-public" 4 | es_version = "7.1" 5 | whitelist = ["1.1.1.1", "2.2.2.2"] 6 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/variables.tf: -------------------------------------------------------------------------------- 1 | # Provider 2 | variable "region" {} 3 | variable "profile" {} 4 | 5 | 6 | # AWS Elasticsearch 7 | variable "es_domain_name" {} 8 | variable "es_version" {} 9 | 10 | 11 | # Whitelist (allow public IPs) 12 | variable "whitelist" { 13 | default = [] 14 | } 15 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | required_providers { 5 | aws = ">= 3.35.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/advanced_security_options_master_user_name_pasword/whitelits.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "", 6 | "Effect": "Allow", 7 | "Principal": { 8 | "AWS": "*" 9 | }, 10 | "Action": "es:*", 11 | "Resource": "arn:aws:es:${region}:${account}:domain/${domain_name}/*", 12 | "Condition": { 13 | "IpAddress": { 14 | "aws:SourceIp": ${whitelist} 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /examples/public/README.md: -------------------------------------------------------------------------------- 1 | # Public AWS Elasticearch Domain example 2 | 3 | ``` 4 | module "aws_es" { 5 | 6 | source = "lgallard/elasticsearch/aws" 7 | 8 | domain_name = var.es_domain_name 9 | elasticsearch_version = var.es_version 10 | 11 | cluster_config = { 12 | dedicated_master_enabled = "true" 13 | instance_count = "3" 14 | instance_type = "r5.large.elasticsearch" 15 | zone_awareness_enabled = "true" 16 | availability_zone_count = "3" 17 | } 18 | 19 | ebs_options = { 20 | ebs_enabled = "true" 21 | volume_size = "25" 22 | } 23 | 24 | encrypt_at_rest = { 25 | enabled = "true" 26 | kms_key_id = "alias/aws/es" 27 | } 28 | 29 | log_publishing_options = { 30 | index_slow_logs = { 31 | enabled = true 32 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/index_slow_logs:*" 33 | rog_publishing_options_retention = 90 34 | } 35 | search_slow_logs = { 36 | enabled = true 37 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/search_slow_logs:*" 38 | } 39 | es_application_logs = { 40 | enabled = true 41 | cloudwatch_log_group_name = "es_application_logs_dev" 42 | } 43 | audit_logs = { 44 | enabled = false 45 | cloudwatch_log_group_name = "audit_logs_dev" 46 | } 47 | } 48 | 49 | advanced_options = { 50 | "rest.action.multi.allow_explicit_index" = "true" 51 | } 52 | 53 | access_policies = templatefile("${path.module}/whitelits.tpl", { 54 | region = data.aws_region.current.name, 55 | account = data.aws_caller_identity.current.account_id, 56 | domain_name = var.es_domain_name, 57 | whitelist = "${jsonencode(var.whitelist)}" 58 | }) 59 | 60 | node_to_node_encryption_enabled = "true" 61 | snapshot_options_automated_snapshot_start_hour = "23" 62 | 63 | timeouts_update = "60m" 64 | 65 | tags = { 66 | Owner = "sysops" 67 | env = "dev" 68 | } 69 | } 70 | ``` 71 | -------------------------------------------------------------------------------- /examples/public/datasources.tf: -------------------------------------------------------------------------------- 1 | # Use this data source to get the access to the effective Account ID in which 2 | # Terraform is working. 3 | data "aws_caller_identity" "current" {} 4 | 5 | # To obtain the name of the AWS region configured on the provider 6 | data "aws_region" "current" {} 7 | -------------------------------------------------------------------------------- /examples/public/main.tf: -------------------------------------------------------------------------------- 1 | module "aws_es" { 2 | 3 | source = "../../" 4 | 5 | domain_name = var.es_domain_name 6 | elasticsearch_version = var.es_version 7 | 8 | cluster_config = { 9 | dedicated_master_enabled = true 10 | instance_count = 3 11 | instance_type = "r5.large.elasticsearch" 12 | zone_awareness_enabled = true 13 | availability_zone_count = 3 14 | } 15 | 16 | ebs_options = { 17 | ebs_enabled = true 18 | volume_size = 25 19 | } 20 | 21 | encrypt_at_rest = { 22 | enabled = true 23 | #kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 24 | } 25 | 26 | log_publishing_options = { 27 | index_slow_logs = { 28 | enabled = true 29 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/index_slow_logs:*" 30 | log_publishing_options_retention = 90 31 | } 32 | search_slow_logs = { 33 | enabled = true 34 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/search_slow_logs:*" 35 | } 36 | es_application_logs = { 37 | enabled = true 38 | cloudwatch_log_group_name = "es_application_logs_dev" 39 | } 40 | audit_logs = { 41 | enabled = false 42 | cloudwatch_log_group_name = "audit_logs_dev" 43 | } 44 | } 45 | 46 | advanced_options = { 47 | "rest.action.multi.allow_explicit_index" = true 48 | } 49 | 50 | access_policies = templatefile("${path.module}/whitelits.tpl", { 51 | region = data.aws_region.current.name, 52 | account = data.aws_caller_identity.current.account_id, 53 | domain_name = var.es_domain_name, 54 | whitelist = jsonencode(var.whitelist) 55 | }) 56 | 57 | node_to_node_encryption_enabled = true 58 | snapshot_options_automated_snapshot_start_hour = 23 59 | 60 | timeouts_update = "60m" 61 | 62 | tags = { 63 | Owner = "sysops" 64 | env = "dev" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/public/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.region 3 | profile = var.profile 4 | } 5 | -------------------------------------------------------------------------------- /examples/public/terraform.tfvars: -------------------------------------------------------------------------------- 1 | region = "us-east-1" 2 | profile = "default" 3 | es_domain_name = "elasticsearch-public" 4 | es_version = "7.1" 5 | whitelist = ["1.1.1.1", "2.2.2.2"] 6 | -------------------------------------------------------------------------------- /examples/public/variables.tf: -------------------------------------------------------------------------------- 1 | # Provider 2 | variable "region" {} 3 | variable "profile" {} 4 | 5 | 6 | # AWS Elasticsearch 7 | variable "es_domain_name" {} 8 | variable "es_version" {} 9 | 10 | 11 | # Whitelist (allow public IPs) 12 | variable "whitelist" { 13 | default = [] 14 | } 15 | -------------------------------------------------------------------------------- /examples/public/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | required_providers { 5 | aws = ">= 3.35.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/public/whitelits.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "", 6 | "Effect": "Allow", 7 | "Principal": { 8 | "AWS": "*" 9 | }, 10 | "Action": "es:*", 11 | "Resource": "arn:aws:es:${region}:${account}:domain/${domain_name}/*", 12 | "Condition": { 13 | "IpAddress": { 14 | "aws:SourceIp": ${whitelist} 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /examples/public_cold_storage/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/aws" { 5 | version = "4.18.0" 6 | constraints = ">= 3.35.0" 7 | hashes = [ 8 | "h1:2W4xAihPlycb2XISriYIk8xCLfmmwt6jgyE31oc7BWI=", 9 | "zh:100a11324326bf849b4c85d3c40a81e485726eee99c5a229387b8485a7a8da8b", 10 | "zh:2226bbf97101af90e43cd5606d8678f35d7e7b477657d9297c42a1bd2ed42750", 11 | "zh:27d51694300c08c32312f8832b889c57a2821dc022d49d38f9b1e14810f8a3fb", 12 | "zh:2b8792c76986facfd415f967c5d61022f7ceeaa46c158037fe8939e36d954f99", 13 | "zh:3ea787967de772cc3a13469753080c8fa81be5aefc735d3753c7627f63c948e5", 14 | "zh:64d58463cbb2b93d5202ef311a101890a1e083f9587f3eabb9f2e26dd0cf8f43", 15 | "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", 16 | "zh:b10eecf4c034a229712825124e7c0b765c5904648550dc8f844f68638531d337", 17 | "zh:d9a3cc46e2746c40ea69bcfb2d12e765ee6bda3e1ed8ce73f272d492ff4836bb", 18 | "zh:df625e57aa3b5fb3e4562da44daf6565289818ba2a7e66f86ad968b43fdb5148", 19 | "zh:eaaa3a5d2a15a87b346e521872120a3ca7f6777a04226a55f51022eaf4097963", 20 | "zh:ec6f4b00ae4f9d536f2a6c2e5a5f149867194268ce9068a9c348bc3e678fbfce", 21 | ] 22 | } 23 | 24 | provider "registry.terraform.io/hashicorp/random" { 25 | version = "3.3.1" 26 | constraints = ">= 3.1.2" 27 | hashes = [ 28 | "h1:2kuwBPKEqBblmy3cfB5OHOUCpe8GDsMFmjHc6uVFp3Y=", 29 | "zh:0af603dc14d0f7ec900b885f7e46226e5743323ce6fc25437738aae20906a799", 30 | "zh:0de2d8f185b006c8928c18e7374ba0ca1df5bbc8c0dc492fb1e539c3184b7472", 31 | "zh:118600e801bf73003ad2c57106564a5abdfe3b0e660b05b595e6884a009f32bd", 32 | "zh:4d7ff20cc1344040911b197741a364c20a51d31ea6c746ce77b0454ad96b9733", 33 | "zh:58b6443bdf638864bf32e580b60e1c811e0b38060d2dcc3a438ae4d83360300d", 34 | "zh:6b4418698a62a39dc9f6ac82f0a48bc115a4ab409435ba918511837f02817f44", 35 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 36 | "zh:a1a43952a4c4cb6970b3cc4bef8c5da74ced36bd4f451e9850074b464ab4ed21", 37 | "zh:c88095d4ca8cd30ccded57d39e55963f35044ffafebd56a2dc8568730edaf51a", 38 | "zh:c955d31c41f4a13c1dd4290afa84c762282998f9afc110970dd288cc6fac5847", 39 | "zh:d80e9b1d0f45e8377a20fe6280722ef6a49eb63d0aa0c71a2fd5a0817ec60458", 40 | "zh:da26a6f89d595e0416c99f4ad288f23b52490ab44882af8c8d9a8ef56c938c70", 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /examples/public_cold_storage/README.md: -------------------------------------------------------------------------------- 1 | # Public AWS Elasticearch Domain example 2 | 3 | ``` 4 | module "aws_es" { 5 | 6 | source = "lgallard/elasticsearch/aws" 7 | 8 | domain_name = var.es_domain_name 9 | elasticsearch_version = var.es_version 10 | 11 | cluster_config = { 12 | dedicated_master_enabled = "true" 13 | instance_count = "3" 14 | instance_type = "r5.large.elasticsearch" 15 | zone_awareness_enabled = "true" 16 | availability_zone_count = "3" 17 | } 18 | 19 | ebs_options = { 20 | ebs_enabled = "true" 21 | volume_size = "25" 22 | } 23 | 24 | encrypt_at_rest = { 25 | enabled = "true" 26 | kms_key_id = "alias/aws/es" 27 | } 28 | 29 | log_publishing_options = { 30 | index_slow_logs = { 31 | enabled = true 32 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/index_slow_logs:*" 33 | rog_publishing_options_retention = 90 34 | } 35 | search_slow_logs = { 36 | enabled = true 37 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:123456789101:log-group:/aws/elasticsearch/search_slow_logs:*" 38 | } 39 | es_application_logs = { 40 | enabled = true 41 | cloudwatch_log_group_name = "es_application_logs_dev" 42 | } 43 | audit_logs = { 44 | enabled = false 45 | cloudwatch_log_group_name = "audit_logs_dev" 46 | } 47 | } 48 | 49 | advanced_options = { 50 | "rest.action.multi.allow_explicit_index" = "true" 51 | } 52 | 53 | access_policies = templatefile("${path.module}/whitelits.tpl", { 54 | region = data.aws_region.current.name, 55 | account = data.aws_caller_identity.current.account_id, 56 | domain_name = var.es_domain_name, 57 | whitelist = "${jsonencode(var.whitelist)}" 58 | }) 59 | 60 | node_to_node_encryption_enabled = "true" 61 | snapshot_options_automated_snapshot_start_hour = "23" 62 | 63 | timeouts_update = "60m" 64 | 65 | tags = { 66 | Owner = "sysops" 67 | env = "dev" 68 | } 69 | } 70 | ``` 71 | -------------------------------------------------------------------------------- /examples/public_cold_storage/datasources.tf: -------------------------------------------------------------------------------- 1 | # Use this data source to get the access to the effective Account ID in which 2 | # Terraform is working. 3 | data "aws_caller_identity" "current" {} 4 | 5 | # To obtain the name of the AWS region configured on the provider 6 | data "aws_region" "current" {} 7 | -------------------------------------------------------------------------------- /examples/public_cold_storage/main.tf: -------------------------------------------------------------------------------- 1 | module "aws_es" { 2 | 3 | source = "../../" 4 | 5 | domain_name = var.es_domain_name 6 | elasticsearch_version = var.es_version 7 | 8 | cluster_config = { 9 | dedicated_master_enabled = true 10 | instance_count = 3 11 | instance_type = "r5.large.elasticsearch" 12 | zone_awareness_enabled = true 13 | warm_enabled = true 14 | warm_type = "ultrawarm1.medium.elasticsearch" 15 | warm_count = 2 16 | cold_storage_options_enabled = true 17 | availability_zone_count = 3 18 | } 19 | 20 | ebs_options = { 21 | ebs_enabled = true 22 | volume_size = 25 23 | } 24 | 25 | encrypt_at_rest = { 26 | enabled = true 27 | #kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 28 | } 29 | 30 | log_publishing_options = { 31 | index_slow_logs = { 32 | enabled = false 33 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:758889637411:log-group:/aws/elasticsearch/index_slow_logs:*" 34 | log_publishing_options_retention = 90 35 | } 36 | search_slow_logs = { 37 | enabled = false 38 | cloudwatch_log_group_arn = "arn:aws:logs:us-east-1:758889637411:log-group:/aws/elasticsearch/search_slow_logs:*" 39 | } 40 | es_application_logs = { 41 | enabled = false 42 | cloudwatch_log_group_name = "es_application_logs_dev" 43 | } 44 | audit_logs = { 45 | enabled = false 46 | cloudwatch_log_group_name = "audit_logs_dev" 47 | } 48 | } 49 | 50 | advanced_options = { 51 | "rest.action.multi.allow_explicit_index" = true 52 | } 53 | 54 | access_policies = templatefile("${path.module}/whitelits.tpl", { 55 | region = data.aws_region.current.name, 56 | account = data.aws_caller_identity.current.account_id, 57 | domain_name = var.es_domain_name, 58 | whitelist = jsonencode(var.whitelist) 59 | }) 60 | 61 | node_to_node_encryption_enabled = true 62 | snapshot_options_automated_snapshot_start_hour = 23 63 | 64 | timeouts_update = "60m" 65 | 66 | tags = { 67 | Owner = "sysops" 68 | env = "dev" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/public_cold_storage/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.region 3 | profile = var.profile 4 | } 5 | -------------------------------------------------------------------------------- /examples/public_cold_storage/terraform.tfvars: -------------------------------------------------------------------------------- 1 | region = "us-east-1" 2 | profile = "default" 3 | es_domain_name = "elasticsearch-public" 4 | es_version = "OpenSearch_1.2" 5 | whitelist = ["1.1.1.1", "2.2.2.2"] 6 | -------------------------------------------------------------------------------- /examples/public_cold_storage/variables.tf: -------------------------------------------------------------------------------- 1 | # Provider 2 | variable "region" {} 3 | variable "profile" {} 4 | 5 | 6 | # AWS Elasticsearch 7 | variable "es_domain_name" {} 8 | variable "es_version" {} 9 | 10 | 11 | # Whitelist (allow public IPs) 12 | variable "whitelist" { 13 | default = [] 14 | } 15 | -------------------------------------------------------------------------------- /examples/public_cold_storage/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | required_providers { 5 | aws = ">= 3.35.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/public_cold_storage/whitelits.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Sid": "", 6 | "Effect": "Allow", 7 | "Principal": { 8 | "AWS": "*" 9 | }, 10 | "Action": "es:*", 11 | "Resource": "arn:aws:es:${region}:${account}:domain/${domain_name}/*", 12 | "Condition": { 13 | "IpAddress": { 14 | "aws:SourceIp": ${whitelist} 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /examples/vpc/README.md: -------------------------------------------------------------------------------- 1 | # AWS Elasticsearch Domain within a VPC example 2 | 3 | ``` 4 | module "aws_es" { 5 | 6 | source = "lgallard/elasticsearch/aws" 7 | 8 | domain_name = var.es_domain_name 9 | elasticsearch_version = var.es_version 10 | 11 | cluster_config = { 12 | dedicated_master_enabled = "true" 13 | instance_count = "3" 14 | instance_type = "r5.large.elasticsearch" 15 | zone_awareness_enabled = "true" 16 | availability_zone_count = "3" 17 | } 18 | 19 | ebs_options = { 20 | ebs_enabled = "true" 21 | volume_size = "25" 22 | } 23 | 24 | encrypt_at_rest = { 25 | enabled = "true" 26 | kms_key_id = "alias/aws/es" 27 | } 28 | 29 | vpc_options = { 30 | subnet_ids = ["subnet-09999999999999999", "subnet-02222222222222222", "subnet-05555555555555555"] 31 | security_group_ids = ["sg-03333333333333333"] 32 | } 33 | 34 | node_to_node_encryption_enabled = true 35 | snapshot_options_automated_snapshot_start_hour = 23 36 | 37 | access_policies = templatefile("${path.module}/access_policies.tpl", { 38 | region = data.aws_region.current.name, 39 | account = data.aws_caller_identity.current.account_id, 40 | domain_name = var.es_domain_name 41 | }) 42 | 43 | timeouts_update = "60m" 44 | 45 | tags = { 46 | Owner = "sysops" 47 | env = "dev" 48 | } 49 | 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /examples/vpc/access_policies.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": "es:*", 6 | "Principal": "*", 7 | "Effect": "Allow", 8 | "Resource": "arn:aws:es:${region}:${account}:domain/${domain_name}/*" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/vpc/datasources.tf: -------------------------------------------------------------------------------- 1 | # Use this data source to get the access to the effective Account ID in which 2 | # Terraform is working. 3 | data "aws_caller_identity" "current" {} 4 | 5 | # To obtain the name of the AWS region configured on the provider 6 | data "aws_region" "current" {} 7 | -------------------------------------------------------------------------------- /examples/vpc/main.tf: -------------------------------------------------------------------------------- 1 | module "aws_es" { 2 | 3 | source = "lgallard/elasticsearch/aws" 4 | 5 | domain_name = var.es_domain_name 6 | elasticsearch_version = var.es_version 7 | 8 | cluster_config = { 9 | dedicated_master_enabled = true 10 | instance_count = 3 11 | instance_type = "r5.large.elasticsearch" 12 | zone_awareness_enabled = true 13 | availability_zone_count = 3 14 | } 15 | 16 | ebs_options = { 17 | ebs_enabled = true 18 | volume_size = 25 19 | } 20 | 21 | encrypt_at_rest = { 22 | enabled = true 23 | kms_key_id = "arn:aws:kms:us-east-1:123456789101:key/cccc103b-4ba3-5993-6fc7-b7e538b25fd8" 24 | } 25 | 26 | vpc_options = { 27 | subnet_ids = ["subnet-09999999999999999", "subnet-02222222222222222", "subnet-05555555555555555"] 28 | security_group_ids = ["sg-03333333333333333"] 29 | } 30 | 31 | node_to_node_encryption_enabled = true 32 | snapshot_options_automated_snapshot_start_hour = 23 33 | 34 | access_policies = templatefile("${path.module}/access_policies.tpl", { 35 | region = data.aws_region.current.name, 36 | account = data.aws_caller_identity.current.account_id, 37 | domain_name = var.es_domain_name 38 | }) 39 | 40 | timeouts_update = "60m" 41 | 42 | tags = { 43 | Owner = "sysops" 44 | env = "dev" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/vpc/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = var.region 3 | profile = var.profile 4 | } 5 | -------------------------------------------------------------------------------- /examples/vpc/terraform.tfvars: -------------------------------------------------------------------------------- 1 | profile = "default" 2 | region = "us-east-1" 3 | es_domain_name = "elasticsearch-vpc" 4 | es_version = "7.1" 5 | -------------------------------------------------------------------------------- /examples/vpc/variable.tf: -------------------------------------------------------------------------------- 1 | variable "region" {} 2 | variable "profile" {} 3 | 4 | # AWS Elasticsearch 5 | variable "es_domain_name" {} 6 | variable "es_version" {} 7 | -------------------------------------------------------------------------------- /examples/vpc/versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | required_providers { 5 | aws = ">= 3.35.0" 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /iam.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_log_group" "es_cloudwatch_log_group" { 2 | 3 | for_each = { for k, v in var.log_publishing_options : 4 | k => v if var.enabled && lookup(v, "enabled", false) && lookup(v, "cloudwatch_log_group_name", null) != null 5 | } 6 | 7 | name = each.value["cloudwatch_log_group_name"] 8 | retention_in_days = lookup(each.value, "log_publishing_options_retention", var.log_publishing_options_retention) 9 | tags = merge(lookup(each.value, "tags", null), var.tags) 10 | } 11 | 12 | resource "aws_cloudwatch_log_resource_policy" "es_aws_cloudwatch_log_resource_policy" { 13 | count = var.enabled && var.cloudwatch_log_enabled ? 1 : 0 14 | policy_name = "${var.domain_name}-policy" 15 | 16 | policy_document = < v if var.enabled && lookup(v, "enabled", false) 125 | } 126 | content { 127 | log_type = upper(log_publishing_options.key) 128 | cloudwatch_log_group_arn = lookup(log_publishing_options.value, "cloudwatch_log_group_arn", null) != null ? lookup(log_publishing_options.value, "cloudwatch_log_group_arn") : aws_cloudwatch_log_group.es_cloudwatch_log_group[log_publishing_options.key].arn 129 | enabled = lookup(log_publishing_options.value, "enabled") 130 | } 131 | } 132 | 133 | # cognito_options 134 | dynamic "cognito_options" { 135 | for_each = local.cognito_options 136 | content { 137 | enabled = lookup(cognito_options.value, "enabled") 138 | user_pool_id = lookup(cognito_options.value, "user_pool_id") 139 | identity_pool_id = lookup(cognito_options.value, "identity_pool_id") 140 | role_arn = lookup(cognito_options.value, "role_arn") 141 | } 142 | } 143 | 144 | # Timeouts 145 | dynamic "timeouts" { 146 | for_each = local.timeouts 147 | content { 148 | update = lookup(timeouts.value, "update") 149 | } 150 | } 151 | 152 | # Tags 153 | tags = var.tags 154 | 155 | # Service-linked role to give Amazon ES permissions to access your VPC 156 | depends_on = [aws_iam_service_linked_role.es, aws_cloudwatch_log_group.es_cloudwatch_log_group] 157 | 158 | } 159 | 160 | resource "random_password" "master_password" { 161 | count = local.create_random_master_password ? 1 : 0 162 | 163 | length = var.advanced_security_options_random_master_password_length 164 | special = true 165 | } 166 | 167 | locals { 168 | # advanced_security_options 169 | # Create subblock master_user_options 170 | create_random_master_password = var.advanced_security_options_enabled && var.advanced_security_options_internal_user_database_enabled && var.advanced_security_options_create_random_master_password 171 | master_user_arn = var.advanced_security_options_internal_user_database_enabled == false ? var.advanced_security_options_master_user_arn : null 172 | master_user_name = var.advanced_security_options_internal_user_database_enabled == true ? var.advanced_security_options_master_user_username : null 173 | master_user_password = local.create_random_master_password == true ? random_password.master_password[0].result : var.advanced_security_options_master_user_password 174 | 175 | master_user_options = lookup(var.advanced_security_options, "master_user_options", null) != null ? lookup(var.advanced_security_options, "master_user_options") : { 176 | master_user_arn = local.master_user_arn 177 | master_user_name = local.master_user_name 178 | master_user_password = local.master_user_password 179 | } 180 | 181 | # If advanced_security_options is provided, build an advanced_security_options using the default values 182 | advanced_security_options_default = { 183 | enabled = lookup(var.advanced_security_options, "enabled", null) == null ? var.advanced_security_options_enabled : lookup(var.advanced_security_options, "enabled") 184 | internal_user_database_enabled = lookup(var.advanced_security_options, "internal_user_database_enabled", null) == null ? var.advanced_security_options_internal_user_database_enabled : lookup(var.advanced_security_options, "internal_user_database_enabled") 185 | master_user_options = local.master_user_options 186 | } 187 | 188 | advanced_security_options = lookup(local.advanced_security_options_default, "enabled", false) == false ? [] : [local.advanced_security_options_default] 189 | 190 | # If domain_endpoint_options is provided, build an domain_endpoint_options using the default values 191 | domain_endpoint_options_default = { 192 | enforce_https = lookup(var.domain_endpoint_options, "enforce_https", null) == null ? var.domain_endpoint_options_enforce_https : lookup(var.domain_endpoint_options, "enforce_https") 193 | tls_security_policy = lookup(var.domain_endpoint_options, "tls_security_policy", null) == null ? var.domain_endpoint_options_tls_security_policy : lookup(var.domain_endpoint_options, "tls_security_policy") 194 | 195 | # custom_endpoint 196 | custom_endpoint_enabled = lookup(var.domain_endpoint_options, "custom_endpoint_enabled", null) == null ? var.domain_endpoint_options_custom_endpoint_enabled : lookup(var.domain_endpoint_options, "custom_endpoint_enabled") 197 | custom_endpoint = lookup(var.domain_endpoint_options, "custom_endpoint", null) == null ? var.domain_endpoint_options_custom_endpoint : lookup(var.domain_endpoint_options, "custom_endpoint") 198 | custom_endpoint_certificate_arn = lookup(var.domain_endpoint_options, "custom_endpoint_certificate_arn", null) == null ? var.domain_endpoint_options_custom_endpoint_certificate_arn : lookup(var.domain_endpoint_options, "custom_endpoint_certificate_arn") 199 | } 200 | 201 | domain_endpoint_options = lookup(local.domain_endpoint_options_default, "enforce_https", false) == false ? [] : [local.domain_endpoint_options_default] 202 | 203 | # ebs_options 204 | # If no ebs_options is provided, build an ebs_options using the default values 205 | ebs_option_default = { 206 | ebs_enabled = lookup(var.ebs_options, "ebs_enabled", null) == null ? var.ebs_enabled : lookup(var.ebs_options, "ebs_enabled") 207 | volume_type = lookup(var.ebs_options, "volume_type", null) == null ? var.ebs_options_volume_type : lookup(var.ebs_options, "volume_type") 208 | volume_size = lookup(var.ebs_options, "volume_size", null) == null ? var.ebs_options_volume_size : lookup(var.ebs_options, "volume_size") 209 | iops = lookup(var.ebs_options, "iops", null) == null ? var.ebs_options_iops : lookup(var.ebs_options, "iops") 210 | } 211 | 212 | ebs_options = var.ebs_enabled == false || lookup(local.ebs_option_default, "ebs_enabled", false) == false ? [] : [local.ebs_option_default] 213 | 214 | # encrypt_at_rest 215 | # If no encrypt_at_rest list is provided, build a encrypt_at_rest using the default values 216 | 217 | encrypt_at_rest_default = { 218 | enabled = lookup(var.encrypt_at_rest, "enabled", null) == null ? var.encrypt_at_rest_enabled : lookup(var.encrypt_at_rest, "enabled") 219 | kms_key_id = lookup(var.encrypt_at_rest, "kms_key_id", null) == null ? data.aws_kms_key.aws_es.arn : lookup(var.encrypt_at_rest, "kms_key_id") 220 | } 221 | 222 | encrypt_at_rest = var.encrypt_at_rest_enabled == false || lookup(local.encrypt_at_rest_default, "enabled", false) == false ? [] : [local.encrypt_at_rest_default] 223 | 224 | # node_to_node_encryption 225 | # If no node_to_node_encryption list is provided, build a node_to_node_encryption using the default values 226 | node_to_node_encryption_default = { 227 | enabled = lookup(var.node_to_node_encryption, "enabled", null) == null ? var.node_to_node_encryption_enabled : lookup(var.node_to_node_encryption, "enabled") 228 | } 229 | 230 | node_to_node_encryption = var.node_to_node_encryption_enabled == false || lookup(local.node_to_node_encryption_default, "enabled", false) == false ? [] : [local.node_to_node_encryption_default] 231 | 232 | # cluster_config 233 | # If no cluster_config list is provided, build a cluster_config using the default values 234 | cluster_config_default = { 235 | instance_type = lookup(var.cluster_config, "instance_type", null) == null ? var.cluster_config_instance_type : lookup(var.cluster_config, "instance_type") 236 | instance_count = lookup(var.cluster_config, "instance_count", null) == null ? var.cluster_config_instance_count : lookup(var.cluster_config, "instance_count") 237 | dedicated_master_enabled = lookup(var.cluster_config, "dedicated_master_enabled", null) == null ? var.cluster_config_dedicated_master_enabled : lookup(var.cluster_config, "dedicated_master_enabled") 238 | dedicated_master_type = lookup(var.cluster_config, "dedicated_master_type", null) == null ? var.cluster_config_dedicated_master_type : lookup(var.cluster_config, "dedicated_master_type") 239 | dedicated_master_count = lookup(var.cluster_config, "dedicated_master_count", null) == null ? var.cluster_config_dedicated_master_count : lookup(var.cluster_config, "dedicated_master_count") 240 | zone_awareness_enabled = lookup(var.cluster_config, "zone_awareness_enabled", null) == null ? var.cluster_config_zone_awareness_enabled : lookup(var.cluster_config, "zone_awareness_enabled") 241 | availability_zone_count = lookup(var.cluster_config, "availability_zone_count", null) == null ? var.cluster_config_availability_zone_count : lookup(var.cluster_config, "availability_zone_count") 242 | warm_enabled = lookup(var.cluster_config, "warm_enabled", null) == null ? var.cluster_config_warm_enabled : lookup(var.cluster_config, "warm_enabled") 243 | warm_count = lookup(var.cluster_config, "warm_count", null) == null ? var.cluster_config_warm_count : lookup(var.cluster_config, "warm_count") 244 | warm_type = lookup(var.cluster_config, "warm_type", null) == null ? var.cluster_config_warm_type : lookup(var.cluster_config, "warm_type") 245 | cold_storage_options_enabled = lookup(var.cluster_config, "cold_storage_options_enabled", null) == null ? var.cluster_config_cold_storage_options_enabled : lookup(var.cluster_config, "cold_storage_options_enabled") 246 | } 247 | 248 | cluster_config = [local.cluster_config_default] 249 | 250 | # snapshot_options 251 | # If no snapshot_options list is provided, build a snapshot_options using the default values 252 | snapshot_options_default = { 253 | automated_snapshot_start_hour = lookup(var.snapshot_options, "automated_snapshot_start_hour", null) == null ? var.snapshot_options_automated_snapshot_start_hour : lookup(var.snapshot_options, "automated_snapshot_start_hour") 254 | } 255 | 256 | snapshot_options = [local.snapshot_options_default] 257 | 258 | # vpc_options 259 | # If no vpc_options list is provided, build a vpc_options using the default values 260 | vpc_options_default = { 261 | security_group_ids = lookup(var.vpc_options, "security_group_ids", null) == null ? var.vpc_options_security_group_ids : lookup(var.vpc_options, "security_group_ids") 262 | subnet_ids = lookup(var.vpc_options, "subnet_ids", null) == null ? var.vpc_options_subnet_ids : lookup(var.vpc_options, "subnet_ids") 263 | } 264 | 265 | vpc_options = length(lookup(local.vpc_options_default, "subnet_ids")) == 0 ? [] : [local.vpc_options_default] 266 | 267 | # cognito_options 268 | # If no cognito_options list is provided, build a cognito_options using the default values 269 | cognito_options_default = { 270 | enabled = lookup(var.cognito_options, "enabled", null) == null ? var.cognito_options_enabled : lookup(var.cognito_options, "enabled") 271 | user_pool_id = lookup(var.cognito_options, "user_pool_id", null) == null ? var.cognito_options_user_pool_id : lookup(var.cognito_options, "user_pool_id") 272 | identity_pool_id = lookup(var.cognito_options, "identity_pool_id", null) == null ? var.cognito_options_identity_pool_id : lookup(var.cognito_options, "identity_pool_id") 273 | role_arn = lookup(var.cognito_options, "role_arn", null) == null ? var.cognito_options_role_arn : lookup(var.cognito_options, "role_arn") 274 | } 275 | 276 | cognito_options = var.cognito_options_enabled == false || lookup(local.cognito_options_default, "enabled", false) == false ? [] : [local.cognito_options_default] 277 | 278 | # Timeouts 279 | # If timeouts block is provided, build one using the default values 280 | timeouts = var.timeouts_update == null && length(var.timeouts) == 0 ? [] : [ 281 | { 282 | update = lookup(var.timeouts, "update", null) == null ? var.timeouts_update : lookup(var.timeouts, "update") 283 | } 284 | ] 285 | 286 | 287 | } 288 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | description = "Amazon Resource Name (ARN) of the domain" 3 | value = join("", aws_elasticsearch_domain.es_domain.*.arn) 4 | } 5 | 6 | output "domain_id" { 7 | description = "Unique identifier for the domain" 8 | value = join("", aws_elasticsearch_domain.es_domain.*.domain_id) 9 | } 10 | 11 | output "endpoint" { 12 | description = "Domain-specific endpoint used to submit index, search, and data upload requests" 13 | value = join("", aws_elasticsearch_domain.es_domain.*.endpoint) 14 | } 15 | 16 | output "kibana_endpoint" { 17 | description = "Domain-specific endpoint for kibana without https scheme" 18 | value = join("", aws_elasticsearch_domain.es_domain.*.kibana_endpoint) 19 | } 20 | 21 | output "master_username" { 22 | description = "Master username" 23 | value = local.master_user_name 24 | } 25 | 26 | output "master_password" { 27 | description = "Master password" 28 | value = local.master_user_password 29 | sensitive = true 30 | } 31 | 32 | output "vpc_options_availability_zones" { 33 | description = "If the domain was created inside a VPC, the names of the availability zones the configured subnet_ids were created inside" 34 | value = var.enabled ? (length(aws_elasticsearch_domain.es_domain[0].vpc_options) > 0 ? aws_elasticsearch_domain.es_domain[0].vpc_options.0.availability_zones : []) : [] 35 | } 36 | 37 | output "vpc_options_vpc_id" { 38 | description = "If the domain was created inside a VPC, the ID of the VPC" 39 | value = var.enabled ? length(aws_elasticsearch_domain.es_domain[0].vpc_options) > 0 ? aws_elasticsearch_domain.es_domain[0].vpc_options.0.vpc_id : null : null 40 | } 41 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | # 2 | # AWS ElasticSearch 3 | # 4 | variable "domain_name" { 5 | description = "Name of the domain" 6 | type = string 7 | } 8 | 9 | variable "elasticsearch_version" { 10 | description = "The version of Elasticsearch to deploy." 11 | type = string 12 | default = "7.1" 13 | } 14 | 15 | variable "access_policies" { 16 | description = "IAM policy document specifying the access policies for the domain" 17 | type = string 18 | default = "" 19 | } 20 | 21 | variable "enabled" { 22 | description = "Change to false to avoid deploying any AWS ElasticSearch resources" 23 | type = bool 24 | default = true 25 | } 26 | 27 | variable "cloudwatch_log_enabled" { 28 | description = "Change to false to avoid deploying any Cloudwatch Logs resources" 29 | type = bool 30 | default = true 31 | } 32 | 33 | # Advanced security options 34 | variable "advanced_security_options" { 35 | description = "Options for fine-grained access control" 36 | type = any 37 | default = {} 38 | } 39 | 40 | variable "advanced_security_options_enabled" { 41 | description = "Whether advanced security is enabled (Forces new resource)" 42 | type = bool 43 | default = false 44 | } 45 | 46 | variable "advanced_security_options_internal_user_database_enabled" { 47 | description = "Whether the internal user database is enabled. If not set, defaults to false by the AWS API." 48 | type = bool 49 | default = false 50 | } 51 | 52 | variable "advanced_security_options_master_user_arn" { 53 | description = "ARN for the master user. Only specify if `internal_user_database_enabled` is not set or set to `false`)" 54 | type = string 55 | default = null 56 | } 57 | 58 | variable "advanced_security_options_master_user_username" { 59 | description = "The master user's username, which is stored in the Amazon Elasticsearch Service domain's internal database. Only specify if `internal_user_database_enabled` is set to `true`." 60 | type = string 61 | default = null 62 | } 63 | 64 | variable "advanced_security_options_master_user_password" { 65 | description = "The master user's password, which is stored in the Amazon Elasticsearch Service domain's internal database. Only specify if `internal_user_database_enabled` is set to `true`." 66 | type = string 67 | default = null 68 | } 69 | 70 | variable "advanced_security_options_create_random_master_password" { 71 | description = "Whether to create random master password for Elasticsearch master user" 72 | type = bool 73 | default = false 74 | } 75 | 76 | variable "advanced_security_options_random_master_password_length" { 77 | description = "Length of random master password to create" 78 | type = number 79 | default = 16 80 | } 81 | 82 | # Domain endpoint options 83 | variable "domain_endpoint_options" { 84 | description = "Domain endpoint HTTP(S) related options." 85 | type = any 86 | default = {} 87 | } 88 | 89 | variable "domain_endpoint_options_enforce_https" { 90 | description = "Whether or not to require HTTPS" 91 | type = bool 92 | default = false 93 | } 94 | 95 | variable "domain_endpoint_options_tls_security_policy" { 96 | description = "The name of the TLS security policy that needs to be applied to the HTTPS endpoint. Valid values: `Policy-Min-TLS-1-0-2019-07` and `Policy-Min-TLS-1-2-2019-07`" 97 | type = string 98 | default = "Policy-Min-TLS-1-2-2019-07" 99 | } 100 | 101 | variable "domain_endpoint_options_custom_endpoint_enabled" { 102 | description = "Whether to enable custom endpoint for the Elasticsearch domain" 103 | type = bool 104 | default = false 105 | } 106 | 107 | variable "domain_endpoint_options_custom_endpoint" { 108 | description = "Fully qualified domain for your custom endpoint" 109 | type = string 110 | default = null 111 | } 112 | 113 | variable "domain_endpoint_options_custom_endpoint_certificate_arn" { 114 | description = "ACM certificate ARN for your custom endpoint" 115 | type = string 116 | default = null 117 | } 118 | 119 | # Advanced options 120 | variable "advanced_options" { 121 | description = "Key-value string pairs to specify advanced configuration options. Note that the values for these configuration options must be strings (wrapped in quotes) or they may be wrong and cause a perpetual diff, causing Terraform to want to recreate your Elasticsearch domain on every apply" 122 | type = map(string) 123 | default = {} 124 | } 125 | 126 | # ebs_options 127 | variable "ebs_options" { 128 | description = "EBS related options, may be required based on chosen instance size" 129 | type = any 130 | default = {} 131 | } 132 | 133 | variable "ebs_enabled" { 134 | description = "Whether EBS volumes are attached to data nodes in the domain" 135 | type = bool 136 | default = true 137 | } 138 | 139 | variable "ebs_options_volume_type" { 140 | description = "The type of EBS volumes attached to data nodes" 141 | type = string 142 | default = "gp2" 143 | } 144 | 145 | variable "ebs_options_volume_size" { 146 | description = "The size of EBS volumes attached to data nodes (in GB). Required if ebs_enabled is set to true" 147 | type = number 148 | default = 10 149 | } 150 | 151 | variable "ebs_options_iops" { 152 | description = "The baseline input/output (I/O) performance of EBS volumes attached to data nodes. Applicable only for the Provisioned IOPS EBS volume type" 153 | type = number 154 | default = 0 155 | } 156 | 157 | # encrypt_at_rest 158 | variable "encrypt_at_rest" { 159 | description = "Encrypt at rest options. Only available for certain instance types" 160 | type = any 161 | default = {} 162 | } 163 | 164 | variable "encrypt_at_rest_enabled" { 165 | description = "Whether to enable encryption at rest" 166 | type = bool 167 | default = true 168 | } 169 | 170 | variable "encrypt_at_rest_kms_key_id" { 171 | description = "The KMS key id to encrypt the Elasticsearch domain with. If not specified then it defaults to using the aws/es service KMS key" 172 | type = string 173 | default = "alias/aws/es" 174 | } 175 | 176 | # node_to_node_encryption 177 | variable "node_to_node_encryption" { 178 | description = "Node-to-node encryption options" 179 | type = any 180 | default = {} 181 | } 182 | 183 | variable "node_to_node_encryption_enabled" { 184 | description = "Whether to enable node-to-node encryption" 185 | type = bool 186 | default = true 187 | } 188 | 189 | # cluster_config 190 | variable "cluster_config" { 191 | description = "Cluster configuration of the domain" 192 | type = any 193 | default = {} 194 | } 195 | 196 | variable "cluster_config_instance_type" { 197 | description = "Instance type of data nodes in the cluster" 198 | type = string 199 | default = "r5.large.elasticsearch" 200 | } 201 | 202 | variable "cluster_config_instance_count" { 203 | description = "Number of instances in the cluster" 204 | type = number 205 | default = 3 206 | } 207 | 208 | variable "cluster_config_dedicated_master_enabled" { 209 | description = "Indicates whether dedicated master nodes are enabled for the cluster" 210 | type = bool 211 | default = true 212 | } 213 | 214 | variable "cluster_config_dedicated_master_type" { 215 | description = "Instance type of the dedicated master nodes in the cluster" 216 | type = string 217 | default = "r5.large.elasticsearch" 218 | } 219 | 220 | variable "cluster_config_dedicated_master_count" { 221 | description = "Number of dedicated master nodes in the cluster" 222 | type = number 223 | default = 3 224 | } 225 | 226 | variable "cluster_config_availability_zone_count" { 227 | description = "Number of Availability Zones for the domain to use with" 228 | type = number 229 | default = 3 230 | } 231 | 232 | variable "cluster_config_zone_awareness_enabled" { 233 | description = "Indicates whether zone awareness is enabled. To enable awareness with three Availability Zones" 234 | type = bool 235 | default = false 236 | } 237 | 238 | variable "cluster_config_warm_enabled" { 239 | description = "Indicates whether to enable warm storage" 240 | type = bool 241 | default = false 242 | } 243 | 244 | variable "cluster_config_warm_count" { 245 | description = "The number of warm nodes in the cluster" 246 | type = number 247 | default = null 248 | } 249 | 250 | variable "cluster_config_warm_type" { 251 | description = "The instance type for the Elasticsearch cluster's warm nodes" 252 | type = string 253 | default = null 254 | } 255 | 256 | variable "cluster_config_cold_storage_options_enabled" { 257 | description = "Indicates whether to enable cold storage for an Elasticsearch domain" 258 | type = bool 259 | default = false 260 | } 261 | 262 | # snapshot_options 263 | variable "snapshot_options" { 264 | description = "Snapshot related options" 265 | type = any 266 | default = {} 267 | } 268 | 269 | variable "snapshot_options_automated_snapshot_start_hour" { 270 | description = "Hour during which the service takes an automated daily snapshot of the indices in the domain" 271 | type = number 272 | default = 0 273 | } 274 | 275 | # vpc_options 276 | variable "vpc_options" { 277 | description = "VPC related options, see below. Adding or removing this configuration forces a new resource" 278 | type = any 279 | default = {} 280 | } 281 | 282 | variable "vpc_options_security_group_ids" { 283 | description = "List of VPC Security Group IDs to be applied to the Elasticsearch domain endpoints. If omitted, the default Security Group for the VPC will be used" 284 | type = list(any) 285 | default = [] 286 | } 287 | 288 | variable "vpc_options_subnet_ids" { 289 | description = "List of VPC Subnet IDs for the Elasticsearch domain endpoints to be created in" 290 | type = list(any) 291 | default = [] 292 | } 293 | 294 | # log_publishing_options 295 | variable "log_publishing_options" { 296 | description = "Options for publishing slow logs to CloudWatch Logs" 297 | type = any 298 | default = {} 299 | } 300 | 301 | 302 | variable "log_publishing_options_retention" { 303 | description = "Retention in days for the created Cloudwatch log group" 304 | type = number 305 | default = 90 306 | } 307 | 308 | 309 | # cognito_options 310 | variable "cognito_options" { 311 | description = "Options for Amazon Cognito Authentication for Kibana" 312 | type = any 313 | default = {} 314 | } 315 | 316 | variable "cognito_options_enabled" { 317 | description = "Specifies whether Amazon Cognito authentication with Kibana is enabled or not" 318 | type = bool 319 | default = false 320 | } 321 | 322 | variable "cognito_options_user_pool_id" { 323 | description = "ID of the Cognito User Pool to use" 324 | type = string 325 | default = "" 326 | } 327 | 328 | variable "cognito_options_identity_pool_id" { 329 | description = "ID of the Cognito Identity Pool to use" 330 | type = string 331 | default = "" 332 | } 333 | 334 | variable "cognito_options_role_arn" { 335 | description = "ARN of the IAM role that has the AmazonESCognitoAccess policy attached" 336 | type = string 337 | default = "" 338 | } 339 | 340 | variable "tags" { 341 | description = "A mapping of tags to assign to the resource" 342 | type = map(any) 343 | default = {} 344 | } 345 | 346 | 347 | # Timeouts 348 | variable "timeouts" { 349 | description = "Timeouts map." 350 | type = map(any) 351 | default = {} 352 | } 353 | 354 | variable "timeouts_update" { 355 | description = "How long to wait for updates." 356 | type = string 357 | default = null 358 | } 359 | 360 | # Service Link Role 361 | variable "create_service_link_role" { 362 | description = "Create service link role for AWS Elasticsearch Service" 363 | type = bool 364 | default = true 365 | } 366 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.12.9" 3 | 4 | required_providers { 5 | aws = ">= 3.35.0" 6 | random = ">=3.1.2" 7 | } 8 | } 9 | --------------------------------------------------------------------------------