Skip to content

Commit 7ed3cef

Browse files
committed
chore: implement review suggestions
1 parent 3a0b105 commit 7ed3cef

File tree

9 files changed

+111
-73
lines changed

9 files changed

+111
-73
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
data "ovh_okms_secret" "latest" {
2+
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
path = "app/api_credentials"
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
data "ovh_okms_secret" "v3" {
2+
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
path = "app/api_credentials"
4+
version = 3
5+
include_data = true
6+
}

examples/resources/okms_secret/example_1.tf

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,21 @@ resource "ovh_okms_secret" "example" {
22
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
33
path = "app/api_credentials"
44

5-
# Check‑and‑set parameter used only on update (if `cas_required` metadata is set to true)
6-
# to enforce optimistic concurrency control: its value must equal the current secret version (`metadata.current_version`)
7-
# for the update to succeed. Ignored on create.
8-
cas = 1
9-
105
metadata = {
116
max_versions = 10 # keep last 10 versions
127
cas_required = true # enforce optimistic concurrency control (server will require current secret version on the cas attribute to allow update)
138
deactivate_version_after = "0s" # keep versions active indefinitely (example)
149
custom_metadata = {
1510
environment = "prod"
16-
appname = "helloworld"
11+
owner = "payments-team"
1712
}
1813
}
1914

2015
# Initial version (will create version 1)
2116
version = {
2217
data = jsonencode({
23-
api_key = "mykey"
24-
api_secret = "mysecret"
18+
api_key = var.api_key
19+
api_secret = var.api_secret
2520
})
2621
}
2722
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
resource "ovh_okms_secret" "example" {
2+
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
3+
path = "app/api_credentials"
4+
5+
# Ensure no concurrent update happened: set cas to the current version
6+
# (metadata.current_version is populated after first apply)
7+
cas = ovh_okms_secret.example.metadata.current_version
8+
9+
metadata = {
10+
cas_required = true
11+
}
12+
13+
version = {
14+
data = jsonencode({
15+
api_key = var.api_key
16+
api_secret = var.new_api_secret # changed value -> creates new version
17+
})
18+
}
19+
}

ovh/data_okms_secret.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func (d *okmsSecretDataSource) Read(ctx context.Context, req datasource.ReadRequ
5656

5757
base := "/v2/okms/resource/" + url.PathEscape(configModel.OkmsId.ValueString()) + "/secret/" + url.PathEscape(configModel.Path.ValueString())
5858
versionProvided := !configModel.Version.IsNull() && !configModel.Version.IsUnknown() && configModel.Version.ValueInt64() > 0
59-
includeDataRequested := !configModel.IncludeData.IsNull() && !configModel.IncludeData.IsUnknown() && configModel.IncludeData.ValueBool()
59+
includeDataRequested := configModel.IncludeData.ValueBool()
6060

6161
metaEndpoint := base
6262
if !versionProvided { // only add includeData for latest case; version endpoint handled separately

ovh/resource_okms_secret.go

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"net/url"
88

99
"github.com/hashicorp/terraform-plugin-framework/resource"
10-
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
11-
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1210
ovhtypes "github.com/ovh/terraform-provider-ovh/v2/ovh/types"
1311
)
1412

@@ -44,19 +42,7 @@ func (d *okmsSecretResource) Configure(_ context.Context, req resource.Configure
4442
}
4543

4644
func (d *okmsSecretResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
47-
s := OkmsSecretResourceSchema(ctx)
48-
49-
// Ensure changes to identifying attributes force recreation instead of in-place update.
50-
if attr, ok := s.Attributes["okms_id"].(schema.StringAttribute); ok {
51-
attr.PlanModifiers = append(attr.PlanModifiers, stringplanmodifier.RequiresReplace())
52-
s.Attributes["okms_id"] = attr
53-
}
54-
if attr, ok := s.Attributes["path"].(schema.StringAttribute); ok {
55-
attr.PlanModifiers = append(attr.PlanModifiers, stringplanmodifier.RequiresReplace())
56-
s.Attributes["path"] = attr
57-
}
58-
59-
resp.Schema = s
45+
resp.Schema = OkmsSecretResourceSchema(ctx)
6046
}
6147

6248
func (r *okmsSecretResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {

ovh/resource_okms_secret_gen.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/data-sources/okms_secret.md.tmpl

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,54 @@ Retrieves metadata (and optionally the payload) of a secret stored in OVHcloud K
1010

1111
## Example Usage
1212

13+
Get the latest secret version (metadata only):
14+
15+
{{tffile "examples/data-sources/okms_secret/example_2.tf"}}
16+
17+
Get the latest secret version including its data:
18+
1319
{{tffile "examples/data-sources/okms_secret/example_1.tf"}}
1420

21+
Get a specific version including its payload:
22+
23+
{{tffile "examples/data-sources/okms_secret/example_3.tf"}}
24+
1525
## Argument Reference
1626

1727
The following arguments are supported:
1828

1929
### Required
2030

21-
* `okms_id` - (Required) OKMS service ID that owns the secret.
22-
* `path` - (Required) Secret path (identifier within the OKMS instance).
31+
- `okms_id` (String) OKMS service ID that owns the secret.
32+
- `path` (String) Secret path (identifier within the OKMS instance).
2333

2434
### Optional
2535

26-
* `version` - (Optional) Specific version to retrieve. If omitted, the latest (current) version is selected.
27-
* `include_data` - (Optional) If true, retrieves the secret payload (`data` attribute). Defaults to false. When false only metadata is returned.
36+
- `version` (Number) Specific version to retrieve. If omitted, the latest (current) version is selected.
37+
- `include_data` (Boolean) If true, retrieves the secret payload (`data` attribute). Defaults to false. When false only metadata is returned.
2838

29-
## Attributes Reference
39+
## Attributes Reference (Read-Only)
3040

3141
In addition to the arguments above, the following attributes are exported:
3242

33-
* `version` - The resolved version number (requested or current latest).
34-
* `data` - (Sensitive) Raw JSON secret payload (present only if `include_data` is true).
35-
* `metadata` - (Block) Secret metadata:
36-
* `cas_required` - (Boolean)
37-
* `created_at` - (String)
38-
* `updated_at` - (String)
39-
* `current_version` - (Number)
40-
* `oldest_version` - (Number)
41-
* `max_versions` - (Number)
42-
* `deactivate_version_after` - (String)
43-
* `custom_metadata` - (Map of String)
44-
* `iam` - (Block) IAM resource metadata:
45-
* `display_name` - (String)
46-
* `id` - (String)
47-
* `tags` - (Map of String)
48-
* `urn` - (String)
43+
- `version` (Number) The resolved version number (requested or current latest).
44+
- `data` (String, Sensitive) Raw JSON secret payload (present only if `include_data` is true).
45+
- `metadata` (Block) Secret metadata:
46+
- `cas_required` (Boolean)
47+
- `created_at` (String)
48+
- `updated_at` (String)
49+
- `current_version` (Number)
50+
- `oldest_version` (Number)
51+
- `max_versions` (Number)
52+
- `deactivate_version_after` (String)
53+
- `custom_metadata` (Map of String)
54+
- `iam` (Block) IAM resource metadata:
55+
- `display_name` (String)
56+
- `id` (String)
57+
- `tags` (Map of String)
58+
- `urn` (String)
4959

5060
## Behavior & Notes
5161

52-
* The `data` attribute retains the raw JSON returned by the API. Use `jsondecode()` to work with individual keys.
53-
* Changing only `include_data` (true -> false) will cause the `data` attribute to become null in subsequent refreshes (state no longer holds the payload).
62+
- The `data` attribute retains the raw JSON returned by the API. Use `jsondecode()` to work with individual keys.
63+
- Changing only `include_data` (true -> false) will cause the `data` attribute to become null in subsequent refreshes (state no longer holds the payload).

templates/resources/okms_secret.md.tmpl

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,70 +2,80 @@
22
subcategory : "Key Management Service (KMS)"
33
---
44

5-
# ovh_okms_secret
5+
# ovh_okms_secret (Resource)
66

77
Manages a secret stored in OVHcloud KMS.
88

99
> WARNING: `version.data` is marked **Sensitive** but still ends up in the state file. To mitigate that, it is recommended to protect your state with encryption and access controls. Avoid committing it to source control.
1010

1111
## Example Usage
1212

13+
Create a secret whose value is a JSON object. Use `jsonencode()` to produce a deterministic JSON string (ordering/whitespace) to minimize diffs.
14+
1315
{{tffile "examples/resources/okms_secret/example_1.tf"}}
1416

17+
# Reading a field from the secret version data:
18+
19+
{{tffile "examples/data-sources/okms_secret/example_1.tf"}}
20+
21+
Updating the secret (new version) while enforcing optimistic concurrency control using CAS:
22+
23+
{{tffile "examples/resources/okms_secret/example_2.tf"}}
24+
1525
## Argument Reference
1626

1727
The following arguments are supported:
1828

1929
### Required
2030

21-
* `okms_id` - (Required) ID of the OKMS service to create the secret in.
22-
* `path` - (Required, Forces new resource) Secret path (acts as the secret identifier within the OKMS instance). Immutable after creation.
23-
* `version` - (Required) Block defining the secret version to create/update. See Version Block below. (On updates providing a new `version.data` creates a new version.)
31+
- `okms_id` (String) ID of the OKMS service to create the secret in.
32+
- `path` (String) Secret path (acts as the secret identifier within the OKMS instance). Immutable after creation.
33+
- `version` (Block) Definition of the version to create/update. See Version Block below. (On updates providing a new `version.data` creates a new version.)
2434

2535
### Optional
2636

27-
* `cas` - (Optional) Check‑and‑set parameter used only on update (if `cas_required` metadata is set to true) to enforce optimistic concurrency control: its value must equal the current secret version (`metadata.current_version`) for the update to succeed. Ignored on create.
28-
* `metadata` - (Optional) Block of secret metadata configuration (subset of fields are user-settable). See Metadata Block below.
37+
- `cas` (Number) Check‑and‑set parameter used only on update (if `cas_required` metadata is set to true) to enforce optimistic concurrency control: its value must equal the current secret version (`metadata.current_version`) for the update to succeed. Ignored on create.
38+
- `metadata` (Block) Secret metadata configuration (subset of fields are user-settable). See Metadata Block below.
2939

3040
### Metadata Block
3141

3242
User configurable attributes inside `metadata`:
3343

34-
* `cas_required` - (Optional) If true, the server enforces optimistic concurrency control by requiring the `cas` parameter to match the current version number on every write (update) request.
35-
* `custom_metadata` - (Optional) Map of arbitrary key/value metadata.
36-
* `deactivate_version_after` - (Optional) Duration (e.g. `"24h"`) after which a version is deactivated. `"0s"` (default) means never automatically deactivate.
37-
* `max_versions` - (Optional) Number of versions to retain (default 10). Older versions beyond this limit are pruned.
44+
- `cas_required` (Boolean) If true, the server will enforce optimistic concurrency control by requiring the `cas` parameter to match the current version number on every write (update) request.
45+
- `custom_metadata` (Map of String) Arbitrary key/value metadata.
46+
- `deactivate_version_after` (String) Duration (e.g. `"24h"`) after which a version is deactivated. `"0s"` (default) means never automatically deactivate.
47+
- `max_versions` (Number) Number of versions to retain (default 10). Older versions beyond this limit are pruned.
3848

3949
Computed (read‑only) metadata attributes:
4050

41-
* `created_at` - Creation timestamp of the secret.
42-
* `updated_at` - Last update timestamp.
43-
* `current_version` - Current (latest) version number.
44-
* `oldest_version` - Oldest retained version number.
51+
- `created_at` (String) Creation timestamp of the secret.
52+
- `updated_at` (String) Last update timestamp.
53+
- `current_version` (Number) Current (latest) version number.
54+
- `oldest_version` (Number) Oldest retained version number.
4555

4656
### Version Block
4757

4858
Required attribute:
4959

50-
* `data` - (Required, Sensitive) Secret payload. Commonly set with `jsonencode(...)` so that Terraform comparisons are stable. Any valid JSON (object, array, string, number, bool) is accepted. Changing `data` creates a new secret version.
60+
- `data` (String, Sensitive) Secret payload. Commonly set with `jsonencode(...)` so that Terraform comparisons are stable. Any valid JSON (object, array, string, number, bool) is accepted. Changing `data` creates a new secret version.
5161

5262
Computed (read‑only) attributes:
5363

54-
* `id` - Version number.
55-
* `created_at` - Version creation timestamp.
56-
* `deactivated_at` - Deactivation timestamp if the version was deactivated.
57-
* `state` - Version state (e.g. `ACTIVE`).
64+
- `id` (Number) Version number.
65+
- `created_at` (String) Version creation timestamp.
66+
- `deactivated_at` (String) Deactivation timestamp if the version was deactivated.
67+
- `state` (String) Version state (e.g. `ACTIVE`).
5868

59-
## Attributes Reference
69+
## Attributes Reference (Read-Only)
6070

6171
In addition to arguments above, the following attributes are exported:
6272

63-
* `iam` - (Block) IAM metadata: `display_name`, `id`, `tags`, `urn`.
64-
* `metadata.*` - Computed fields as listed above.
65-
* `version.*` - Computed fields as listed above.
73+
- `iam` (Block) IAM metadata: `display_name`, `id`, `tags`, `urn`.
74+
- `metadata.*` computed fields as listed above.
75+
- `version.*` computed fields as listed above.
6676

6777
## Behavior & Notes
6878

69-
* Updating with a new `version.data` performs an API PUT that creates a new version; the previous version remains (subject to `max_versions`).
70-
* If `cas_required` is true, all write operations must include a correct `cas` query parameter (the expected current version number). Set `cas = ovh_okms_secret.example.metadata.current_version` to enforce optimistic concurrency. A mismatch causes the API to reject the update (preventing overwriting unseen changes).
71-
* `cas` is ignored on create (no existing version).
79+
- Updating with a new `version.data` performs an API PUT that creates a new version; the previous version remains (subject to `max_versions`).
80+
- If `cas_required` is true, all write operations must include a correct `cas` query parameter (the expected current version number). Set `cas = ovh_okms_secret.example.metadata.current_version` to enforce optimistic concurrency. A mismatch causes the API to reject the update (preventing overwriting unseen changes).
81+
- `cas` is ignored on create (no existing version).

0 commit comments

Comments
 (0)