Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Sovereign, high-performance data protection

Terraform / OpenTofu Provider

The Cosmian KMS Terraform provider allows DevOps and platform engineering teams to manage cryptographic keys, certificates, and access rights in Eviden KMS as infrastructure-as-code, with full GitOps support.

AttributeValue
Provider sourceCosmian/kms
Terraform Registryregistry.terraform.io/providers/Cosmian/kms
GitHub repositorygithub.com/Cosmian/terraform-provider-kms
Current versionv0.1.1
LicenseMozilla Public License 2.0
KMS versionEviden KMS ≥ 5.0

Requirements

Installation

Declare the provider in your Terraform configuration:

terraform {
  required_providers {
    kms = {
      source  = "Cosmian/kms"
      version = "~> 0.1"
    }
  }
}

Then run:

terraform init

Provider Configuration

provider "kms" {
  server_url = "https://kms.example.com:9998"
  api_key    = var.kms_api_key   # or set COSMIAN_KMS_API_KEY env var
}

mTLS client certificate authentication

provider "kms" {
  server_url    = "https://kms.example.com:9998"
  tls_cert_file = "/etc/kms/client.crt"
  tls_key_file  = "/etc/kms/client.key"
  ca_cert_file  = "/etc/kms/ca.pem"   # optional — verify KMS server certificate
}

Environment variables

All provider arguments can be supplied via environment variables, which is the recommended approach for CI/CD pipelines:

ArgumentEnvironment variable
server_urlCOSMIAN_KMS_SERVER_URL
api_keyCOSMIAN_KMS_API_KEY
export COSMIAN_KMS_SERVER_URL="https://kms.example.com:9998"
export COSMIAN_KMS_API_KEY="my-secret-api-key"
terraform apply

Resources

kms_symmetric_key

Creates an AES symmetric key via KMIP Create.

resource "kms_symmetric_key" "data_key" {
  algorithm       = "AES"
  key_length_bits = 256
  name            = "database-encryption-key"
  tags            = ["env=prod", "team=data"]
}

output "data_key_uid" {
  value = kms_symmetric_key.data_key.id
}

Arguments

ArgumentTypeRequiredDescription
algorithmstringyesCryptographic algorithm. AES (default)
key_length_bitsnumberyesKey size in bits: 128, 192, or 256
namestringnoHuman-readable name stored as a KMIP Name attribute
tagslist(string)noList of key=value tags attached to the object

Attributes

AttributeDescription
idKMS UID of the created key (UUID)

kms_key_pair

Creates an asymmetric key pair via KMIP CreateKeyPair.

resource "kms_key_pair" "signing_pair" {
  algorithm       = "RSA"
  key_length_bits = 4096
  name            = "code-signing"
}

output "private_key_uid" {
  value = kms_key_pair.signing_pair.private_key_uid
}

output "public_key_uid" {
  value = kms_key_pair.signing_pair.public_key_uid
}

Arguments

ArgumentTypeRequiredDescription
algorithmstringyesRSA, EC
key_length_bitsnumberyesRSA: 2048, 3072, 4096. EC: curve size (256, 384, 521)
namestringnoHuman-readable key pair name
tagslist(string)noTags for both keys

Attributes

AttributeDescription
private_key_uidKMS UID of the private key
public_key_uidKMS UID of the public key

kms_certificate

Creates or imports an X.509 certificate via KMIP Certify.

resource "kms_key_pair" "ca_pair" {
  algorithm       = "RSA"
  key_length_bits = 4096
  name            = "internal-ca"
}

resource "kms_certificate" "internal_ca" {
  subject_name  = "CN=Internal CA,O=Example,C=FR"
  key_pair_uid  = kms_key_pair.ca_pair.private_key_uid
  is_ca         = true
  validity_days = 3650
}

Arguments

ArgumentTypeRequiredDescription
subject_namestringyesDistinguished Name (DN) of the certificate subject
key_pair_uidstringyesUID of the KMS private key to sign with
is_caboolnoWhether to add the CA basic constraint. Default: false
validity_daysnumbernoCertificate validity period in days. Default: 365
tagslist(string)noTags attached to the certificate object

Attributes

AttributeDescription
idKMS UID of the certificate

kms_access_right

Grants a user access rights to a KMS object via the KMS grant endpoint.

resource "kms_access_right" "alice_can_decrypt" {
  object_uid = kms_symmetric_key.data_key.id
  user_id    = "alice@example.com"
  operations = ["Get", "Decrypt"]
}

Arguments

ArgumentTypeRequiredDescription
object_uidstringyesUID of the KMS object to grant access to
user_idstringyesIdentity of the user (email, sub claim, or DN)
operationslist(string)yesKMIP operation names to grant: Get, Decrypt, Encrypt, Sign, Verify, Export, Destroy, …

Data Sources

data.kms_symmetric_key

Reads an existing symmetric key by UID.

data "kms_symmetric_key" "existing_key" {
  unique_identifier = "550e8400-e29b-41d4-a716-446655440000"
}

data.kms_key_pair

Reads an existing key pair.

data "kms_key_pair" "existing_pair" {
  private_key_uid = "uuid-of-private-key"
}

data.kms_access_list

Lists all access rights on a KMS object.

data "kms_access_list" "key_grants" {
  object_uid = kms_symmetric_key.data_key.id
}

output "granted_users" {
  value = data.kms_access_list.key_grants.users
}

Import

All resources support terraform import to bring existing KMS objects under Terraform management.

# Symmetric key
terraform import kms_symmetric_key.data_key 550e8400-e29b-41d4-a716-446655440000

# Key pair — format: private_uid:public_uid
terraform import kms_key_pair.signing_pair \
  aaaa0000-0000-0000-0000-000000000001:bbbb0000-0000-0000-0000-000000000002

# Certificate
terraform import kms_certificate.internal_ca cccc0000-0000-0000-0000-000000000003

Complete example

The following configuration creates a 256-bit AES key and a 4096-bit RSA signing pair, then grants alice@example.com decrypt rights on the AES key:

terraform {
  required_providers {
    kms = {
      source  = "Cosmian/kms"
      version = "~> 0.1"
    }
  }
}

provider "kms" {
  # server_url and api_key read from COSMIAN_KMS_SERVER_URL / COSMIAN_KMS_API_KEY
}

resource "kms_symmetric_key" "app_dek" {
  algorithm       = "AES"
  key_length_bits = 256
  name            = "app-data-encryption-key"
  tags            = ["app=myapp", "env=prod"]
}

resource "kms_key_pair" "app_signing" {
  algorithm       = "RSA"
  key_length_bits = 4096
  name            = "app-signing-key"
  tags            = ["app=myapp", "env=prod"]
}

resource "kms_access_right" "alice_decrypt" {
  object_uid = kms_symmetric_key.app_dek.id
  user_id    = "alice@example.com"
  operations = ["Get", "Decrypt"]
}

output "dek_uid"         { value = kms_symmetric_key.app_dek.id }
output "private_key_uid" { value = kms_key_pair.app_signing.private_key_uid }
output "public_key_uid"  { value = kms_key_pair.app_signing.public_key_uid }

Apply it against a local KMS instance:

docker run -d -p 9998:9998 --name kms ghcr.io/cosmian/kms:latest

export COSMIAN_KMS_SERVER_URL=http://localhost:9998
terraform init
terraform apply

Local development and testing

Clone the provider repository and build the binary:

git clone https://github.com/Cosmian/terraform-provider-kms
cd terraform-provider-kms
make build     # produces ./terraform-provider-kms

Configure Terraform to use the local binary instead of the registry version by creating or editing ~/.terraformrc:

provider_installation {
  dev_overrides {
    "Cosmian/kms" = "/absolute/path/to/terraform-provider-kms"
  }
  direct {}
}

Run the acceptance tests against a local KMS server:

docker run -d -p 9998:9998 --name kms ghcr.io/cosmian/kms:latest

export TF_ACC=1
export COSMIAN_KMS_SERVER_URL=http://localhost:9998
make testacc