Using Functions¶
Provider functions enable custom transformations and computations in your Terraform configurations. This guide shows how to use functions effectively.
๐ค AI-Generated Content
This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.
What are Provider Functions?¶
Functions are callable operations that transform input into output without managing infrastructure. They're useful for: - Data transformation (JSON, strings, numbers) - Hash computation - Encoding/decoding operations - Custom business logic
Basic Usage¶
Call a provider function in Terraform:
terraform {
required_providers {
mycloud = {
source = "example.com/mycloud"
}
}
}
output "hashed_value" {
value = provider::mycloud::hash("hello world")
}
Common Patterns¶
String Transformation¶
locals {
uppercase_name = provider::mycloud::to_upper(var.server_name)
slugified = provider::mycloud::slugify("My Server Name")
}
JSON Manipulation¶
locals {
config_json = jsonencode({
name = "app"
port = 8080
})
transformed = provider::mycloud::jq_transform(
local.config_json,
".name + \"-v2\""
)
}
Hash Generation¶
resource "mycloud_api_key" "app" {
name = "app-key"
secret_hash = provider::mycloud::sha256(var.api_secret)
}
Encoding/Decoding¶
locals {
encoded_data = provider::mycloud::base64_encode("sensitive data")
decoded_data = provider::mycloud::base64_decode(var.encoded_config)
}
Using Functions with Resources¶
Functions integrate seamlessly with resource configuration:
resource "mycloud_server" "app" {
name = provider::mycloud::slugify(var.server_name)
environment = {
CONFIG_HASH = provider::mycloud::md5(file("config.json"))
}
tags = {
fingerprint = provider::mycloud::sha256(var.deployment_id)
}
}
Function Composition¶
Chain functions for complex transformations:
locals {
# Encode JSON, then base64 encode the result
encoded_config = provider::mycloud::base64_encode(
jsonencode(var.config)
)
# Transform JSON with JQ, then hash the result
config_hash = provider::mycloud::sha256(
provider::mycloud::jq_transform(
jsonencode(var.config),
"sort_keys"
)
)
}
Comparison with Built-in Functions¶
| Aspect | Provider Functions | Built-in Functions |
|---|---|---|
| Definition | Defined by providers | Built into Terraform |
| Namespace | provider::name::function |
Direct call (e.g., length()) |
| Scope | Provider-specific logic | General-purpose |
| Examples | provider::mycloud::hash |
length, concat, merge |
Use built-in functions when possible; use provider functions for domain-specific operations.
Best Practices¶
1. Use for Domain Logic¶
Provider functions should encapsulate provider-specific logic:
# Good: Provider-specific validation
resource "mycloud_server" "app" {
name = provider::mycloud::validate_name(var.server_name)
}
# Avoid: Use built-in functions for generic operations
# Bad:
value = provider::mycloud::to_upper(var.name)
# Good:
value = upper(var.name)
2. Keep Functions Pure¶
Functions should be deterministic (same input = same output):
# Good: Pure function
hash = provider::mycloud::sha256("data")
# Avoid: Functions that depend on external state
# (Use data sources for this instead)
3. Document Function Usage¶
Add comments explaining function purpose:
locals {
# Hash server configuration for change detection
# Uses SHA-256 to ensure consistent length
config_fingerprint = provider::mycloud::sha256(
jsonencode(var.server_config)
)
}
Examples from pyvider-components¶
The pyvider-components repository includes function examples:
- String functions (
upper,lower,slugify) - Numeric functions (
add,multiply,round) - JQ transformation functions
- Hash and encoding functions
Real-World Use Cases¶
Configuration Fingerprinting¶
resource "mycloud_deployment" "app" {
name = "app-deployment"
config_hash = provider::mycloud::sha256(
jsonencode({
version = var.app_version
environment = var.environment
replicas = var.replica_count
})
)
# Triggers redeployment when config changes
triggers = {
config = provider::mycloud::sha256(
file("${path.module}/config.yaml")
)
}
}
Data Transformation¶
locals {
# Transform API response using JQ
processed_data = provider::mycloud::jq_transform(
data.http.api_response.body,
".items | map(.name) | sort"
)
}
Name Sanitization¶
resource "mycloud_bucket" "data" {
# Ensure bucket name meets provider requirements
name = provider::mycloud::sanitize_bucket_name(
"${var.project}-${var.environment}-data"
)
}
Debugging Functions¶
Test function output using terraform console:
$ terraform console
> provider::mycloud::hash("test")
"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
> provider::mycloud::slugify("My Server Name")
"my-server-name"
Performance Considerations¶
Functions execute during planning:
# Evaluated once during plan
locals {
hash = provider::mycloud::sha256(file("large-file.json"))
}
# All resources use cached value
resource "mycloud_server" "web1" {
config_hash = local.hash
}
resource "mycloud_server" "web2" {
config_hash = local.hash
}
See Also¶
- Creating Functions - How to implement provider functions
- Best Practices - Provider development patterns
- Pyvider Components - Working examples