Convert the DPK to use Hiera Hash Merging

The way PeopleSoft delivers Puppet and the Hiera backend, is that everything you define in psft_customizations.yaml overrides configuration defined elsewhere. This is a useful setup when getting started with the DPK and Puppet. But when using YAML files to manage your configuration across multiple servers, you’ll quickly find that you are re-entering the same configuration in many files.

Hiera, the tool Puppet uses to read YAML files, has multiple ways to look up data. First, let’s cover what a YAML hash is. A hash is a key-value structure used in the DPK to store configuration. For example, this is the hash for PS_HOME information:

ps_home:
  db_type:    "%{hiera('db_platform')}"
  unicode_db: "%{hiera('unicode_db')}"
  location:   "%{hiera('ps_home_location')}"
  remove:     true

The main hash key is ps_home, and its value is all the configuration below it. The next level down has 4 keys with 4 corresponding values. The appserver_domain_list hash is a large one that contains all the configuration for one or more app server domains.

Under the delivered setup, if you want to change a value for a domain you need to copy the entire appserver_domain_list hash into your psft_customizations.yaml file and make the change. With Hiera hashing, you could define your domains in a file named appservers.yaml and any specific server changes can be defined in hostname.yaml. For example, the hostname.yaml file could contain this hash to override a configuration:

appserver_domain_list:
  DEV:
    feature_settings:
      SERVER_EVENTS: "Yes"
      DOMAIN_GW:     "Yes"

This provides far more flexibility when working with YAML files, but it does introduce some complexity. If you want to give this a try, here is how you can convert the current DPK to use Hiera hasing.

Find/Replace

I used VisualStudio Code to do the find/replace. Open up the etc\modules directory and do these against the modules\pt_profile folder:

  • Find: hiera('tns_admin_list
  • Replace: hiera_hash('tns_admin_list

I repeated this step for the following lookups.

  • tns_admin_list
  • appserver_domain_list
  • prcs_domain_list
  • pia_domain_list

You don’t want to replace all the lookups – that will cause errors. But, you can replace additional lookups if you want. Anything that is a hash in YAML files can use the hiera_hash() lookup function. If you wanted to make the ps_home: key support hash merging, you could replace hiera('ps_home with hiera_hash('ps_home.

Change the Hiera Merge Behavior

By default, Hiera will look at the top-level keys of a hash and not merge the underlying settings. Hiera hashing will merge all the values inside the hash. This means you can you define a hash with default settings in a common file (e.g, default app server settings). Then you can specify server or application specific settings in a YAML file for that domain or server.

To enable the hash merging, open the hiera.yaml file under c:\programdata\puppetlabs\hiera\etc.

Add this line to the file:

:merger_behavior: deeper

Hiera Lookup Order

With Hiera hash merging, we can utilize more than the psft_customizations.yaml file to manage our configuration. We can use multiple YAML files to control our configuration. For example, we could have:

  • [hostname].yaml
  • dev.yaml
  • hr.yaml
  • common.yaml

So, this setup would let us define common configuration that is shared across all applications in the common.yaml. Next, we could define anything related to servers that run HR applications in the hr.yaml. For any settings that are specific to the Development region, we can add them into dev.yaml. Last, for anything that is specific to the server, we can add into the [hostname].yaml file. This setup would let you re-use the common, hr, and dev YAML files across multiple servers, and anything specific to the server would be defined in [hostname].yaml.

In the hiera.yaml file, we can define this setup like this:

:hierarchy:
  - "%{::hostname}"
  - dev
  - hr
  - common

Test Hiera Hashing

On the command line, you can use the hiera utility to test lookups with Hiera. To do a normal Hiera lookup, use

hiera appserver_domain_list

To test a hiera hash lookup, use

hiera --hash appserver_domain_list

If you have multiple YAML files with the appserver_domain_list hash, the first option will only show you the results from the top of the list. The second test should show you a merged appserver_domain_list hash.

Encrypt psft_customizations.yaml Passwords

In the psft_customizations.yaml file we store configuration information for a server, including passwords. There is a project, hiera-eyaml, that supports encrypting and decrypting sensitive data in Hiera YAML files. Out of the box, the Windows-based DPK doesn’t work with hiera-eyaml. For Linux DPK, check out 2188771.1 – there is better support in the Linux DPK for hiera-eyaml.

In this post, we’ll walk through the steps to get hiera-eyaml working on Windows and how to encrypt data in the psft_customizations.yaml file.

Update RubyGems

The version of Ruby, and RubyGems, that ships with the DPK can’t install new Gems. The RubyGems version doesn’t support trust the site’s SSL certificate. To fix that, download the root certificate and tell RubyGems to trust it.

  1. Download the newer SSL certificate.
  2. Save the file as RubyGemsRootCA.pem
  3. Copy the new certificate to C:\Program Files\Puppet Labs\Puppet\sys\ruby\lib\ruby\2.0.0\rubygems\ssl_certs

Copying the new certificate to ssl_certs will tell RubyGems to trust any certificate signed by it. Now we can use RubyGems to install hiera-eyaml on the server.

Install hiera-eyaml

When Puppet is installed, it includes Ruby and RubyGems binaries because Puppet is written in Ruby. We’ll use the gem utility to install the hiera-eyaml RubyGem. First, we should update PATH to include Puppet’s Ruby binaries:

  1. $env:PATH += ";C:\Program Files\Puppet Labs\Puppet\sys\ruby\bin"
  2. gem install hiera-eyaml

RubyGems will install any dependencies and report the progress.

Fetching: trollop-2.1.2.gem (100%)
Successfully installed trollop-2.1.2
Fetching: highline-1.6.21.gem (100%)
Successfully installed highline-1.6.21
Fetching: hiera-eyaml-2.1.0.gem (100%)
Successfully installed hiera-eyaml-2.1.0
Parsing documentation for trollop-2.1.2
Installing ri documentation for trollop-2.1.2
Parsing documentation for highline-1.6.21
Installing ri documentation for highline-1.6.21
Parsing documentation for hiera-eyaml-2.1.0
Installing ri documentation for hiera-eyaml-2.1.0
3 gems installed

Keys

Hiera-eyaml uses it’s own Public and Private keys to encrypt and decrypt data. If you have inspected the puppet\ssl directory, you will see folders for public and private keys. These keys are used by Puppet to communicate with a Puppet Server. We use different keys for encrypting data in psft_customizations.yaml.

The keys should be created in the folder C:\ProgramData\PuppetLabs\puppet\etc\secure\keys\. To ensure the keys are created in the correct location, Hiera-eyaml and Hiera know where they are, we’ll create a configuration file for Hiera-eyaml.

  1. Create eyaml.yaml under C:\ProgramData\PuppetLabs\hiera\etc and add these values:

    ---    
    pkcs7_private_key: C:\ProgramData\PuppetLabs\puppet\etc\secure\keys\private_key.pkcs7.pem  
    pkcs7_public_key: C:\ProgramData\PuppetLabs\puppet\etc\secure\keys\public_key.pkcs7.pem
    
  2. Set the EYAML_CONFIG environment variable:

    $env:EYAML_CONFIG="C:\ProgramData\PuppetLabs\hiera\etc\eyaml.yaml"
    
  3. Create new encryption keys for Hiera-eyaml to use:

    eyaml createkeys
    

Keep these new keys safe and locked down; they decrypt your passwords!

Encrypt Passwords

Now that we have installed Hiera-eyaml and created keys, let’s do a quick test to make sure we can encrypt passwords. This test will encrypt the text “VP1”:

eyaml encrypt -s VP1

The output will look similar to this:

string: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEALsKtTfAXyHyE/k5r2U2ZZU98SqaQ5/ukfNR/FkOt9bNhoZ1EomqmqIc/06l7Tk5W4BYJA0mXV6ykLgOHYTAJbVPM8gXBuHsw1jh+/VC0er7evlzqtf7UjIvu3rTo+0LUm2X3imjbWHGhyrs2bxm0L1qpC2atlTSzEYrSc6OxkTpZA19Y8iEJxFb+F0fGwsQ3SRVJD1J3Jwf0hAsHN/SXX/p2ywn5qz2BnlJl4wa7ragYv4aVBGbGF3ThvYMCTzNiFHtyHdCFvPX9i/t0fpDUJY76ndAl/T4q/Stopnq6Gm9vLJH5EC6KMUQZzb0ssDHriojQgUH7uFt8/Wn9vFeTQTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFcUOesdHoJgYi5PnXGmkAgBDbEJsr/tDXbDpJu7+xz9uL]

OR

block: >
    ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw
    DQYJKoZIhvcNAQEBBQAEggEALsKtTfAXyHyE/k5r2U2ZZU98SqaQ5/ukfNR/
    FkOt9bNhoZ1EomqmqIc/06l7Tk5W4BYJA0mXV6ykLgOHYTAJbVPM8gXBuHsw
    1jh+/VC0er7evlzqtf7UjIvu3rTo+0LUm2X3imjbWHGhyrs2bxm0L1qpC2at
    lTSzEYrSc6OxkTpZA19Y8iEJxFb+F0fGwsQ3SRVJD1J3Jwf0hAsHN/SXX/p2
    ywn5qz2BnlJl4wa7ragYv4aVBGbGF3ThvYMCTzNiFHtyHdCFvPX9i/t0fpDU
    JY76ndAl/T4q/Stopnq6Gm9vLJH5EC6KMUQZzb0ssDHriojQgUH7uFt8/Wn9
    vFeTQTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBFcUOesdHoJgYi5PnX
    GmkAgBDbEJsr/tDXbDpJu7+xz9uL]

Hiera-eyaml gives two options for output: string and block. For psft_customizations.yaml I’m using the string output. It’s cleaner and easier to insert into the file. We can request string output only and assign a label to the encrypted password:

eyaml encrypt -s VP1 -o string -q -l db_user_pwd

The output should look like this:

db_user_pwd: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAV2y+yriBfuFlXspBIzZ8eBEOow7FU7mcwYL1HCpHd+XrwIliMTgDj+4X47XXQ3bce4WRvaezHUNahJQF4OZrwlGdCgXYeFG4dYvMEg/75T0704I2+y/XmLpI3Y5swd3L9LnHfxpAm6x8AJpf2yybSP4rsD1IxZgrpjy1CjFe3GuRW9ZcNFkNq5WofRweoX4C9QgNp1bmXQnJym+ZnVe1y7vQ9iEY336vF2FH3wJNgqRIy+74RWj9F+OaAg78meSxM0eM7jm4fLa32cMmOLzfU/FGFhLFcQJ2FaAa5/SWmBSgtwDUXsGaLcSa0R2nfQZrbRWmlP+s1WYL9MzkLFTEoDA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDMAfrBMvJ+HRA+iL4zyQppgBBcHlLe8hUl6JD1jFXH/N22]

We can pass the output of this command into the clipboard and then paste the line directly into psft_customizations.yaml:

eyaml encrypt -s VP1 -o string -q -l db_user_pwd | set-clipboard

set-clipboard requires WMF 5.0

Edit YAML Files

Encrypting passwords on the command line is great, but what if you want to edit all of the passwords in your psft_customizations.yaml file at once? Hiera-eyaml has an edit command that will decrypt the passwords in psft_customizations.yaml and open the file in a text editor for you. First, we need to set the EDITOR environment variable:

  1. $env:EDITOR="notepad.exe"
  2. eyaml edit .\psft_customizations.yaml

Notepad will open the psft_customizations.yaml file. At the top of the file, you will see a large comment block explaining how to add and edit passwords. (The comment block will go away when you close Notepad.)

Add New Passwords

To add a new password, you wrap the plain text password inside the brackets in this syntax: DEC::PKCS7[plaintextpassword]! For example,

db_user_pwd:     DEC::PKCS7[VP1]!

If you save and close the file, and open psft_customizations.yaml directly in Notepad, you will see the db_user_pwd: password is encrypted.

db_user_pwd:  ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAdGWx7WeuGw3lULsdDANpYotX66B1wzO3U9H47RLJA+s4cIVg5z2JtzTp+uHOp9L9SdcNyzsvo6+uPY29DxMsaIUv9Dfa5LWKv+GZypH4myJYxbNfhtRE5TcLWxxwTSji9WYxDyFu8FFJGIkdNcEzN4svG6CknDhmA/od/NPanQg+xWbjP2qJkiOMi2fDwPJd11dev7Qm4NcwkZzdcsMBpkSgL3eL2dZ/BzdJndWrsGlYfUAy0TLxJD9a4aBCiwYoWWmmS4smnmtmti0R1DPEs8BpAl5L76JItMUwzRsnmu5IZ8odxn8rQZQNJaOVk/oScp4SRIgCh5+tYp7FMvgM/jA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCqrQ+GokeF23Of2odDkv5JgBBulnH4XkLOrQBEy+fa7cMr]

Excellent – we have encrypted passwords!

Edit Passwords

The next step is to edit existing encrypted passwords in the psft_customizations.yaml file. The eyaml edit command will open the file and decrypt passwords. The password syntax will be slightly different – it will have a number assigned to the password: db_user_pwd: DEC(1)::PKCS7[VP1]!

The (1) is used internally by Hiera-eyaml, so don’t change it. But you can change the password inside the square brackets. After changing the password, save and close the file and your updated passwords will be encrypted.

Enable eyaml with the DPK

When we push psft_customizations.yaml out to servers, we also need to ensure each server has the keys used to encrypt the passwords, and also knows about Hiera-eyaml. First, if you are using the encrypted passwords on more than one server, copy the puppet\etc\secure\keys folder to each server.

Next, Hiera needs to know that we are using Hiera-eyaml. In C:\ProgramData\PuppetLabs\hiera\etc\hiera.yaml, enable eyaml as a back-end format by adding - eyaml to the ;backends: section:

:backends:
    - yaml
    - eyaml

Verify that the :eyaml: section is at the bottom of hiera.yaml. Change the paths to the Public and Private keys. If you followed the steps above and created them in puppet\etc\secure\keys, the paths will look like this:

:eyaml:
    :datadir: C:\ProgramData\PuppetLabs\puppet\etc\data
    :extension: yaml

    :pkcs7_private_key: C:\ProgramData\PuppetLabs\puppet\etc\secure\keys\private_key.pkcs7.pem
    :pkcs7_public_key:  C:\ProgramData\PuppetLabs\puppet\etc\secure\keys\public_key.pkcs7.pem

Save hiera.yaml and let’s test our configuration.

Testing Hiera-eyaml

To test Hiera-eyaml and Puppet working together, we’ll encrypt the a password in psft_customizations.yaml and update UserPswd= value in psappsrv.cfg.

  1. Open psft_customizations.yaml with eyaml edit and add the line:

    db_user_pwd: DEC::PKCS7[VP1]!
    
  2. Save and close psft_customizations.yaml.

  3. Save this code below as pwd.pp and save it to puppet\etc\manifests. Change the $configFile path to point to your psappsrv.cfg file.

    $configFile = 'C:/Users/vagrant/psft/pt/8.55/appserv/APPDOM/psappsrv.cfg' 
    ini_setting { "eyaml_test": 
        ensure => present, 
        path => $configFile, 
        section => 'Startup', 
        setting => 'UserPswd', 
        value => hiera('db_user_pwd'), 
    }
    
  4. Change directories to puppet\etc\manifests.

  5. Run puppet apply .\pwd.pp --trace --debug

  6. After the run is done, open your psappsrv.cfg file. You should see UserPswd=VP1 in the file.

If the test above worked, you’re all set to use Hiera-eyaml with the DPK and Puppet. Once Hiera knows about Hiera-eyaml, any data in Hiera can be encrypted. Happy encrypting!