Skip to content

Commit ae3deed

Browse files
kbatuigasclaudeFeediver1
authored
DOC-1928: Document write-only attributes for Terraform provider (#566)
* DOC-1928: Document write-only attributes for Terraform provider Adds guidance for the password_wo / password_wo_version pattern shipped in provider v1.6.0 (PR #303) and updates Schema Registry HCL examples to use the write-only variants. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add to What's New in Cloud * Apply suggestions from code review Co-authored-by: Joyce Fee <102751339+Feediver1@users.noreply.github.com> * Apply suggestions from doc review * Document precedence when both password and password_wo are set Per gene-redpanda: if both the plaintext attribute and its write-only counterpart are set on the same resource, the provider uses the write-only value. Users should avoid setting both. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Joyce Fee <102751339+Feediver1@users.noreply.github.com>
1 parent e0361ca commit ae3deed

2 files changed

Lines changed: 128 additions & 27 deletions

File tree

modules/get-started/pages/whats-new-cloud.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ Remote MCP has been deprecated and removed from Redpanda Cloud.
3737

3838
Serverless clusters now support up to 100 Redpanda Connect pipelines and MCP servers. See xref:get-started:cluster-types/serverless.adoc#_serverless_usage_limits[Serverless usage limits].
3939

40+
=== Terraform provider: Write-only attributes for sensitive fields
41+
42+
The Redpanda Terraform provider (v1.6.0+) now supports https://developer.hashicorp.com/terraform/plugin/framework/resources/write-only-arguments[Terraform 1.11+ write-only attributes^] for sensitive fields such as user passwords and pipeline client secrets. Use the new `password_wo` and `password_wo_version` attributes (and equivalents for other sensitive fields) to keep credentials out of your `.tfstate` file. See xref:manage:terraform-provider.adoc#manage-sensitive-attributes-with-write-only-fields[Manage sensitive attributes with write-only fields].
43+
4044
=== Redpanda Connect updates
4145

4246
* The Redpanda Connect pipeline creation and editing workflow has been simplified. The new UI replaces the previous multi-page wizard with a visual pipeline diagram, an IDE-like configuration editor, slash commands for inserting variables, and inline links to component documentation. See the xref:develop:connect/connect-quickstart.adoc[Redpanda Connect quickstart] to try it out.

modules/manage/pages/terraform-provider.adoc

Lines changed: 124 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,101 @@ provider "redpanda" {
199199
--
200200
======
201201

202+
== Manage sensitive attributes with write-only fields
203+
204+
You can use https://developer.hashicorp.com/terraform/plugin/framework/resources/write-only-arguments[Terraform 1.11+ write-only attributes^] to keep sensitive values out of your Terraform state file. By default, Terraform persists sensitive attributes such as passwords to `.tfstate` when you run `terraform apply`. When you store state in a remote backend or in CI runner artifacts, this can leak credentials.
205+
206+
[IMPORTANT]
207+
====
208+
Write-only attributes require Terraform CLI 1.11 or later and Redpanda Terraform provider v1.6.0 or later.
209+
====
210+
211+
=== How write-only attributes work
212+
213+
For each supported sensitive field, the provider exposes two new attributes alongside the existing one:
214+
215+
* `<field>_wo`: A write-only attribute. Terraform sends the value to the provider during `apply` but never persists it to state.
216+
* `<field>_wo_version`: An integer version. Because Terraform cannot detect changes in a write-only value (there is nothing to compare against in state), you increment this number to signal that the value has changed and to trigger an update on the next apply.
217+
218+
NOTE: `redpanda_pipeline` is an exception to this naming convention. The existing `client_secret` attribute is the write-only attribute (no separate `client_secret_wo` field), and is paired with `secret_version` instead of `client_secret_wo_version`.
219+
220+
The provider retains the original plaintext attributes for backward compatibility. You can migrate to the write-only variants on your own schedule. Avoid setting both the plaintext attribute and its write-only counterpart on the same resource. If both are set, the provider uses the write-only value.
221+
222+
=== Supported attributes
223+
224+
|===
225+
| Resource | Plaintext attribute (deprecated) | Write-only attribute | Version attribute
226+
227+
| `redpanda_user`
228+
| `password`
229+
| `password_wo`
230+
| `password_wo_version`
231+
232+
| `redpanda_schema`
233+
| `password`
234+
| `password_wo`
235+
| `password_wo_version`
236+
237+
| `redpanda_schema_registry_acl`
238+
| `password`
239+
| `password_wo`
240+
| `password_wo_version`
241+
242+
| `redpanda_pipeline`
243+
| `client_secret`
244+
| `client_secret` (write-only)
245+
| `secret_version`
246+
|===
247+
248+
=== Set a write-only attribute
249+
250+
Inject the sensitive value through a sensitive Terraform variable, an environment variable, or your secrets manager. The following example uses a `TF_VAR_` environment variable to populate `var.schema_password`:
251+
252+
[source,hcl]
253+
----
254+
variable "schema_password" {
255+
description = "Password for the Schema Registry user"
256+
sensitive = true
257+
}
258+
259+
resource "redpanda_user" "schema_user" {
260+
name = "schema-user"
261+
password_wo = var.schema_password
262+
password_wo_version = 1
263+
mechanism = "scram-sha-256"
264+
cluster_api_url = data.redpanda_cluster.byoc.cluster_api_url
265+
allow_deletion = true
266+
}
267+
----
268+
269+
Set the variable before running Terraform:
270+
271+
[source,bash]
272+
----
273+
export TF_VAR_schema_password="your-secret-password"
274+
terraform apply
275+
----
276+
277+
Terraform sends the value to Redpanda Cloud during `apply` but never writes it to `.tfstate`.
278+
279+
=== Rotate a write-only attribute
280+
281+
Because Terraform cannot detect a change in the write-only value itself, increment the corresponding `_wo_version` to trigger an update:
282+
283+
[source,hcl]
284+
----
285+
resource "redpanda_user" "schema_user" {
286+
name = "schema-user"
287+
password_wo = var.schema_password # Set TF_VAR_schema_password to the new value
288+
password_wo_version = 2 # Increment from 1 to trigger update
289+
mechanism = "scram-sha-256"
290+
cluster_api_url = data.redpanda_cluster.byoc.cluster_api_url
291+
allow_deletion = true
292+
}
293+
----
294+
295+
After running `terraform apply`, the provider sends the new password to Redpanda Cloud. Neither the old nor the new value is written to state.
296+
202297
== Examples
203298

204299
This section provides examples of using the Redpanda Terraform provider to create and manage clusters. For descriptions of resources and data sources, see the https://registry.terraform.io/providers/redpanda-data/redpanda/latest/docs[Redpanda Terraform Provider documentation^].
@@ -486,11 +581,12 @@ data "redpanda_cluster" "byoc" {
486581
}
487582
488583
resource "redpanda_user" "schema_user" {
489-
name = "schema-user"
490-
password = var.schema_password
491-
mechanism = "scram-sha-256"
492-
cluster_api_url = data.redpanda_cluster.byoc.cluster_api_url
493-
allow_deletion = true
584+
name = "schema-user"
585+
password_wo = var.schema_password
586+
password_wo_version = 1
587+
mechanism = "scram-sha-256"
588+
cluster_api_url = data.redpanda_cluster.byoc.cluster_api_url
589+
allow_deletion = true
494590
}
495591
496592
resource "redpanda_schema" "user_events" {
@@ -508,8 +604,9 @@ resource "redpanda_schema" "user_events" {
508604
]
509605
})
510606
511-
username = redpanda_user.schema_user.name
512-
password = var.schema_password
607+
username = redpanda_user.schema_user.name
608+
password_wo = var.schema_password
609+
password_wo_version = 1
513610
}
514611
----
515612

@@ -519,21 +616,21 @@ In this example:
519616
* `subject` defines the logical name under which schema versions are registered.
520617
* `schema_type` specifies the serialization type (`AVRO`, `JSON`, or `PROTOBUF`).
521618
* `schema` provides the full schema definition, encoded with `jsonencode()`.
522-
* `username` and `password` authenticate the user to the Schema Registry.
619+
* `username` identifies the Schema Registry user. Set `password_wo` to the password value, and increment `password_wo_version` to trigger updates. For details, see <<manage-sensitive-attributes-with-write-only-fields>>.
523620

524621
==== Store credentials securely
525622

526-
Store credentials using environment variables or sensitive Terraform variables.
623+
Use Terraform 1.11+ write-only attributes (such as `password_wo`) to keep Schema Registry credentials out of your `.tfstate` file. For details, see <<manage-sensitive-attributes-with-write-only-fields>>.
527624

528-
For short-lived credentials or CI/CD usage, use provider-level environment variables:
625+
For short-lived credentials or CI/CD usage, you can also export the Schema Registry credentials as provider-level environment variables. The provider reads them automatically:
529626

530627
[source,bash]
531628
----
532629
export REDPANDA_SR_USERNAME=schema-user
533630
export REDPANDA_SR_PASSWORD="your-secret-password"
534631
----
535632

536-
Or, declare a sensitive Terraform variable and inject it at runtime:
633+
If you must use the deprecated plaintext `password` attribute (for example, on Terraform versions earlier than 1.11), declare a sensitive Terraform variable and inject the value at runtime to avoid committing secrets to source control:
537634

538635
[source,hcl]
539636
----
@@ -543,15 +640,11 @@ variable "schema_password" {
543640
}
544641
----
545642

546-
Then, set the value securely using an environment variable before running Terraform:
547-
548643
[source,bash]
549644
----
550645
export TF_VAR_schema_password="your-secret-password"
551646
----
552647

553-
This avoids committing secrets to source control.
554-
555648
==== Manage Schema Registry ACLs
556649

557650
The `redpanda_schema_registry_acl` resource configures fine-grained access control for Schema Registry subjects or registry-wide operations. Each ACL specifies which principal can perform specific operations on a subject or the registry.
@@ -567,8 +660,9 @@ resource "redpanda_schema_registry_acl" "allow_user_read" {
567660
host = "*"
568661
operation = "READ" # READ, WRITE, DELETE, DESCRIBE, etc.
569662
permission = "ALLOW" # ALLOW or DENY
570-
username = redpanda_user.schema_user.name
571-
password = var.schema_password
663+
username = redpanda_user.schema_user.name
664+
password_wo = var.schema_password
665+
password_wo_version = 1
572666
}
573667
----
574668

@@ -582,7 +676,7 @@ In this example:
582676
* `operation` defines the permitted action (`READ`, `WRITE`, `DELETE`, etc.).
583677
* `permission` defines whether the operation is allowed or denied.
584678
* `host` specifies the host filter (typically `"*"` for all hosts).
585-
* `username` and `password` authenticate the principal to the Schema Registry.
679+
* `username` identifies the Schema Registry principal. Set `password_wo` to the password value, and increment `password_wo_version` to trigger updates. For details, see <<manage-sensitive-attributes-with-write-only-fields>>.
586680

587681
TIP: To manage Schema Registry ACLs, the user must have cluster-level `ALTER` permissions. This is typically granted through a Kafka ACL with `ALTER` on the `CLUSTER` resource.
588682

@@ -597,11 +691,12 @@ data "redpanda_cluster" "byoc" {
597691
}
598692
599693
resource "redpanda_user" "schema_user" {
600-
name = "schema-user"
601-
password = var.schema_password
602-
mechanism = "scram-sha-256"
603-
cluster_api_url = data.redpanda_cluster.byoc.cluster_api_url
604-
allow_deletion = true
694+
name = "schema-user"
695+
password_wo = var.schema_password
696+
password_wo_version = 1
697+
mechanism = "scram-sha-256"
698+
cluster_api_url = data.redpanda_cluster.byoc.cluster_api_url
699+
allow_deletion = true
605700
}
606701
607702
resource "redpanda_schema" "user_events" {
@@ -619,8 +714,9 @@ resource "redpanda_schema" "user_events" {
619714
]
620715
})
621716
622-
username = redpanda_user.schema_user.name
623-
password = var.schema_password
717+
username = redpanda_user.schema_user.name
718+
password_wo = var.schema_password
719+
password_wo_version = 1
624720
}
625721
626722
resource "redpanda_schema_registry_acl" "user_events_acl" {
@@ -632,8 +728,9 @@ resource "redpanda_schema_registry_acl" "user_events_acl" {
632728
host = "*"
633729
operation = "READ"
634730
permission = "ALLOW"
635-
username = redpanda_user.schema_user.name
636-
password = var.schema_password
731+
username = redpanda_user.schema_user.name
732+
password_wo = var.schema_password
733+
password_wo_version = 1
637734
}
638735
----
639736

0 commit comments

Comments
 (0)