Search
  • Frank Yoo

Automate Cryptographic Key Generation with Terraform

I've had my fair share of using automation tools in the past (including Puppet, Chef and Ansible), but on the cloud instance provisioning front, I've been an avid user of Terraform. Well, to be exact - I was going strong with Vagrant and later migrated to Terraform.


I've certainly used other provisioning tools as well, but when your shiny Macbook Pro was still kicking Snow Leopard and it was the only system you had available, plus I was able to customise the older versions of vagrant-esxi plugin to work on my own home VMWare ESXi setup - let's just say I needed a way to copy VMDK's automatically from Datastore #1 to Datastore #2 before starting the VM :D - Vagrant seemed like a good choice at the time. And, then came Terraform.


So why Terraform with Cryptographic Keys?


Well, the simple first answer is - because "You Can". And the second answer is it'll be cool if we could automate a Bring-Your-Own-Key (BYOK) to a cloud KMS without the headache of having to work through a vendor's RESTful API service. Keeping the interaction a common yet a high-level experience across other tools is always useful when it comes to agile operations.


Fortanix recently released an alpha version of the Terraform Provider for Self-Defending KMS, and it was my duty to test this out. Unfortunately, since this is only an alpha version, I had to reach out to the local Fortanix team to allow me access to the provider itself, but once it was copied onto the right directory, it was ready for Dr. Evil, er.... prime time!


For this blog, I'm only going to cover a simple cryptographic key generation using Terraform. I hope to cover BYOK soon.

Self-Defending KMS Setup


Before getting started, make sure you have created or have your Tenant / Account ID handy from Self-Defending KMS. You can grab the Account ID by selecting "Settings" within your Account:


And that's it! Nothing else is required for now. Let's get right into it.

Let's Automate: Terraform Provider / Configuration


Once you have the provider with you, it's quite simple to set it up. Copy the provider to your local plugins location (details on where to place the custom plugins are here) and you're ready to rock. Ensure you have defined your main.tf file to point to the custom provider:

terraform {
  required_providers {
    sdkms = {
      versions = ["0.1"]
      source = "fortanix.com/herdus0512/sdkms"
    }
  }
}

Simply run terraform init from your working directory and terraform will do the automatic copying of the custom provider to the right locations in your working directory for you:


To initialise the provider, setup your main.tf with the following provider block:

provider "sdkms" {
    endpoint = <sdkms_api_endpoint>
    username = <sdkms_username>
    password = <sdkms_password>
    acct_id  = <sdkms_account_id>
}

You can optionally setup a custom port for the Self-Defending KMS API endpoint, but at a minimum you'll need to know the following:

  • The endpoint to your Self-Defending KMS cluster

  • Your username that you use to login to Self-Defending KMS

  • Your password that you use to login to Self-Defending KMS

  • acct_id: The Tenant / Account ID you copied previously


Now that your provider is setup, it's time to create a a group. The following resource block should help:

resource "sdkms_group" "<resource_name>" {
    name        = <group_name>
    description = <group_description>
}

The group_name specified here will be used to create a new group within your Self-Defending KMS account and the description is optional.


To create a security object / cryptographic key within the group, you can use the following template resource block:

resource "sdkms_sobject" "<resource_name>" {
    name        = <sobject_name>
    obj_type    = <sobject_key_type>
    group_id    = <sobject_group_id>
    key_size    = <sobject_key_size>
    key_ops     = ["ENCRYPT", "DECRYPT", "WRAPKEY", "UNWRAPKEY", "DERIVEKEY", "MACGENERATE", "MACVERIFY", "APPMANAGEABLE"]
    description = <sobject_description>
}

At a minimum to create a new cryptographic key, you'll need to specify:

  • name: Name of security object

  • obj_type: Security Object type - if it's a AES key, "AES" would work

  • key_size: Security Object size - if it's a AES-256 key, 256 would work

  • key_ops: Permissions for what the key is allowed to do


Now we're ready to test. So for me, I wanted to initially create:

  • Group called "test-fyoo-group"

  • Security Object called "test-fyoo-key"

  • Group "test-fyoo-group" will own the Security Object "test-fyoo-key"

The "test-fyoo-key" will be a security object of something simple:

  • AES key

  • AES key that is 256 in size

  • Permissions for the AES key are limited to Encrypt or Decrypt only


Sample block would look something like this:

provider "sdkms" {
    endpoint    = https://sdkms.fortanix.com
    username    = REDACTED
    password    = REDACTED
    acct_id     = REDACTED
}

resource "sdkms_group" "group" {
    name        = "test-fyoo-group"
}

resource "sdkms_sobject" "security_object" {
    name        = "test-fyoo-key"
    obj_type    = "AES"
    group_id    = sdkms_group.group.id
    key_size    = 256
    key_ops     = ["ENCRYPT", "DECRYPT"]
}

Run a quick terraform plan and terraform apply that gives me the following output:


Terraform has completed my tasks. Let's review it in the Self-Defending KMS UI. Make note of the "id" of each resources created.


Firstly, I can see I have test-fyoo-group created in my UI:


Note that the UUID for test-fyoo-group, and it matches the ID from a terraform's saved state. That's going well.


Now let's look at the security object test-fyoo-key:


Again the UUID of the security object matches the ID from terraform's saved resource state. Since I also specified that I only wanted the ability to Encrypt and Decrypt, let's make sure that's also reflected in the UI:


And that's it! We've automated creating a cryptographic key within Fortanix Self-Defending KMS using Terraform!


Let's also make sure we can destroy the key and the group properly (following the CRUD standard) using Terraform (sorry, had to REDACT some of the sensitive values :D)


More documentation is being created as we speak on the link to the documentation page.


I will be back soon to cover BYOK to a cloud service using Terraform and how a FIPS 140-2 Level 3 appliance from Fortanix Self-Defending KMS can easily extend to cloud services using Terraform.


Feedback is always welcome and let me know your thoughts!

46 views0 comments