Skip to content

Commit

Permalink
feat(module): add support to customize vpc and ebs options
Browse files Browse the repository at this point in the history
* feat(saml): add support to disable SAML authentication

* feat(acm): add support to an existing ACM certificate

* feat(vpc): add support to customize vpc options

* feat(ebs): add support to customize ebs options

* docs(readme): update prerequisites and input variables

Co-authored-by: Giuseppe Misurelli <misurellig@ip-192-168-1-51.ec2.internal>
Co-authored-by: misurellig <lagrancartola@gmail.com>
Co-authored-by: Steve Teuber <steve.teuber@idealo.de>
  • Loading branch information
4 people authored Jan 6, 2023
1 parent b60cc80 commit ee8c8c7
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 6 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Terraform module to provision an OpenSearch cluster with SAML authentication.
## Prerequisites

- A [hosted zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingHostedZone.html) to route traffic to your OpenSearch domain
- An [entityID and metadata XML](https://aws.amazon.com/de/blogs/security/configure-saml-single-sign-on-for-kibana-with-ad-fs-on-amazon-elasticsearch-service/) from your SAML identity provider
- An [entityID and metadata XML](https://aws.amazon.com/de/blogs/security/configure-saml-single-sign-on-for-kibana-with-ad-fs-on-amazon-elasticsearch-service/) from your SAML identity provider (in case `saml_enabled = true`)

## Features

Expand Down Expand Up @@ -111,6 +111,12 @@ Here is a working example of using this Terraform module:
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | The name of the OpenSearch cluster. | `string` | `"opensearch"` | no |
| <a name="input_cluster_version"></a> [cluster\_version](#input\_cluster\_version) | The version of OpenSearch to deploy. | `string` | `"1.0"` | no |
| <a name="input_create_service_role"></a> [create\_service\_role](#input\_create\_service\_role) | Indicates whether to create the service-linked role. See https://docs.aws.amazon.com/opensearch-service/latest/developerguide/slr.html | `bool` | `true` | no |
| <a name="input_custom_endpoint_certificate_arn"></a> [custom\_endpoint\_certificate\_arn](#input\_custom\_endpoint\_certificate\_arn) | The ARN of the custom ACM certificate. | `string` | `""` | no |
| <a name="input_ebs_enabled"></a> [ebs\_enabled](#input\_ebs\_enabled) | Indicates whether attach EBS volumes to the data nodes. | `bool` | `false` | no |
| <a name="input_ebs_iops"></a> [ebs\_iops](#input\_ebs\_iops) | The baseline input/output (I/O) performance of EBS volumes attached to data nodes. | `number` | `3000` | no |
| <a name="input_ebs_throughput"></a> [ebs\_throughput](#input\_ebs\_throughput) | The throughput (in MiB/s) of the EBS volumes attached to data nodes. Valid values are between 125 and 1000. | `number` | `125` | no |
| <a name="input_ebs_volume_size"></a> [ebs\_volume\_size](#input\_ebs\_volume\_size) | The size of EBS volumes attached to data nodes (in GiB). | `number` | `10` | no |
| <a name="input_ebs_volume_type"></a> [ebs\_volume\_type](#input\_ebs\_volume\_type) | The type of EBS volumes attached to data nodes. | `string` | `"gp3"` | no |
| <a name="input_encrypt_kms_key_id"></a> [encrypt\_kms\_key\_id](#input\_encrypt\_kms\_key\_id) | The KMS key ID to encrypt the OpenSearch cluster with. If not specified, then it defaults to using the AWS OpenSearch Service KMS key. | `string` | `""` | no |
| <a name="input_hot_instance_count"></a> [hot\_instance\_count](#input\_hot\_instance\_count) | The number of dedicated hot nodes in the cluster. | `number` | `3` | no |
| <a name="input_hot_instance_type"></a> [hot\_instance\_type](#input\_hot\_instance\_type) | The type of EC2 instances to run for each hot node. A list of available instance types can you find at https://aws.amazon.com/en/opensearch-service/pricing/#On-Demand_instance_pricing | `string` | `"r6gd.4xlarge.elasticsearch"` | no |
Expand All @@ -128,14 +134,18 @@ Here is a working example of using this Terraform module:
| <a name="input_role_mapping_files"></a> [role\_mapping\_files](#input\_role\_mapping\_files) | A set of all role mapping files to create. | `set(string)` | `[]` | no |
| <a name="input_role_mappings"></a> [role\_mappings](#input\_role\_mappings) | A map of all role mappings to create. | `map(any)` | `{}` | no |
| <a name="input_roles"></a> [roles](#input\_roles) | A map of all roles to create. | `map(any)` | `{}` | no |
| <a name="input_saml_entity_id"></a> [saml\_entity\_id](#input\_saml\_entity\_id) | The unique Entity ID of the application in SAML Identity Provider. | `string` | n/a | yes |
| <a name="input_saml_enabled"></a> [saml\_enabled](#input\_saml\_enabled) | Indicates whether to configure SAML for the OpenSearch dashboard. | `bool` | `true` | no |
| <a name="input_saml_entity_id"></a> [saml\_entity\_id](#input\_saml\_entity\_id) | The unique Entity ID of the application in SAML Identity Provider. | `string` | `""` | no |
| <a name="input_saml_master_backend_role"></a> [saml\_master\_backend\_role](#input\_saml\_master\_backend\_role) | This backend role receives full permissions to the cluster, equivalent to a new master role, but can only use those permissions within Dashboards. | `string` | `null` | no |
| <a name="input_saml_master_user_name"></a> [saml\_master\_user\_name](#input\_saml\_master\_user\_name) | This username receives full permissions to the cluster, equivalent to a new master user, but can only use those permissions within Dashboards. | `string` | `null` | no |
| <a name="input_saml_metadata_content"></a> [saml\_metadata\_content](#input\_saml\_metadata\_content) | The metadata of the SAML application in xml format. | `string` | n/a | yes |
| <a name="input_saml_metadata_content"></a> [saml\_metadata\_content](#input\_saml\_metadata\_content) | The metadata of the SAML application in xml format. | `string` | `""` | no |
| <a name="input_saml_roles_key"></a> [saml\_roles\_key](#input\_saml\_roles\_key) | Element of the SAML assertion to use for backend roles. | `string` | `"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"` | no |
| <a name="input_saml_session_timeout"></a> [saml\_session\_timeout](#input\_saml\_session\_timeout) | Duration of a session in minutes after a user logs in. Default is 60. Maximum value is 1,440. | `number` | `60` | no |
| <a name="input_saml_subject_key"></a> [saml\_subject\_key](#input\_saml\_subject\_key) | Element of the SAML assertion to use for username. | `string` | `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"` | no |
| <a name="input_security_group_ids"></a> [security\_group\_ids](#input\_security\_group\_ids) | The list of VPC security groups IDs to attach. | `list(string)` | `[]` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | The list of VPC subnet IDs to use. | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no |
| <a name="input_vpc_enabled"></a> [vpc\_enabled](#input\_vpc\_enabled) | Indicates whether the cluster is running inside a VPC. | `bool` | `false` | no |
| <a name="input_warm_instance_count"></a> [warm\_instance\_count](#input\_warm\_instance\_count) | The number of dedicated warm nodes in the cluster. | `number` | `3` | no |
| <a name="input_warm_instance_enabled"></a> [warm\_instance\_enabled](#input\_warm\_instance\_enabled) | Indicates whether ultrawarm nodes are enabled for the cluster. | `bool` | `true` | no |
| <a name="input_warm_instance_type"></a> [warm\_instance\_type](#input\_warm\_instance\_type) | The type of EC2 instances to run for each warm node. A list of available instance types can you find at https://aws.amazon.com/en/elasticsearch-service/pricing/#UltraWarm_pricing | `string` | `"ultrawarm1.large.elasticsearch"` | no |
Expand Down
28 changes: 27 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
moved {
from = module.acm
to = module.acm[0]
}

module "acm" {
count = (var.custom_endpoint_certificate_arn != "") ? 0 : 1
source = "terraform-aws-modules/acm/aws"
version = "~> 4.0.1"

Expand Down Expand Up @@ -57,7 +63,7 @@ resource "aws_elasticsearch_domain" "opensearch" {

custom_endpoint_enabled = true
custom_endpoint = "${var.cluster_name}.${data.aws_route53_zone.opensearch.name}"
custom_endpoint_certificate_arn = module.acm.acm_certificate_arn
custom_endpoint_certificate_arn = (var.custom_endpoint_certificate_arn != "") ? var.custom_endpoint_certificate_arn : module.acm[0].acm_certificate_arn
}

node_to_node_encryption {
Expand All @@ -69,12 +75,32 @@ resource "aws_elasticsearch_domain" "opensearch" {
kms_key_id = var.encrypt_kms_key_id
}

dynamic "vpc_options" {
for_each = var.vpc_enabled ? [true] : []
content {
security_group_ids = var.security_group_ids
subnet_ids = var.subnet_ids
}
}

dynamic "ebs_options" {
for_each = var.ebs_enabled ? [true] : []
content {
ebs_enabled = true
volume_size = var.ebs_volume_size
volume_type = var.ebs_volume_type
throughput = var.ebs_throughput
iops = var.ebs_iops
}
}

tags = var.tags

depends_on = [aws_iam_service_linked_role.es]
}

resource "aws_elasticsearch_domain_saml_options" "opensearch" {
count = var.saml_enabled ? 1 : 0
domain_name = aws_elasticsearch_domain.opensearch.domain_name

saml_options {
Expand Down
66 changes: 64 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ variable "master_instance_type" {
default = "r6gd.large.elasticsearch"

validation {
condition = can(regex("^[m3|r3|i3|i2|r6gd]", var.master_instance_type))
condition = can(regex("^[t3|m3|r3|i3|i2|r6gd|c6g]", var.master_instance_type))
error_message = "The EC2 master_instance_type must provide a SSD or NVMe-based local storage."
}
}
Expand All @@ -56,7 +56,7 @@ variable "hot_instance_type" {
default = "r6gd.4xlarge.elasticsearch"

validation {
condition = can(regex("^[m3|r3|i3|i2|r6gd]", var.hot_instance_type))
condition = can(regex("^[t3|m3|r3|i3|i2|r6gd|c6g]", var.hot_instance_type))
error_message = "The EC2 hot_instance_type must provide a SSD or NVMe-based local storage."
}
}
Expand Down Expand Up @@ -91,12 +91,66 @@ variable "availability_zones" {
default = 3
}

variable "vpc_enabled" {
description = "Indicates whether the cluster is running inside a VPC."
type = bool
default = false
}

variable "subnet_ids" {
description = "The list of VPC subnet IDs to use."
type = list(string)
default = []
}

variable "security_group_ids" {
description = "The list of VPC security groups IDs to attach."
type = list(string)
default = []
}

variable "ebs_enabled" {
description = "Indicates whether attach EBS volumes to the data nodes."
type = bool
default = false
}

variable "ebs_volume_size" {
description = "The size of EBS volumes attached to data nodes (in GiB)."
type = number
default = 10
}

variable "ebs_volume_type" {
description = "The type of EBS volumes attached to data nodes."
type = string
default = "gp3"
}

variable "ebs_throughput" {
description = "The throughput (in MiB/s) of the EBS volumes attached to data nodes. Valid values are between 125 and 1000."
type = number
default = 125
}

variable "ebs_iops" {
description = "The baseline input/output (I/O) performance of EBS volumes attached to data nodes."
type = number
default = 3000
}

variable "encrypt_kms_key_id" {
description = "The KMS key ID to encrypt the OpenSearch cluster with. If not specified, then it defaults to using the AWS OpenSearch Service KMS key."
type = string
default = ""
}

variable "saml_enabled" {
description = "Indicates whether to configure SAML for the OpenSearch dashboard."
type = bool
default = true
}

variable "saml_subject_key" {
description = "Element of the SAML assertion to use for username."
type = string
Expand All @@ -112,11 +166,13 @@ variable "saml_roles_key" {
variable "saml_entity_id" {
description = "The unique Entity ID of the application in SAML Identity Provider."
type = string
default = ""
}

variable "saml_metadata_content" {
description = "The metadata of the SAML application in xml format."
type = string
default = ""
}

variable "saml_session_timeout" {
Expand Down Expand Up @@ -202,3 +258,9 @@ variable "tags" {
type = map(string)
default = {}
}

variable "custom_endpoint_certificate_arn" {
description = "The ARN of the custom ACM certificate."
type = string
default = ""
}

0 comments on commit ee8c8c7

Please sign in to comment.