When working with Puppet, you might need to access environment variables that are set in the Puppet master's environment. This becomes particularly useful when you want to:
- Dynamically adjust configurations based on deployment environments
- Pass sensitive information without hardcoding in manifests
- Create environment-specific behaviors in your infrastructure code
Puppet provides several ways to access environment variables from within your manifests:
1. Using the $::environment Variable
Puppet automatically provides the current environment name through the $::environment
variable:
# Example: Conditionally include classes based on environment
if $::environment == 'production' {
include nginx::production_config
} else {
include nginx::development_config
}
2. Accessing System Environment Variables
For accessing other environment variables available to the Puppet master process:
# Using the $::facts hash (requires Facter)
$db_host = $facts['env']['DB_HOST'] ? {
undef => 'localhost',
default => $facts['env']['DB_HOST']
}
# Alternative method using the $::environment special variable
$app_env = getvar('::environment')
3. Using External Data Lookups
A more robust approach for production environments:
# In hiera.yaml
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Environment variables"
lookup_key: env_lookup
options:
variables: %{facts.env}
# In your manifest
$api_key = lookup('API_KEY', String, 'first')
When working with environment variables in Puppet:
- Always provide default values for critical variables
- Use the
getvar()
function for safer variable access - Consider using Hiera for complex environment-specific configurations
- For sensitive data, prefer using Puppet's encrypted secrets management
Here's a complete example of using environment variables for database configuration:
class profile::database {
$db_host = pick($facts['env']['DB_HOST'], 'localhost')
$db_user = pick($facts['env']['DB_USER'], 'app_user')
$db_pass = pick($facts['env']['DB_PASS'], 'default_pass')
file { '/etc/app/database.conf':
ensure => file,
content => template('profile/database.conf.erb'),
owner => 'root',
group => 'root',
mode => '0600',
}
}
With corresponding template (database.conf.erb):
# Database Configuration
host: <%= @db_host %>
username: <%= @db_user %>
password: <%= @db_pass %>
When working with Puppet manifests, you might need to access environment variables from the Puppet daemon's environment. Unlike shell scripts where you can simply use $VAR
, Puppet requires specific approaches to access these values.
There are several ways to access environment variables in Puppet manifests:
1. Using the $::environment Variable
Puppet automatically provides access to its environment through the $::environment
variable:
# Example: Using built-in environment variable
if $::environment == 'production' {
notify { 'This is production environment': }
}
2. Accessing Custom Environment Variables
For custom environment variables, you'll need to use the generate()
function or external facts:
# Example: Using generate() to access env vars
$db_password = generate('/bin/sh', '-c', 'echo $DB_PASSWORD')
# Then use it in your resource
file { '/etc/db.conf':
content => "password=${db_password}",
mode => '0600'
}
3. Using External Facts
A more maintainable approach is to use external facts:
# Create a fact in /etc/puppetlabs/facter/facts.d/env_vars.sh
#!/bin/bash
echo "custom_env_var=$CUSTOM_ENV_VAR"
# Then access it in your manifest
$value = $facts['custom_env_var']
When dealing with environment variables in Puppet:
- Always sanitize input from environment variables
- Consider using Hiera for sensitive data instead of environment variables
- Use appropriate file permissions when writing files containing environment variables
- Log and monitor access to sensitive environment variables
For complex scenarios, you can create a custom Puppet function:
# lib/puppet/parser/functions/get_env.rb
module Puppet::Parser::Functions
newfunction(:get_env, :type => :rvalue) do |args|
ENV[args[0]]
end
end
# In your manifest:
$api_key = get_env('API_KEY')