Encrypting sensitive data in puppet using hiera-eyaml
Puppet manifests can hold a lot of sensitive information. Sensitive information like passwords or certificates are used in the configuration of many applications. Exposing them in a puppet manifest is not ideal and may conflict with an organization's compliance policies. That is why data separation is very important aspect of secure puppet code.
Hiera is a pluggable Hierarchical Database. Hiera can help by keeping data out of puppet manifests. Puppet classes can look for data in hiera and hiera would search hierarchically and provide the first instance of value. Although Hiera is able to provide data separation, it cannot ensure security of sensitive information. Anyone with access to the Hiera data store will be able to see the data.
Secure Data Separation with Hiera-eyaml
Enter Hiera-eyaml. Hiera-eyaml is a backend for Hiera that provides per-value encryption of sensitive data within yaml files to be used by Puppet. The following puppet module can be used to manage hiera with eyaml support: https://forge.puppetlabs.com/hunner/hiera.
The module class can be used like below:
modules/profile/manifests/hieraconf.pp
class profile::hieraconf { # hiera configuration class { 'hiera': hierarchy => [ '%{environment}/%{calling_class}', '%{environment}', '%{fqdn}', 'common', 'accounts', 'dev' ], } }
The /etc/hiera.conf would look like following after the puppet run:
/etc/puppet/hiera.yaml
# managed by puppet --- :backends: - yaml :logger: console :hierarchy: - "%{environment}/%{calling_class}" - "%{environment}" - "%{fqdn}" - common - accounts - dev :yaml: :datadir: /etc/puppet/hieradata
Moving Data to Hiera
In following example, diamond collector for Mongodb does have data like, hosts, user and password. The collector is only enabled for grafana.pythian.com host.
modules/profile/manifests/diamond_coll.pp
diamond::collector { 'MongoDBCollector': options => { enabled => $fqdn ? { /grafana.pythian.com/ => True, default => false }, hosts => 'abc.pythian.com,xyz.pythian.com', user => 'grafana', passwd => 'xxxx', } }
To move the data to hiera, create_resources function can be used in the manifest.
modules/profile/manifests/diamond_coll.pp
class profile::diamond_coll{ $mycollectors = hiera('diamond::collectors', {}) create_resources('diamond::collector', $mycollectors) }
Then a new yaml file can be created and diamond::collectors code for MongoDBCollector can be abstracted like below:
hieradata/grafana.pythian.com.yaml
--- diamond::collectors: MongoDBCollector: options: enabled: True hosts: abc.pythian.com,xyz.pythian.com user: grafana passwd: xxxx
Implementing Hiera-eyaml
Hiera puppet code can be changed to following to enable eyaml
class profile::hieraconf { # hiera configuration class { 'hiera': hierarchy => [ '%{environment}/%{calling_class}', '%{environment}', '%{fqdn}', 'common', 'accounts', 'dev' ], eyaml => true, eyaml_datadir => '/etc/puppet/hieradata', eyaml_extension => 'eyaml', } }
This will add the eyaml backend to puppet after a puppet run on the puppet server. The process involves:
- Installing the hiera-eyaml gem.
- Creating PKCS#7 keys via
eyaml createkeys(Private:/etc/puppet/keys/private_key.pkcs7.pem, Public:/etc/puppet/keys/public_key.pkcs7.pem). - Updating
/etc/hiera.confto include the eyaml backend and key paths.
Note that the Puppetmaster needs to be restarted after these changes to apply the new configuration.
Working with the eyaml Command Line
Eyaml commands should be executed in a directory containing the keys directory (e.g., /etc/puppet).
Encrypting Passwords
The following command can be used to encrypt a password. It provides both string and block options
# eyaml encrypt -p Enter password: **** string: ENC[PKCS7,MIIBeQYJKoZIhvcN[..]Fg3jAmdlCLbQ] OR block: > ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw...]
Decrypting and Using Encrypted Data
To decrypt, use the following: # eyaml decrypt -s 'ENC[PKCS7,MIIBeQYJKoZIhvcN[..]Fg3jAmdlCLbQ]'
While using our previous example, the hiera file would look like following. We also have to rename the file to .eyaml from .yaml.
hieradata/grafana.pythian.com.eyam
--- diamond::collectors: MongoDBCollector: options: enabled: True hosts: abc.pythian.com,xyz.pythian.com user: grafana passwd: ENC[PKCS7,MIIBeQYJKoZIhvcN[..]Fg3jAmdlCLbQ]
Advanced Usage: Encrypting Certificates
Here is a standard file resource used to copy an SSL certificate
file { '/etc/logstash/certs/logstash-forwarder.crt': ensure => present, mode => '0644', owner => 'root', group => 'root', source => 'puppet:///modules/logstash/logstash-forwarder.crt', }
The file resource can be moved to hiera using hiera_hash and then encrypted using the following command: # eyaml encrypt -f modules/logstash/files/logstash-forwarder.crt
The returned string value can then be added using the content parameter of the file resource in your .eyaml file:
hieradata/common.eyam
files: '/etc/logstash-forwarder/certs/logstash-forwarder.crt': ensure: present mode: '0644' owner: 'root' group: 'root' content: 'ENC[PKCS7,MIIB+wYJKoZI[..]C609Oc2QUvxARaw==]'
Incorporating hiera-eyaml into your Puppet workflow ensures compliance and security for sensitive data, covering everything from simple strings to complex certificate files.
Managed IT Consulting Services
Are you ready to save up to 60% in operational costs?
Share this
Share this
More resources
Learn more about Pythian by reading the following blogs and articles.

DatabaseJournal Article on DBMS_OBFUSCATION_TOOLKIT
Cassandra Vulnerability - CVE-2020-13946 - Apache Cassandra RMI Rebind Vulnerability
Column Level Security BigQuery(GCP)
Ready to unlock value from your data?
With Pythian, you can accomplish your data transformation goals and more.