The “random” Terraform provider, one of the more unique Terraform providers, is used to generate random values in your Terraform or OpenTofu configurations. It's particularly useful when you need unique or arbitrary values in the Terraform configuration, but don't want to hardcode them. Some use cases for using the random provider are:
There are five resources that the random provider supports in the Terraform configuration:
random_id
: Generates a random identifierrandom_integer
: Produces a random integer within a specified rangerandom_string
: Creates a random string of charactersrandom_password
: Generates a random passwordrandom_shuffle
: Randomly shuffles a list of stringsrandom_pet
: Randomly generate namesrandom_uuid
: Randomly generates a UUIDIt’s important to note that the random values are generated during the plan phase and remain consistent across applies, unless explicitly set to regenerate through the keepers argument which is discussed later in the blog.
Before doing anything, you always need to declare the provider to ensure you can pull the random resources into the Terraform run:
terraform {
required_providers {
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
}
Once the Terraform provider is set, you can start testing out the various provider resources as seen below:
The main use case for the random_id
resource is to create random resource IDs, such as appending an ID to a name. This will allow you to keep a consistent naming convention:
# Define variables
variable "environment" {
type = string
default = "stage"
}
variable "instance_type" {
type = string
default = "t2.micro"
}
variable "ami_id" {
type = string
default = "ami-09bd3f9be7c1b8217"
}
# Generate a random ID
resource "random_id" "server_id" {
keepers = {
# Generate a new id when these values change
ami_id = var.ami_id
instance_type = var.instance_type
environment = var.environment
}
byte_length = 8
}
# Create an EC2 instance
resource "aws_instance" "example" {
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = "server-${var.environment}-${random_id.server_id.hex}"
Environment = var.environment
some_tag = "tag123"
}
}
The main use case for the random_integer
resource is to create a random integer for testing scenarios and simulations.
resource "random_integer" "min_size" {
min = 1
max = 3
}
resource "random_integer" "max_size" {
min = 4
max = 6
}
resource "random_shuffle" "az_list" {
input = data.aws_subnets.default.ids
result_count = 2
}
resource "aws_autoscaling_group" "example" {
name = "example-asg"
vpc_zone_identifier = random_shuffle.az_list.result
min_size = random_integer.min_size.result
max_size = random_integer.max_size.result
desired_capacity = random_integer.min_size.result
}
The main use case for the random_string
resource is to generate random strings for input. This helps to create unique values for testing, especially useful for non-sensitive values. Sensitive values would be more appropriate for the random_password resource below.
resource "random_string" "bucket_suffix" {
length = 8
special = false
upper = false
}
resource "aws_s3_bucket" "example" {
bucket = "some-example-${random_string.bucket_suffix.result}"
tags = {
Name = "My bucket"
Environment = "Dev"
}
}
The main use case for random_password
is to generate random passwords or strings to improve security. Rather than relying on a human, this resource will create strong unique passwords based on the set of rules that are set:
resource "random_password" "db_password" {
length = 16
special = true
override_special = "!#$%&*()-_=+[]{}<>:?"
}
resource "aws_db_instance" "default" {
identifier = "mydb"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t3.micro"
allocated_storage = 20
db_name = "mydb"
username = "admin"
password = random_password.db_password.result
skip_final_snapshot = true
}
}
The main use case for random_shuffle
is to randomly shuffle a list of inputs. A use case for this is distributing resources across different AZs for high availability:
variable "availability_zones" {
default = ["us-west-2a", "us-west-2b", "us-west-2c", "us-west-2d"]
}
resource "random_shuffle" "az_list" {
input = var.availability_zones
result_count = 2
}
resource "aws_instance" "example" {
count = 2
ami = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI (HVM), SSD Volume Type
instance_type = "t2.micro"
availability_zone = random_shuffle.az_list.result[count.index]
}
The main use case for this is to provide an easy way to generate unique, memorable names for resources without having to come up with them manually.
resource "random_pet" "bucket_name" {
prefix = "my-unique-bucket"
length = 4
}
resource "aws_s3_bucket" "example" {
bucket = random_pet.bucket_name.id
tags = {
Name = "My bucket"
Environment = "Dev"
}
}
Nothing else is needed besides the resource when using random_UUID, as it calls go-uuid to generate the UUID:
resource "random_uuid" "test" {
}
By design, the values generated as part of the random provider will remain the same during every new Terraform plan and apply, unless told otherwise by a “keeper” in the configuration file. Keepers reference an attribute in the Terraform code, that if changed, will change the random value. The goal is to make the value of the random resource predictable in how it behaves. For example, you might want the name of an ec2 instance to remain the same unless the AMI, instance type, or environment type changes:
# Define variables
variable "environment" {
type = string
default = "stage"
}
variable "instance_type" {
type = string
default = "t2.micro"
}
variable "ami_id" {
type = string
default = "ami-09bd3f9be7c1b8217"
}
# Generate a random ID
resource "random_id" "server_id" {
keepers = {
# Generate a new id when these values change
ami_id = var.ami_id
instance_type = var.instance_type
environment = var.environment
}
byte_length = 8
}
# Create an EC2 instance
resource "aws_instance" "example" {
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = "server-${var.environment}-${random_id.server_id.hex}"
Environment = var.environment
some_tag = "tag123"
}
}
The random Terraform provider is a good resource to use when testing and simulation is needed. Rather than leaving it up to human error, the random provider can ensure proper values are generated based on rules. As you try out the random provider, it’s important to try out the keepers argument to see how resources change based on it.