[Webinar] Policy-as-Code for Secure, Resilient Infrastructure

➡️ Register Now

Terraform

Terraform Random_Password Resource Overview

terraform random password

Subscribe to our Newsletter

Mission Infrastructure newsletter is a monthly digest of the latest posts from our blog, curated to give you the insights you need to advance your infrastructure game.

Generating secure passwords in Terraform can be challenging without a reliable method. The random_password resource from the Terraform Random provider solves this by creating strong, unpredictable passwords for infrastructure automation while ensuring proper security measures.

In this article, we will cover how to use random_password for variable-length passwords, multi-user setups, secret storage, and importing existing passwords, along with key differences from random_string.

  1. What is Terraform Random provider?
  2. What is the Terraform random_password resource?
  3. How to use random_password resource to generate passwords in Terraform
  4. Importing a random password to Terraform
  5. What is the difference between random_password and random_string in Terraform?

What is Terraform Random provider?

The Terraform Random provider (random) generates cryptographically secure pseudo-random values for use in Terraform configurations. 

It provides resources like random_string, random_id, and random_pet, which help create unique names, passwords, or tokens. These values persist in the Terraform state file but can be re-generated when their arguments change or when forced through lifecycle configurations.

It’s useful for creating unique resources in both production and testing environments where unique identifiers or credentials are required.

What is the Terraform random_password resource?

The Terraform random_password resource, part of the Random provider, generates a secure, random password with specific length and complexity requirements. The generated value can be referenced in other resources, such as database configurations or secrets management tools, ensuring no hardcoded passwords exist in your configuration.

For example:

resource "random_password" "example" {
  length           = 16
  special         = true
  upper           = true
  lower           = true
  numeric         = true
  override_special = "!@#%^&*"
}

output "generated_password" {
  value = random_password.example.result
  sensitive = true
}

The random_password resource is declared with various parameters:

  • length – Defines the number of characters in the password
  • special – Boolean flag to include special characters
  • upper – Boolean flag to include uppercase letters
  • lower – Boolean flag to include lowercase letters
  • numeric – Boolean flag to include numbers
  • override_special – Custom set of special characters

Always mark the result of random_password as sensitive = true in any output or resource attribute that uses it. However, note that while this hides the value from Terraform CLI output, the password is still stored in plain text in the Terraform state file. To enhance security, consider using remote state storage with encryption, such as AWS S3 with server-side encryption enabled. (Learn more: Terraform security best practices)

How to use random_password resource to generate passwords in Terraform

Terraform requires the random provider to use the random_password resource. 

resource "random_password" "secure_password" {
  length  = 20
  special = false
  upper   = true
  lower   = true
  numeric = true
}

output "secure_generated_password" {
  value     = random_password.secure_password.result
  sensitive = true
}

The parameters we used here:

  • length = 20: Specifies that the password will be 20 characters long
  • special = false: Ensures that special characters (!@#$%^&*(), etc.) are not included, making the password suitable for systems that do not support special characters
  • upper = true: Ensures that uppercase letters are included
  • lower = true: Ensures that lowercase letters are included
  • numeric = true: Ensures that numbers are included

The output block defines secure_generated_password, which displays the generated password when running Terraform. However, since sensitive = true is set, the password will not appear in the CLI output to prevent accidental exposure.

Generate a password with a variable length

You can define a variable and reference it within the random_password resource to generate a password with a dynamically adjustable length in Terraform.

For example:

provider "random" {}

variable "password_length" {
  description = "Length of the generated password"
  type        = number
  default     = 16
}

resource "random_password" "dynamic_password" {
  length  = var.password_length
  special = true
  upper   = true
  lower   = true
  numeric = true
}

output "generated_password" {
  value     = random_password.dynamic_password.result
  sensitive = true
}

The variable "password_length" block allows setting the password length dynamically. Here, the default value is 16, but this can be overridden when running Terraform. Then instead of specifying a fixed length, length = var.password_length dynamically sets the password length based on the variable.

You can specify a different password length by passing a value using the Terraform CL:

terraform apply -var="password_length=20"

Generate passwords for multiple users

To generate unique passwords for multiple users in Terraform, you can use the random_password resource with the for_each or count meta-argument

In the example below, we’ll use for_each:

provider "random" {}

variable "users" {
  description = "List of users who need passwords"
  type        = list(string)
  default     = ["alice", "bob", "charlie"]
}

resource "random_password" "user_passwords" {
  for_each = toset(var.users)

  length  = 16
  special = true
  upper   = true
  lower   = true
  numeric = true
}

output "user_passwords" {
  value     = { for user in var.users : user => random_password.user_passwords[user].result }
  sensitive = true
}

The variable “users” stores a list of usernames that require passwords. We can modify that list to add or remove users dynamically.

To ensure a unique password is generated for each user, the random_password resource iterates over each username in var.users (converted to a set using toset()). 

You can also use a map instead of a list to store additional user metadata.

Storing generated passwords in a secret manager

Best practice dictates that generated passwords should be stored in a secure secrets manager rather than in Terraform state files.

In the example below, we’ll use random_password and store it in AWS Secrets Manager using the aws_secretsmanager_secret and aws_secretsmanager_secret_version resources.

provider "aws" {
  region = "us-east-1"
}

provider "random" {}

# Generate a random password
resource "random_password" "db_password" {
  length  = 20
  special = true
  upper   = true
  lower   = true
  numeric = true
}

# Create a secret in AWS Secrets Manager
resource "aws_secretsmanager_secret" "db_secret" {
  name = "my-database-password"
}

# Store the generated password in AWS Secrets Manager
resource "aws_secretsmanager_secret_version" "db_secret_value" {
  secret_id     = aws_secretsmanager_secret.db_secret.id
  secret_string = jsonencode({
    username = "admin"
    password = random_password.db_password.result
  })
}

output "secret_arn" {
  value = aws_secretsmanager_secret.db_secret.arn
}

The provider "aws" block configures Terraform to interact with AWS services. Terraform requires proper authentication credentials, which can be provided via environment variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) or IAM roles if running on AWS infrastructure. 

Once the password is generated, Terraform creates an AWS Secrets Manager secret using the aws_secretsmanager_secret resource. This secret acts as a container for sensitive data, allowing controlled access through IAM policies. 

The actual password is then stored inside this secret using the aws_secretsmanager_secret_version resource. The secret_string field is defined using jsonencode({ username = "admin", password = random_password.db_password.result }), which securely structures the credentials as a JSON object containing both a username and password.

To avoid exposing the password in Terraform output, only the ARN (Amazon Resource Name) of the secret is displayed using an output block. This ARN can be used to reference the secret securely in other AWS resources, such as RDS instances or Lambda functions. The actual password can be retrieved securely using the AWS CLI command:

aws secretsmanager get-secret-value --secret-id my-database-password --query SecretString --output text

If you are using a different secrets manager, such as, HashiCorp Vault, the vault_generic_secret resource stores the password, and the vault provider handles authentication and retrieval. 

Importing a random password to Terraform

Because random_password generates passwords rather than managing existing ones, direct import is not possible. However, you can work around this by defining a terraform.tfvars file or using an external data source.

Using Terraform variables

You can manually specify the password as a variable and pass it to Terraform.

variable "imported_password" {
  description = "Manually imported password"
  type        = string
  sensitive   = true
}

output "imported_password_output" {
  value     = var.imported_password
  sensitive = true
}

Save your password in a terraform.tfvars file:

imported_password = "YourExistingSecurePassword123!"

And run Terraform with:

terraform apply -var-file="terraform.tfvars"

Using an external data source

If the password is stored externally (e.g., in AWS Secrets Manager or HashiCorp Vault), you can fetch it dynamically using a data source.

data "aws_secretsmanager_secret_version" "imported_password" {
  secret_id = "my-secret-password"
}

output "retrieved_password" {
  value     = data.aws_secretsmanager_secret_version.imported_password.secret_string
  sensitive = true
}

What is the difference between random_password and random_string in Terraform?

random_password and random_string are both Terraform resources provided by the random provider. random_password is a specialized and safer choice for password generation due to its pre-configured, more robust character set. random_string is more versatile and used for non-sensitive unique values, such as random resource names, bucket names, or database instance identifiers.

If you do use the random_string for passwords, be sure to configure the special, upper, lower, and number arguments appropriately, and consider using override_special to precisely define the set of special characters to include.

Key points

Using Terraform’s random_password resource simplifies credential management by generating secure, cryptographically random passwords within infrastructure as code. It avoids hardcoded secrets, ensuring consistency and security across deployments.

However, proper state management is critical to prevent unintended password exposure. As best practice, consider:

  • Storing state in an encrypted backend, such as AWS S3 with KMS encryption
  • Using a secure secrets manager (AWS Secrets Manager, HashiCorp Vault) instead of exposing credentials in state files
  • Leveraging IAM roles for authentication rather than static credentials

We encourage you to explore how Spacelift makes it easy to work with Terraform. If you need help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this.

If you want to learn more about Spacelift, create a free account today or book a demo with one of our engineers.

Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.

Automate Terraform Deployments with Spacelift

Automate your infrastructure provisioning, and build more complex workflows based on Terraform using policy as code, programmatic configuration, context sharing, drift detection, resource visualization, and many more.

Learn more

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide