From 9838f3b16b394b7412ac400779f95556d76a8e81 Mon Sep 17 00:00:00 2001 From: k-yomo Date: Wed, 9 Nov 2022 00:28:34 +0900 Subject: [PATCH 1/7] Implement system-user resource --- internal/clients/security.go | 47 +++++ .../elasticsearch/security/system_user.go | 165 ++++++++++++++++++ internal/models/models.go | 13 ++ provider/provider.go | 1 + 4 files changed, 226 insertions(+) create mode 100644 internal/elasticsearch/security/system_user.go diff --git a/internal/clients/security.go b/internal/clients/security.go index 8b526c447..4197f6fc0 100644 --- a/internal/clients/security.go +++ b/internal/clients/security.go @@ -75,6 +75,53 @@ func (a *ApiClient) DeleteElasticsearchUser(ctx context.Context, username string return diags } +func (a *ApiClient) EnableElasticsearchUser(ctx context.Context, username string) diag.Diagnostics { + var diags diag.Diagnostics + res, err := a.es.Security.EnableUser(username, a.es.Security.EnableUser.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + defer res.Body.Close() + if diags := utils.CheckError(res, "Unable to enable system user"); diags.HasError() { + return diags + } + return diags +} + +func (a *ApiClient) DisableElasticsearchUser(ctx context.Context, username string) diag.Diagnostics { + var diags diag.Diagnostics + res, err := a.es.Security.DisableUser(username, a.es.Security.DisableUser.WithContext(ctx)) + if err != nil { + return diag.FromErr(err) + } + defer res.Body.Close() + if diags := utils.CheckError(res, "Unable to disable system user"); diags.HasError() { + return diags + } + return diags +} + +func (a *ApiClient) ChangeElasticsearchUserPassword(ctx context.Context, username string, userPassword *models.UserPassword) diag.Diagnostics { + var diags diag.Diagnostics + userPasswordBytes, err := json.Marshal(userPassword) + if err != nil { + return diag.FromErr(err) + } + res, err := a.es.Security.ChangePassword( + bytes.NewReader(userPasswordBytes), + a.es.Security.ChangePassword.WithUsername(username), + a.es.Security.ChangePassword.WithContext(ctx), + ) + if err != nil { + return diag.FromErr(err) + } + defer res.Body.Close() + if diags := utils.CheckError(res, "Unable to change user's password"); diags.HasError() { + return diags + } + return diags +} + func (a *ApiClient) PutElasticsearchRole(ctx context.Context, role *models.Role) diag.Diagnostics { var diags diag.Diagnostics diff --git a/internal/elasticsearch/security/system_user.go b/internal/elasticsearch/security/system_user.go new file mode 100644 index 000000000..9e0883923 --- /dev/null +++ b/internal/elasticsearch/security/system_user.go @@ -0,0 +1,165 @@ +package security + +import ( + "context" + "fmt" + "regexp" + + "github.com/elastic/terraform-provider-elasticstack/internal/clients" + "github.com/elastic/terraform-provider-elasticstack/internal/models" + "github.com/elastic/terraform-provider-elasticstack/internal/utils" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func ResourceSystemUser() *schema.Resource { + userSchema := map[string]*schema.Schema{ + "id": { + Description: "Internal identifier of the resource", + Type: schema.TypeString, + Computed: true, + }, + "username": { + Description: "An identifier for the system user (see https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html).", + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 1024), + validation.StringMatch(regexp.MustCompile(`^[[:graph:]]+$`), "must contain alphanumeric characters (a-z, A-Z, 0-9), spaces, punctuation, and printable symbols in the Basic Latin (ASCII) block. Leading or trailing whitespace is not allowed"), + ), + }, + "password": { + Description: "The user’s password. Passwords must be at least 6 characters long.", + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(6, 128), + ConflictsWith: []string{"password_hash"}, + }, + "password_hash": { + Description: "A hash of the user’s password. This must be produced using the same hashing algorithm as has been configured for password storage (see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html#hashing-settings).", + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(6, 128), + ConflictsWith: []string{"password"}, + }, + "enabled": { + Description: "Specifies whether the user is enabled. The default value is true.", + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + } + + utils.AddConnectionSchema(userSchema) + + return &schema.Resource{ + Description: "Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html", + + CreateContext: resourceSecuritySystemUserPut, + UpdateContext: resourceSecuritySystemUserPut, + ReadContext: resourceSecuritySystemUserRead, + DeleteContext: resourceSecuritySystemUserDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: userSchema, + } +} + +func resourceSecuritySystemUserPut(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := clients.NewApiClient(d, meta) + if err != nil { + return diag.FromErr(err) + } + usernameId := d.Get("username").(string) + id, diags := client.ID(ctx, usernameId) + if diags.HasError() { + return diags + } + + user, diags := client.GetElasticsearchUser(ctx, usernameId) + if diags.HasError() { + return diags + } + if user == nil || !user.IsSystemUser() { + return diag.Errorf(`System user "%s" not found`, usernameId) + } + + var userPassword models.UserPassword + if v, ok := d.GetOk("password"); ok && d.HasChange("password") { + password := v.(string) + userPassword.Password = &password + } + if v, ok := d.GetOk("password_hash"); ok && d.HasChange("password_hash") { + pass_hash := v.(string) + userPassword.PasswordHash = &pass_hash + } + if userPassword.Password != nil || userPassword.PasswordHash != nil { + if diags := client.ChangeElasticsearchUserPassword(ctx, usernameId, &userPassword); diags.HasError() { + return diags + } + } + + if d.HasChange("enabled") { + if d.Get("enabled").(bool) { + if diags := client.EnableElasticsearchUser(ctx, usernameId); diags.HasError() { + return diags + } + } else { + if diags := client.DisableElasticsearchUser(ctx, usernameId); diags.HasError() { + return diags + } + } + } + + d.SetId(id.String()) + return resourceSecuritySystemUserRead(ctx, d, meta) +} + +func resourceSecuritySystemUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + var diags diag.Diagnostics + client, err := clients.NewApiClient(d, meta) + if err != nil { + return diag.FromErr(err) + } + compId, diags := clients.CompositeIdFromStr(d.Id()) + if diags.HasError() { + return diags + } + usernameId := compId.ResourceId + + user, diags := client.GetElasticsearchUser(ctx, usernameId) + if diags == nil && (user == nil || !user.IsSystemUser()) { + tflog.Warn(ctx, fmt.Sprintf(`System user "%s" not found, removing from state`, compId.ResourceId)) + d.SetId("") + return diags + } + if diags.HasError() { + return diags + } + + if err := d.Set("username", usernameId); err != nil { + return diag.FromErr(err) + } + if err := d.Set("enabled", user.Enabled); err != nil { + return diag.FromErr(err) + } + + return diags +} + +func resourceSecuritySystemUserDelete(ctx context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics { + compId, diags := clients.CompositeIdFromStr(d.Id()) + if diags.HasError() { + return diags + } + tflog.Warn(ctx, fmt.Sprintf(`System user '%s' is not deletable, just removing from state`, compId.ResourceId)) + return nil +} diff --git a/internal/models/models.go b/internal/models/models.go index 0bfbe76ba..35d65bb6f 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -11,6 +11,19 @@ type User struct { Enabled bool `json:"enabled"` } +func (u *User) IsSystemUser() bool { + if reserved := u.Metadata["_reserved"]; reserved != nil { + isReserved, ok := reserved.(bool) + return ok && isReserved + } + return false +} + +type UserPassword struct { + Password *string `json:"password,omitempty"` + PasswordHash *string `json:"password_hash,omitempty"` +} + type Role struct { Name string `json:"-"` Applications []Application `json:"applications,omitempty"` diff --git a/provider/provider.go b/provider/provider.go index 7655402d7..28a83ade4 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -135,6 +135,7 @@ func New(version string) func() *schema.Provider { "elasticstack_elasticsearch_security_role": security.ResourceRole(), "elasticstack_elasticsearch_security_role_mapping": security.ResourceRoleMapping(), "elasticstack_elasticsearch_security_user": security.ResourceUser(), + "elasticstack_elasticsearch_security_system_user": security.ResourceSystemUser(), "elasticstack_elasticsearch_snapshot_lifecycle": cluster.ResourceSlm(), "elasticstack_elasticsearch_snapshot_repository": cluster.ResourceSnapshotRepository(), "elasticstack_elasticsearch_script": cluster.ResourceScript(), From 7ac237ffe92151aaffff7bb89a224c5db7b8f6fa Mon Sep 17 00:00:00 2001 From: k-yomo Date: Mon, 14 Nov 2022 16:44:05 +0900 Subject: [PATCH 2/7] Add tests for system-user resource --- .../security/system_user_test.go | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 internal/elasticsearch/security/system_user_test.go diff --git a/internal/elasticsearch/security/system_user_test.go b/internal/elasticsearch/security/system_user_test.go new file mode 100644 index 000000000..de5e06e75 --- /dev/null +++ b/internal/elasticsearch/security/system_user_test.go @@ -0,0 +1,77 @@ +package security_test + +import ( + "regexp" + "testing" + + "github.com/elastic/terraform-provider-elasticstack/internal/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccResourceSecuritySystemUser(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccResourceSecuritySystemUserCreate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_system_user.kibana_system", "username", "kibana_system"), + resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_system_user.kibana_system", "enabled", "true"), + ), + }, + { + Config: testAccResourceSecuritySystemUserUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_system_user.kibana_system", "username", "kibana_system"), + resource.TestCheckResourceAttr("elasticstack_elasticsearch_security_system_user.kibana_system", "enabled", "false"), + ), + }, + }, + }) +} + +func TestAccResourceSecuritySystemUserNotFound(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProviderFactories: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccResourceSecuritySystemUserNotFound, + ExpectError: regexp.MustCompile(`System user "not_system_user" not found`), + }, + }, + }) +} + +const testAccResourceSecuritySystemUserCreate = ` +provider "elasticstack" { + elasticsearch {} +} + +resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { + username = "kibana_system" + password = "new_password" +} + ` +const testAccResourceSecuritySystemUserUpdate = ` +provider "elasticstack" { + elasticsearch {} +} + +resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { + username = "kibana_system" + password = "new_password" + enabled = false +} + ` +const testAccResourceSecuritySystemUserNotFound = ` +provider "elasticstack" { + elasticsearch {} +} + +resource "elasticstack_elasticsearch_security_system_user" "test" { + username = "not_system_user" + password = "new_password" +} + ` From 59256e1cfc2c26d0576809afe15ee4f696e23ebc Mon Sep 17 00:00:00 2001 From: k-yomo Date: Mon, 14 Nov 2022 16:49:04 +0900 Subject: [PATCH 3/7] Add examples and generate doc for system-user resource --- .../elasticsearch_security_system_user.md | 71 +++++++++++++++++++ .../import.sh | 1 + .../resource.tf | 16 +++++ ...elasticsearch_security_system_user.md.tmpl | 23 ++++++ 4 files changed, 111 insertions(+) create mode 100644 docs/resources/elasticsearch_security_system_user.md create mode 100644 examples/resources/elasticstack_elasticsearch_security_system_user/import.sh create mode 100644 examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf create mode 100644 templates/resources/elasticsearch_security_system_user.md.tmpl diff --git a/docs/resources/elasticsearch_security_system_user.md b/docs/resources/elasticsearch_security_system_user.md new file mode 100644 index 000000000..933c663f0 --- /dev/null +++ b/docs/resources/elasticsearch_security_system_user.md @@ -0,0 +1,71 @@ +--- +subcategory: "Security" +layout: "" +page_title: "Elasticstack: elasticstack_elasticsearch_security_system_user Resource" +description: |- + Updates system user's password and enablement. +--- + +# Resource: elasticstack_elasticsearch_security_system_user + +Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html + +## Example Usage + +```terraform +provider "elasticstack" { + elasticsearch {} +} + +resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { + username = "kibana_system" + + // use hashed password: see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-request-body + password_hash = "$2a$10$rMZe6TdsUwBX/TA8vRDz0OLwKAZeCzXM4jT3tfCjpSTB8HoFuq8xO" + + elasticsearch_connection { + endpoints = ["http://localhost:9200"] + username = "elastic" + password = "changeme" + } +} +``` + + +## Schema + +### Required + +- `username` (String) An identifier for the system user (see https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html). + +### Optional + +- `elasticsearch_connection` (Block List, Max: 1) Used to establish connection to Elasticsearch server. Overrides environment variables if present. (see [below for nested schema](#nestedblock--elasticsearch_connection)) +- `enabled` (Boolean) Specifies whether the user is enabled. The default value is true. +- `password` (String, Sensitive) The user’s password. Passwords must be at least 6 characters long. +- `password_hash` (String, Sensitive) A hash of the user’s password. This must be produced using the same hashing algorithm as has been configured for password storage (see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html#hashing-settings). + +### Read-Only + +- `id` (String) Internal identifier of the resource + + +### Nested Schema for `elasticsearch_connection` + +Optional: + +- `api_key` (String, Sensitive) API Key to use for authentication to Elasticsearch +- `ca_data` (String) PEM-encoded custom Certificate Authority certificate +- `ca_file` (String) Path to a custom Certificate Authority certificate +- `endpoints` (List of String, Sensitive) A list of endpoints the Terraform provider will point to. They must include the http(s) schema and port number. +- `insecure` (Boolean) Disable TLS certificate validation +- `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. +- `username` (String) A username to use for API authentication to Elasticsearch. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import elasticstack_elasticsearch_security_system_user.kibana_system /kibana_system +``` diff --git a/examples/resources/elasticstack_elasticsearch_security_system_user/import.sh b/examples/resources/elasticstack_elasticsearch_security_system_user/import.sh new file mode 100644 index 000000000..0d9262877 --- /dev/null +++ b/examples/resources/elasticstack_elasticsearch_security_system_user/import.sh @@ -0,0 +1 @@ +terraform import elasticstack_elasticsearch_security_system_user.kibana_system /kibana_system diff --git a/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf b/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf new file mode 100644 index 000000000..7a4062e3b --- /dev/null +++ b/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf @@ -0,0 +1,16 @@ +provider "elasticstack" { + elasticsearch {} +} + +resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { + username = "kibana_system" + + // use hashed password: see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-request-body + password_hash = "$2a$10$rMZe6TdsUwBX/TA8vRDz0OLwKAZeCzXM4jT3tfCjpSTB8HoFuq8xO" + + elasticsearch_connection { + endpoints = ["http://localhost:9200"] + username = "elastic" + password = "changeme" + } +} diff --git a/templates/resources/elasticsearch_security_system_user.md.tmpl b/templates/resources/elasticsearch_security_system_user.md.tmpl new file mode 100644 index 000000000..12af97e53 --- /dev/null +++ b/templates/resources/elasticsearch_security_system_user.md.tmpl @@ -0,0 +1,23 @@ +--- +subcategory: "Security" +layout: "" +page_title: "Elasticstack: elasticstack_elasticsearch_security_system_user Resource" +description: |- + Updates system user's password and enablement. +--- + +# Resource: elasticstack_elasticsearch_security_system_user + +Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html + +## Example Usage + +{{ tffile "examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf" }} + +{{ .SchemaMarkdown | trimspace }} + +## Import + +Import is supported using the following syntax: + +{{ codefile "shell" "examples/resources/elasticstack_elasticsearch_security_system_user/import.sh" }} From a641bcd07ecf8a5c55f7eeef95bb52e023ce4379 Mon Sep 17 00:00:00 2001 From: k-yomo Date: Mon, 21 Nov 2022 17:37:25 +0900 Subject: [PATCH 4/7] Fix to make system-user not importable --- docs/resources/elasticsearch_security_system_user.md | 11 ++--------- .../import.sh | 1 - .../resource.tf | 2 +- internal/elasticsearch/security/system_user.go | 4 ---- .../elasticsearch_security_system_user.md.tmpl | 7 +------ 5 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 examples/resources/elasticstack_elasticsearch_security_system_user/import.sh diff --git a/docs/resources/elasticsearch_security_system_user.md b/docs/resources/elasticsearch_security_system_user.md index 933c663f0..6e8fbf89d 100644 --- a/docs/resources/elasticsearch_security_system_user.md +++ b/docs/resources/elasticsearch_security_system_user.md @@ -9,6 +9,7 @@ description: |- # Resource: elasticstack_elasticsearch_security_system_user Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html +Since this resource is to manage undeletable built-in user, destroy will removes it only from terraform state and the user itself won't be deleted. ## Example Usage @@ -20,7 +21,7 @@ provider "elasticstack" { resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { username = "kibana_system" - // use hashed password: see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-request-body + // For details on how to generate the hashed password see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-request-body password_hash = "$2a$10$rMZe6TdsUwBX/TA8vRDz0OLwKAZeCzXM4jT3tfCjpSTB8HoFuq8xO" elasticsearch_connection { @@ -61,11 +62,3 @@ Optional: - `insecure` (Boolean) Disable TLS certificate validation - `password` (String, Sensitive) A password to use for API authentication to Elasticsearch. - `username` (String) A username to use for API authentication to Elasticsearch. - -## Import - -Import is supported using the following syntax: - -```shell -terraform import elasticstack_elasticsearch_security_system_user.kibana_system /kibana_system -``` diff --git a/examples/resources/elasticstack_elasticsearch_security_system_user/import.sh b/examples/resources/elasticstack_elasticsearch_security_system_user/import.sh deleted file mode 100644 index 0d9262877..000000000 --- a/examples/resources/elasticstack_elasticsearch_security_system_user/import.sh +++ /dev/null @@ -1 +0,0 @@ -terraform import elasticstack_elasticsearch_security_system_user.kibana_system /kibana_system diff --git a/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf b/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf index 7a4062e3b..e3578a117 100644 --- a/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf +++ b/examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf @@ -5,7 +5,7 @@ provider "elasticstack" { resource "elasticstack_elasticsearch_security_system_user" "kibana_system" { username = "kibana_system" - // use hashed password: see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-request-body + // For details on how to generate the hashed password see https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-request-body password_hash = "$2a$10$rMZe6TdsUwBX/TA8vRDz0OLwKAZeCzXM4jT3tfCjpSTB8HoFuq8xO" elasticsearch_connection { diff --git a/internal/elasticsearch/security/system_user.go b/internal/elasticsearch/security/system_user.go index 9e0883923..29514c883 100644 --- a/internal/elasticsearch/security/system_user.go +++ b/internal/elasticsearch/security/system_user.go @@ -65,10 +65,6 @@ func ResourceSystemUser() *schema.Resource { ReadContext: resourceSecuritySystemUserRead, DeleteContext: resourceSecuritySystemUserDelete, - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - Schema: userSchema, } } diff --git a/templates/resources/elasticsearch_security_system_user.md.tmpl b/templates/resources/elasticsearch_security_system_user.md.tmpl index 12af97e53..ac10a9fdb 100644 --- a/templates/resources/elasticsearch_security_system_user.md.tmpl +++ b/templates/resources/elasticsearch_security_system_user.md.tmpl @@ -9,15 +9,10 @@ description: |- # Resource: elasticstack_elasticsearch_security_system_user Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html +Since this resource is to manage undeletable built-in user, destroy will removes it only from terraform state and the user itself won't be deleted. ## Example Usage {{ tffile "examples/resources/elasticstack_elasticsearch_security_system_user/resource.tf" }} {{ .SchemaMarkdown | trimspace }} - -## Import - -Import is supported using the following syntax: - -{{ codefile "shell" "examples/resources/elasticstack_elasticsearch_security_system_user/import.sh" }} From 43a5cfffd95c30976ea05031984b0820fb653d2c Mon Sep 17 00:00:00 2001 From: k-yomo Date: Mon, 21 Nov 2022 17:40:19 +0900 Subject: [PATCH 5/7] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1aabc775..2621479ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Add `elasticstack_elasticsearch_security_role_mapping` data source ([#178](https://github.com/elastic/terraform-provider-elasticstack/pull/178)) - Apply `total_shards_per_node` setting in `allocate` action in ILM. Supported from Elasticsearch version **7.16** ([#112](https://github.com/elastic/terraform-provider-elasticstack/issues/112)) - Add `elasticstack_elasticsearch_security_api_key` resource ([#193](https://github.com/elastic/terraform-provider-elasticstack/pull/193)) +- Add `elasticstack_elasticsearch_security_system_user` resource to manage built-in user ([#188](https://github.com/elastic/terraform-provider-elasticstack/pull/188)) ### Fixed - Remove unnecessary unsetting id on delete ([#174](https://github.com/elastic/terraform-provider-elasticstack/pull/174)) From 6f9dfd4a6a4cbc1b63847c3ff6567955cc137f8a Mon Sep 17 00:00:00 2001 From: Kanji Yomoda Date: Mon, 21 Nov 2022 19:25:03 +0900 Subject: [PATCH 6/7] Update docs/resources/elasticsearch_security_system_user.md Co-authored-by: Toby Brain --- docs/resources/elasticsearch_security_system_user.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources/elasticsearch_security_system_user.md b/docs/resources/elasticsearch_security_system_user.md index 6e8fbf89d..6e57ad466 100644 --- a/docs/resources/elasticsearch_security_system_user.md +++ b/docs/resources/elasticsearch_security_system_user.md @@ -9,7 +9,7 @@ description: |- # Resource: elasticstack_elasticsearch_security_system_user Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html -Since this resource is to manage undeletable built-in user, destroy will removes it only from terraform state and the user itself won't be deleted. +Since this resource is to manage built-in users, destroy will not delete the underlying Elasticsearch and will only remove it from Terraform state. ## Example Usage From 13e0364de1c5a444fdb06e0d2a6f94cb5de18902 Mon Sep 17 00:00:00 2001 From: Kanji Yomoda Date: Mon, 21 Nov 2022 19:25:20 +0900 Subject: [PATCH 7/7] Update templates/resources/elasticsearch_security_system_user.md.tmpl Co-authored-by: Toby Brain --- templates/resources/elasticsearch_security_system_user.md.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/resources/elasticsearch_security_system_user.md.tmpl b/templates/resources/elasticsearch_security_system_user.md.tmpl index ac10a9fdb..ca2fa49b9 100644 --- a/templates/resources/elasticsearch_security_system_user.md.tmpl +++ b/templates/resources/elasticsearch_security_system_user.md.tmpl @@ -9,7 +9,7 @@ description: |- # Resource: elasticstack_elasticsearch_security_system_user Updates system user's password and enablement. See, https://www.elastic.co/guide/en/elasticsearch/reference/current/built-in-users.html -Since this resource is to manage undeletable built-in user, destroy will removes it only from terraform state and the user itself won't be deleted. +Since this resource is to manage built-in users, destroy will not delete the underlying Elasticsearch and will only remove it from Terraform state. ## Example Usage