Skip to content

Commit 1cf0c76

Browse files
Copilottobio
andauthored
Add write-only password support to elasticsearch_security_user resource (#1419)
* Initial plan * Migrate elasticsearch_security_user from SDKv2 to Plugin Framework Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * Add write-only password attributes (password_wo and password_wo_version) Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * Address code review feedback: simplify validators and fix unused variable Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * Address PR review feedback: use built-in validators, add type assertions, fix password_wo version logic Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * Update PutUser and DeleteUser to return Framework diagnostics directly Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * Read password_wo from config instead of plan for write-only attributes Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * Fix Go formatting (remove trailing whitespace) Co-authored-by: tobio <444668+tobio@users.noreply.github.com> * PR feedback * Remove ephemeral random password * PR feedback --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tobio <444668+tobio@users.noreply.github.com> Co-authored-by: Toby Brain <toby.brain@elastic.co>
1 parent c8c0ca8 commit 1cf0c76

File tree

21 files changed

+736
-301
lines changed

21 files changed

+736
-301
lines changed

docs/resources/elasticsearch_security_user.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
page_title: "elasticstack_elasticsearch_security_user Resource - terraform-provider-elasticstack"
44
subcategory: "Security"
55
description: |-
6-
Adds and updates users in the native realm. These users are commonly referred to as native users. See the security user API documentation https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html for more details.
6+
Adds and updates users in the native realm. These users are commonly referred to as native users. See the Elasticsearch security user API documentation https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html for more details.
77
---
88

99
# elasticstack_elasticsearch_security_user (Resource)
1010

11-
Adds and updates users in the native realm. These users are commonly referred to as native users. See the [security user API documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html) for more details.
11+
Adds and updates users in the native realm. These users are commonly referred to as native users. See the [Elasticsearch security user API documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html) for more details.
1212

1313
## Example Usage
1414

@@ -58,18 +58,22 @@ resource "elasticstack_elasticsearch_security_user" "dev" {
5858

5959
### Required
6060

61-
- `roles` (Set of String) A set of roles the user has. The roles determine the users access permissions. Default is [].
62-
- `username` (String) An identifier for the user see the [security API put user documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-path-params) for more details.
61+
- `roles` (Set of String) A set of roles the user has. The roles determine the user's access permissions.
62+
- `username` (String) An identifier for the user (see the [security API put user documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html#security-api-put-user-path-params) for more details).
6363

6464
### Optional
6565

66-
- `elasticsearch_connection` (Block List, Max: 1, Deprecated) Elasticsearch connection configuration block. This property will be removed in a future provider version. Configure the Elasticsearch connection via the provider configuration instead. (see [below for nested schema](#nestedblock--elasticsearch_connection))
66+
> **NOTE**: [Write-only arguments](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments) are supported in Terraform 1.11 and later.
67+
68+
- `elasticsearch_connection` (Block List, Deprecated) Elasticsearch connection configuration block. (see [below for nested schema](#nestedblock--elasticsearch_connection))
6769
- `email` (String) The email of the user.
6870
- `enabled` (Boolean) Specifies whether the user is enabled. The default value is true.
6971
- `full_name` (String) The full name of the user.
7072
- `metadata` (String) Arbitrary metadata that you want to associate with the user.
71-
- `password` (String, Sensitive) The user’s password. Passwords must be at least 6 characters long.
72-
- `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).
73+
- `password` (String, Sensitive) The user's password. Passwords must be at least 6 characters long. Note: Consider using `password_wo` for better security with ephemeral resources.
74+
- `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 the [security settings documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html#hashing-settings)).
75+
- `password_wo` (String, Sensitive, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) Write-only password attribute for use with ephemeral resources. Passwords must be at least 6 characters long. This attribute is designed for use with ephemeral resources like `vault_kv_secret_v2` to prevent secrets from being stored in the Terraform state. Must be used with `password_wo_version`.
76+
- `password_wo_version` (String) Version identifier for the write-only password. This field is used to trigger updates when the password changes. Required when `password_wo` is set. Typically, you would use a hash of the password or a version identifier from your secret management system.
7377

7478
### Read-Only
7579

internal/clients/elasticsearch/security.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@ import (
1414
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1515
)
1616

17-
func PutUser(ctx context.Context, apiClient *clients.ApiClient, user *models.User) diag.Diagnostics {
18-
var diags diag.Diagnostics
17+
func PutUser(ctx context.Context, apiClient *clients.ApiClient, user *models.User) fwdiag.Diagnostics {
18+
var diags fwdiag.Diagnostics
1919
userBytes, err := json.Marshal(user)
2020
if err != nil {
21-
return diag.FromErr(err)
21+
diags.AddError("Unable to marshal user", err.Error())
22+
return diags
2223
}
2324
esClient, err := apiClient.GetESClient()
2425
if err != nil {
25-
return diag.FromErr(err)
26+
diags.AddError("Unable to get Elasticsearch client", err.Error())
27+
return diags
2628
}
2729
res, err := esClient.Security.PutUser(user.Username, bytes.NewReader(userBytes), esClient.Security.PutUser.WithContext(ctx))
2830
if err != nil {
29-
return diag.FromErr(err)
31+
diags.AddError("Unable to create or update user", err.Error())
32+
return diags
3033
}
3134
defer res.Body.Close()
32-
if diags := diagutil.CheckError(res, "Unable to create or update a user"); diags.HasError() {
33-
return diags
35+
if fwDiags := diagutil.CheckErrorFromFW(res, "Unable to create or update a user"); fwDiags.HasError() {
36+
return fwDiags
3437
}
3538
return diags
3639
}
@@ -72,19 +75,21 @@ func GetUser(ctx context.Context, apiClient *clients.ApiClient, username string)
7275
return nil, diags
7376
}
7477

75-
func DeleteUser(ctx context.Context, apiClient *clients.ApiClient, username string) diag.Diagnostics {
76-
var diags diag.Diagnostics
78+
func DeleteUser(ctx context.Context, apiClient *clients.ApiClient, username string) fwdiag.Diagnostics {
79+
var diags fwdiag.Diagnostics
7780
esClient, err := apiClient.GetESClient()
7881
if err != nil {
79-
return diag.FromErr(err)
82+
diags.AddError("Unable to get Elasticsearch client", err.Error())
83+
return diags
8084
}
8185
res, err := esClient.Security.DeleteUser(username, esClient.Security.DeleteUser.WithContext(ctx))
8286
if err != nil {
83-
return diag.FromErr(err)
87+
diags.AddError("Unable to delete user", err.Error())
88+
return diags
8489
}
8590
defer res.Body.Close()
86-
if diags := diagutil.CheckError(res, "Unable to delete a user"); diags.HasError() {
87-
return diags
91+
if fwDiags := diagutil.CheckErrorFromFW(res, "Unable to delete a user"); fwDiags.HasError() {
92+
return fwDiags
8893
}
8994
return diags
9095
}

internal/elasticsearch/security/user.go

Lines changed: 0 additions & 227 deletions
This file was deleted.

0 commit comments

Comments
 (0)