I'm quite pleased with my solution to this. It's a shell script called by generate() function from puppet manifest. Password for each host is generated and stored in simple file as needed.

#!/bin/bash
# /etc/puppet/helpers/bacula/getpwd

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <pwd_name>"
    exit 1
fi

if [ ! -x /usr/bin/pwgen ]; then
    echo "missing pwgen!" >&2
    exit 1
fi

workdir="/etc/puppet/helpers/bacula/"
workfile="$workdir/passwd"
[ ! -r $workfile ] && exit 2
get_name="$1"

# get password from storage
pwd=$(awk -F: -v name="$get_name" '
BEGIN      { r = "NOTFOUND" }
name == $1 { r = $2         }
END        { printf "%s", r }
' "$workfile")

if [ "$pwd" = "NOTFOUND" ]; then
    # generate new password & store it
    len=$((60 + $RANDOM % 9 ))
    pwd=$(/usr/bin/pwgen -s $len 1)

    echo "${get_name}:${pwd}" >> $workfile
fi

# echo password (without new line)
echo -n "$pwd"

Install pwgen or another password generation tool, modify workdir variable for your system settings, check password lengths. In template file call it:

Password = <%= scope.function_generate("/etc/puppet/helpers/bacula/getpwd", bacula_dirname) %>

Puppet variable bacula_dirname should be based on hostname or set from extlookup() e.g.:

$bacula_dirname = "${hostname}-dir"

    $secret = "super special complicated long secure random string"
    $password = sha1("${fqdn}${secret}")
    notify {$password:}

Import $secret from another file (perhaps that one puppet class that you don't keep in version control) and there you have it. Magic password generation.

Passwords can be changed globally by changing $secret or individually in each declaration by using something other than $fqdn.