# Psono Terraform Provider
The Psono Terraform Provider (opens new window) manages individual keys inside pre-created Psono Environment Variables entries. It can:
- Preserve and adopt an existing key.
- Generate a value when a key does not exist.
- Write a value without storing it in Terraform state.
- Rotate provider-generated or externally supplied values.
- Read a value through an ephemeral resource without persisting it in plan or state.
- Retain or explicitly delete a key when its Terraform resource is destroyed.
The provider uses a restricted Psono API key. Encryption and decryption happen locally in the provider; an unrestricted API key is not required. The provider does not create Psono entries, folders, or datastores.
# Requirements
Before using the provider, ensure that you have:
- Terraform 1.11 or newer.
- Network access from Terraform to your Psono server.
- A pre-created Psono Environment Variables entry.
- A dedicated restricted API key with that entry assigned.
- Read permission for every operation.
- Write permission for creating, updating, rotating, or deleting keys.
# Prepare Psono
# Create an Environment Variables entry
Create or select an Environment Variables entry in Psono. The provider manages
individual keys in this entry, such as DB_PASSWORD or API_TOKEN.
The entry itself must already exist. Terraform only manages the selected keys inside it.
# Create a restricted API key
Follow the API key creation guide and apply these provider-specific settings:
- Create a dedicated restricted API key for Terraform.
- Assign the Environment Variables entries that Terraform may access.
- Grant read permission.
- Grant write permission if Terraform will create, change, rotate, or delete keys.
- Leave "Allow insecure usage" disabled.
- Record the API key ID and API secret key.
- Record the
SECRET_IDdisplayed for each assigned entry.
The provider needs the API key ID and API secret key. It does not need the API private key or server signature.
WARNING
Use a dedicated API key and assign only the entries Terraform needs. Anyone who can access the API secret key can read the assigned Psono entries and, when write permission is enabled, modify them.
# Install the provider
Declare the provider in your Terraform configuration:
terraform {
required_version = ">= 1.11.0"
required_providers {
psono = {
source = "psono/psono"
version = "~> 1.0"
}
}
}
provider "psono" {}
Initialize the working directory:
terraform init
Terraform downloads the signed provider release from the public Terraform Registry and verifies its checksum signature.
# Configure authentication
Prefer environment variables so credentials do not appear in Terraform files:
export PSONO_SERVER_URL='https://psono.example.com/server'
export PSONO_API_KEY_ID='REPLACE_WITH_API_KEY_ID'
export PSONO_API_SECRET_KEY='REPLACE_WITH_API_SECRET_KEY'
PSONO_SERVER_URL must include the /server path. The API secret key is the
64-character hexadecimal secret shown in the restricted API key details.
For a Psono server that uses a private certificate authority, provide the PEM CA certificate bundle contents:
export PSONO_CA_BUNDLE="$(cat company-ca.pem)"
TLS certificate verification cannot be disabled. The additional certificates are appended to the system trust store.
The equivalent provider arguments are server_url, api_key_id,
api_secret_key, and ca_bundle. Environment variables are recommended to
avoid placing credentials directly in configuration.
# Generate a value
The following resource preserves DB_PASSWORD if it already exists. Otherwise,
the provider generates a 32-character value and stores it in Psono:
resource "psono_environment_variable" "database_password" {
secret_id = var.psono_environment_variables_secret_id
name = "DB_PASSWORD"
length = 32
min_lower = 4
min_upper = 4
min_numeric = 4
min_special = 4
rotation_version = 1
}
The generated value is not returned by the managed resource and does not enter
Terraform state. Increment rotation_version to replace a provider-generated
value:
rotation_version = 2
Changing password-generation settings does not rotate an existing value by
itself. Increment rotation_version when the new settings should take effect.
WARNING
Incrementing rotation_version replaces the current key value even when the
resource originally adopted or imported that key. Terraform cannot distinguish
an adopted value from a value it previously generated.
# Supply a write-only value
Use value_wo to write an externally supplied value without storing it in
Terraform plan or state. This example writes an ephemeral random password:
ephemeral "random_password" "database" {
length = 32
}
resource "psono_environment_variable" "database_password" {
secret_id = var.psono_environment_variables_secret_id
name = "DB_PASSWORD"
value_wo = ephemeral.random_password.database.result
value_wo_version = 1
}
value_wo_version is required when value_wo is configured. Increment it when
Terraform should write a replacement value. Changing value_wo without also
changing value_wo_version does not update Psono.
# Read a value without state
The ephemeral resource reads one key without persisting its value in Terraform plan or state:
ephemeral "psono_environment_variable" "database_password" {
secret_id = var.psono_environment_variables_secret_id
name = "DB_PASSWORD"
}
Its sensitive value attribute can only be passed to another ephemeral context,
such as a write-only argument. It cannot be exposed as a normal Terraform
output.
For continuous synchronization into Kubernetes Secrets, use the Psono Kubernetes Operator instead. Terraform only reads or writes values while a Terraform operation is running.
# Deletion behavior
The default deletion policy is Retain. Destroying the Terraform resource
removes it from Terraform state but leaves the key in Psono. This prevents an
adopted value from being deleted unexpectedly.
Set deletion_policy to Delete only when Terraform should remove the Psono
key during destroy:
resource "psono_environment_variable" "temporary_token" {
secret_id = var.psono_environment_variables_secret_id
name = "TEMPORARY_TOKEN"
deletion_policy = "Delete"
}
Changing secret_id or name replaces the Terraform resource. The deletion
policy also applies to the old key during replacement: Retain leaves it in
Psono, while Delete removes it.
# Import an existing key
Import an existing key with <SECRET_ID>:<KEY_NAME>:
terraform import psono_environment_variable.database_password \
'25070c66-8950-4264-9b39-11e6d83312e3:DB_PASSWORD'
Importing never reads the secret value into Terraform state.
# Changes outside Terraform
Terraform checks whether the managed key exists but does not store or compare
its secret value. A value changed directly in Psono is therefore accepted as
the current value. Terraform only writes another value when
rotation_version or value_wo_version changes.
# Security considerations
- Keep provider credentials outside Terraform configuration and state.
- Treat Terraform process environments and CI variables as sensitive.
- Use a dedicated restricted API key for each Terraform trust boundary.
- Assign only required Psono entries and grant only required permissions.
- Keep "Allow insecure usage" disabled to prevent other clients from requesting server-side decryption.
- Review
deletion_policy = "Delete"carefully before applying or destroying. - Do not expose ephemeral values through logs, provisioners, or non-write-only arguments.
# Reference
The Terraform Registry contains additional provider and resource reference documentation: