Terraform

reading time 5 mins

This guide will show you how to use Doppler to securely read and write secrets in Terraform.

Prerequisites

  • You have created a project in Doppler
  • You are familiar with using Terraform to manage infrastructure

Passing Doppler Secrets as Input Variables

The Doppler CLI can be used to pass secrets directly to Terraform without the need for a provider at all.

# Automatically converts Doppler secrets to lowercase Terraform variables
doppler run --name-transformer tf-var -- terraform plan

The --name-transformer tf-var flag will transform the names of your Doppler secrets into the Terraform Environment Variable format.

For example, a variable named API_KEY will be converted into TF_VAR_api_key by the name transformer and Terraform will automatically find this value if you have a Terraform variable named api_key.

Read on to learn about the Doppler Terraform provider and more complex use cases.

Provider Overview

There are two main ways to use the Doppler Terraform Provider:

  • Reading Secrets
    • Fetch secrets from Doppler and use them in your Terraform configuration
    • Use the doppler_secrets Data Source
  • Managing Secrets
    • Create, update, and delete Doppler secrets from Terraform
    • Use the doppler_secret Resource

Reading Secrets with the doppler_secrets Data Source

In this example, we'll use the doppler_secrets data source to read secrets from a config:

# Install the Doppler provider
terraform {
  required_providers {
    doppler = {
      source = "DopplerHQ/doppler"
      version = "1.0.0" # Always specify the latest version
    }
  }
}

# Define a variable so we can pass in our token
variable "doppler_token" {
  type = string
  description = "A token to authenticate with Doppler"
}

# Configure the Doppler provider with the token
provider "doppler" {
  doppler_token = var.doppler_token
}

# Define our data source to fetch secrets
data "doppler_secrets" "this" {}

# Access individual secrets
output "stripe_key" {
  # nonsensitive used for demo purposes only
  value = nonsensitive(data.doppler_secrets.this.map.STRIPE_KEY)
}

To read Doppler secrets from Terraform, we just need to create a Service Token to provide read-only access to a specific config.

There are several ways to pass variables to Terraform, but for now, we can just provide our Doppler token when prompted by Terraform.

First, run terraform init to setup your Terraform project, then run terraform apply to test the configuration:

Terraform used the Doppler provider to fetch the secrets from your config.

All of the secrets that you load from Doppler will be loaded into Terraform as strings. You can use Terraform's built-in parsing functions to convert secrets to their Terraform types:

# Use `tonumber` and `tobool` to parse string values into Terraform primatives
output "max_workers" {
  value = nonsensitive(tonumber(data.doppler_secrets.this.map.MAX_WORKERS))
}

# JSON values can be decoded direcly in Terraform
# e.g. FEATURE_FLAGS = `{ "AUTOPILOT": true, "TOP_SPEED": 130 }`
output "json_parsing_values" {
  value = nonsensitive(jsondecode(data.doppler_secrets.this.map.FEATURE_FLAGS)["TOP_SPEED"])
}

Reading Secrets from Multiple Projects

In this example, we use multiple Doppler providers with aliases to access secrets from two separate configs. This can be useful when you need to use multiple access tokens that are scoped to a single project and config in your Terraform run.

terraform {
  required_providers {
    doppler = {
      source = "DopplerHQ/doppler"
      version = "1.0.0"
    }
  }
}

variable "doppler_token_dev" {
  type = string
  description = "A token to authenticate with Doppler for the dev config"
}

variable "doppler_token_prd" {
  type = string
  description = "A token to authenticate with Doppler for the prd config"
}

provider "doppler" {
  doppler_token = var.doppler_token_dev
  alias = "dev"
}

provider "doppler" {
  doppler_token = var.doppler_token_prd
  alias = "prd"
}

data "doppler_secrets" "dev" {
  provider = doppler.dev
}

data "doppler_secrets" "prd" {
  provider = doppler.prd
}

output "port-dev" {
  value = nonsensitive(data.doppler_secrets.dev.map.PORT)
}

output "port-prd" {
  value = nonsensitive(data.doppler_secrets.prd.map.PORT)
}

Managing Secrets with the doppler_secret Resource

In this example, we'll use the doppler_secret resource to write to secrets in our Doppler config:

# Install the Doppler provider
terraform {
  required_providers {
    doppler = {
      source = "DopplerHQ/doppler"
      version = "1.0.0" # Always specify the latest version
    }
  }
}

# Define a variable so we can pass in our token
variable "doppler_token" {
  type = string
  description = "A token to authenticate with Doppler"
}

# Configure the Doppler provider with the token
provider "doppler" {
  doppler_token = var.doppler_token
}

# Generate a random password
resource "random_password" "db_password" {
  length = 32
  special = true
}

# Save the random password to Doppler
resource "doppler_secret" "db_password" {
  project = "rocket"
  config = "dev"
  name = "DB_PASSWORD"
  value = random_password.db_password.result
}

# Access the secret value
output "resource_value" {
  # nonsensitive used for demo purposes only
  value = nonsensitive(doppler_secret.db_password.value)
}

To write Doppler secrets, we'll need to provide a Doppler Personal Token in our Terraform configuration. You can generate a new Personal Token from the Doppler dashboard on the "Tokens" page.

Similar to our example for reading secrets, we'll run terraform init and then terraform apply to test the configuration:

Terraform generated a new password and saved it to our Doppler config as DB_PASSWORD.

Terraform will still store all of this data in Terraform state, but having your secrets in Doppler allows for much easier access to these secrets for all developers on your team.

πŸ‘

Awesome Work!

Now you know to use the Doppler Terraform provider to securely read and manage secrets for your infrastructure.


Did this page help you?