-
Notifications
You must be signed in to change notification settings - Fork 160
feat(okms): add datasource and resource okms_secret #1105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
alexGNX
wants to merge
1
commit into
ovh:master
Choose a base branch
from
alexGNX:dev/agagneux/okms_secret
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
--- | ||
subcategory : "Key Management Service (KMS)" | ||
--- | ||
|
||
# ovh_okms_secret (Data Source) | ||
|
||
Retrieves metadata (and optionally the payload) of a secret stored in OVHcloud KMS. | ||
|
||
> WARNING: If `include_data = true` the secret value is stored in cleartext (JSON) in the Terraform state file. Marked **Sensitive** only hides it from CLI output. If you use this option it is recommended to protect your state with encryption and access controls. | ||
|
||
## Example Usage | ||
|
||
Get the latest secret version (metadata only): | ||
|
||
```terraform | ||
data "ovh_okms_secret" "latest" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
} | ||
``` | ||
|
||
Get the latest secret version including its data: | ||
|
||
```terraform | ||
data "ovh_okms_secret" "latest_with_data" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
include_data = true | ||
} | ||
|
||
locals { | ||
secret_obj = jsondecode(data.ovh_okms_secret.latest_with_data.data) | ||
} | ||
|
||
output "api_key" { | ||
value = local.secret_obj.api_key | ||
sensitive = true | ||
} | ||
``` | ||
|
||
Get a specific version including its payload: | ||
|
||
```terraform | ||
data "ovh_okms_secret" "v3" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
version = 3 | ||
include_data = true | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
### Required | ||
|
||
- `okms_id` (String) OKMS service ID that owns the secret. | ||
- `path` (String) Secret path (identifier within the OKMS instance). | ||
|
||
### Optional | ||
|
||
- `version` (Number) Specific version to retrieve. If omitted, the latest (current) version is selected. | ||
- `include_data` (Boolean) If true, retrieves the secret payload (`data` attribute). Defaults to false. When false only metadata is returned. | ||
|
||
## Attributes Reference (Read-Only) | ||
|
||
In addition to the arguments above, the following attributes are exported: | ||
|
||
- `version` (Number) The resolved version number (requested or current latest). | ||
- `data` (String, Sensitive) Raw JSON secret payload (present only if `include_data` is true). | ||
- `metadata` (Block) Secret metadata: | ||
- `cas_required` (Boolean) | ||
- `created_at` (String) | ||
- `updated_at` (String) | ||
- `current_version` (Number) | ||
- `oldest_version` (Number) | ||
- `max_versions` (Number) | ||
- `deactivate_version_after` (String) | ||
- `custom_metadata` (Map of String) | ||
- `iam` (Block) IAM resource metadata: | ||
- `display_name` (String) | ||
- `id` (String) | ||
- `tags` (Map of String) | ||
- `urn` (String) | ||
|
||
## Behavior & Notes | ||
|
||
- The `data` attribute retains the raw JSON returned by the API. Use `jsondecode()` to work with individual keys. | ||
- Changing only `include_data` (true -> false) will cause the `data` attribute to become null in subsequent refreshes (state no longer holds the payload). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
|
||
--- | ||
subcategory : "Key Management Service (KMS)" | ||
--- | ||
|
||
# ovh_okms_secret (Resource) | ||
|
||
Manages a secret stored in OVHcloud KMS. | ||
|
||
> 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. | ||
|
||
## Example Usage | ||
|
||
Create a secret whose value is a JSON object. Use `jsonencode()` to produce a deterministic JSON string (ordering/whitespace) to minimize diffs. | ||
|
||
```terraform | ||
resource "ovh_okms_secret" "example" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
|
||
metadata = { | ||
max_versions = 10 # keep last 10 versions | ||
cas_required = true # enforce optimistic concurrency control (server will require current secret version on the cas attribute to allow update) | ||
deactivate_version_after = "0s" # keep versions active indefinitely (example) | ||
custom_metadata = { | ||
environment = "prod" | ||
owner = "payments-team" | ||
} | ||
} | ||
|
||
# Initial version (will create version 1) | ||
version = { | ||
data = jsonencode({ | ||
api_key = var.api_key | ||
api_secret = var.api_secret | ||
}) | ||
} | ||
} | ||
|
||
# Reading a field from the secret version data | ||
locals { | ||
secret_json = jsondecode(ovh_okms_secret.example.version.data) | ||
} | ||
|
||
output "api_key" { | ||
value = local.secret_json.api_key | ||
sensitive = true | ||
} | ||
``` | ||
|
||
Updating the secret (new version) while enforcing optimistic concurrency control using CAS: | ||
|
||
```terraform | ||
resource "ovh_okms_secret" "example" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
|
||
# Ensure no concurrent update happened: set cas to the current version | ||
# (metadata.current_version is populated after first apply) | ||
cas = ovh_okms_secret.example.metadata.current_version | ||
|
||
metadata = { | ||
cas_required = true | ||
} | ||
|
||
version = { | ||
data = jsonencode({ | ||
api_key = var.api_key | ||
api_secret = var.new_api_secret # changed value -> creates new version | ||
}) | ||
} | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
### Required | ||
|
||
- `okms_id` (String) ID of the OKMS service to create the secret in. | ||
- `path` (String) Secret path (acts as the secret identifier within the OKMS instance). Immutable after creation. | ||
- `version` (Block) Definition of the version to create/update. See Version Block below. (On updates providing a new `version.data` creates a new version.) | ||
|
||
### Optional | ||
|
||
- `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. | ||
- `metadata` (Block) Secret metadata configuration (subset of fields are user-settable). See Metadata Block below. | ||
|
||
### Metadata Block | ||
|
||
User configurable attributes inside `metadata`: | ||
|
||
- `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. | ||
- `custom_metadata` (Map of String) Arbitrary key/value metadata. | ||
- `deactivate_version_after` (String) Duration (e.g. `"24h"`) after which a version is deactivated. `"0s"` (default) means never automatically deactivate. | ||
- `max_versions` (Number) Number of versions to retain (default 10). Older versions beyond this limit are pruned. | ||
|
||
Computed (read‑only) metadata attributes: | ||
|
||
- `created_at` (String) Creation timestamp of the secret. | ||
- `updated_at` (String) Last update timestamp. | ||
- `current_version` (Number) Current (latest) version number. | ||
- `oldest_version` (Number) Oldest retained version number. | ||
|
||
### Version Block | ||
|
||
Required attribute: | ||
|
||
- `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. | ||
|
||
Computed (read‑only) attributes: | ||
|
||
- `id` (Number) Version number. | ||
- `created_at` (String) Version creation timestamp. | ||
- `deactivated_at` (String) Deactivation timestamp if the version was deactivated. | ||
- `state` (String) Version state (e.g. `ACTIVE`). | ||
|
||
## Attributes Reference (Read-Only) | ||
|
||
In addition to arguments above, the following attributes are exported: | ||
|
||
- `iam` (Block) IAM metadata: `display_name`, `id`, `tags`, `urn`. | ||
- `metadata.*` computed fields as listed above. | ||
- `version.*` computed fields as listed above. | ||
|
||
## Behavior & Notes | ||
|
||
- Updating with a new `version.data` performs an API PUT that creates a new version; the previous version remains (subject to `max_versions`). | ||
- 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). | ||
- `cas` is ignored on create (no existing version). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
data "ovh_okms_secret" "latest_with_data" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
include_data = true | ||
} | ||
|
||
locals { | ||
secret_obj = jsondecode(data.ovh_okms_secret.latest_with_data.data) | ||
} | ||
|
||
output "api_key" { | ||
value = local.secret_obj.api_key | ||
sensitive = true | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
resource "ovh_okms_secret" "example" { | ||
okms_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | ||
path = "app/api_credentials" | ||
|
||
# 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. | ||
cas = 1 | ||
|
||
metadata = { | ||
max_versions = 10 # keep last 10 versions | ||
cas_required = true # enforce optimistic concurrency control (server will require current secret version on the cas attribute to allow update) | ||
deactivate_version_after = "0s" # keep versions active indefinitely (example) | ||
custom_metadata = { | ||
environment = "prod" | ||
appname = "helloworld" | ||
} | ||
} | ||
|
||
# Initial version (will create version 1) | ||
version = { | ||
data = jsonencode({ | ||
api_key = "mykey" | ||
api_secret = "mysecret" | ||
}) | ||
} | ||
} | ||
|
||
# Reading a field from the secret version data | ||
locals { | ||
secret_json = jsondecode(ovh_okms_secret.example.version.data) | ||
} | ||
|
||
output "api_key" { | ||
value = local.secret_json.api_key | ||
sensitive = true | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.