Improving Windows Services from the DPK

A common theme we write about on the blog is how to make the DPK work with multiple environments on the same machine. It’s common to run a DEV and TST on the same server. The DPK can build those environments, but there are a few changes to make the setup run well. On Windows, the services the DPK creates makes an assumption that breaks when we run multiple environments.

When starting a domain via Windows services, the service assumes that the environment variables are set for that environment. If you create your DEV environment via the DPK, that’s a good assumption. But, if you create a TST environment next, the environment variables are set to TST. When you attempt to start the DEV domain via Windows services, the domain start will fail.

To resolve this, we can improve the Ruby script that starts our domains. Under the ps_cfg_home\appserv\DOMAIN folder, there are Ruby scripts that are called by the Windows service. For the app server, it’s appserver_win_service.rb. These scripts will look for the PS_CFG_HOME environment variable and start the domains it finds under that home. We can add a line in the file to point to the correct PS_CFG_HOME location like this:

ENV["PS_CFG_HOME"]=c:\psft\cfg\DEV

While we can modify the file directly, the DPK way of handling this is to update the template in the DPK. Then, whenever we rebuild our domains the code change is automatically included.

The Ruby scripts to start/stop domains are templates in the DPK. The templates are stored under peoplesoft_base\dpk\puppet\modules\pt_config\files\pt_appserver\appserver_win_service.erb (replace pt_appserver with pt_prcs or pt_pia for the batch and PIA services.)

To make the environment variables we add dynamic, we can reference variables that exist in the Ruby environment that calls the ERB template. In the program appserver_domain_boot.rb, the variables ps_home and ps_cfg_home are set. We will use those variables to build our environment variables.

ENV["PS_HOME"] = "<%= ps_home %>"
ENV["PS_CFG_HOME"] = "<%= ps_cfg_home %>"
system("<%= ps_home %>/appserv/psadmin -c start -d <%= domain_name %>")

The <%= %> tags will output the value of that command or variable. So in our case, we are outputting the string value of ps_cfg_home.

The result of this file will look like this:

ENV["PS_HOME"] = "c:\\psft\\pt\ps_home8.56.08"
ENV["PS_CFG_HOME"] = "c:\\psft\\cfg\\DEV"
system("c:\\psft\\pt\ps_home8.56.08\\appserv\\psadmin -c start -d DEV")

When we run Puppet the next time, our Windows service will have it’s environment variables set before starting or stopping a domain.

#123 – ps_patch


This week on the podcast Dan and Kyle discuss Colton Fischer’s Web Profile discovery, Kyle shares his CPU Patching process and how he automated the process then Dan discusses how he resolved a PIA domain bug.

Show Notes

#121 – Under Review


That’s right, its another Change Assistant episode. Dan shares some updates to Change Assistant in 8.56, some 8.57 speculation, and applying PeopleTools Upgrades headlessly. Kyle shares an ACM discovery, and the PeopleTools Idea Space updates.

Show Notes

#116 – ps-terraform


This week on the podcast, Dan shares a new project called ps-terraform to help you build PeopleSoft Images on AWS. Kyle tries to resolve a Friday Night Ghost issue and Dan follows up on his love for Continuous Integration and the DPK.

Show Notes

  • Elasticsearch DPK Install Methods @ 1:00
  • GitLab Continuous Integration Follow-up @ 5:30
  • Friday Night Ghost @ 19:00
  • Ps-terraform @ 31:00

#113 – Rundeck and Bolt

This week on the podcast, Kyle and Dan discuss Bolt, a new tool from Puppet to run commands and scripts remotely on servers. Dan also talks about setting up a new Rundeck server and using Bolt with Rundeck.

Show Notes

#105 – Agile PeopleSoft

This week on the podcast, Charlie Sinks joins us to talk about the Upper Midwest Regional User Group. We talk about using Agile with PeopleSoft, our experiences with Elasticearch, the Idea Space for PeopleTools, and using Git with PeopleSoft.

Show Notes

  • Chatbots Demo @ 3:30
  • Agile and PeopleSoft @ 11:00
    • SCRUM
    • Kanban
    • SAFE
  • Elasticsearch Experiences @ 33:45
  • PeopleTools 8.56 Updates @ 43:30
  • Testing Effort for Certifications @ 45:30
    • AIX/Solaris: pspuppet.sh is used to prepare the environment. Need to invoke if the bootstrap or puppet failed and you need to re-run
  • Idea Space @ 50:15
  • Advanced PS Admin Talk @ 56:30
  • Orchestration @ 61:00
  • Using Git @ 67:30

#97 – Dozens of Us

This week on the podcast, Dan and Kyle discuss strategies to organize and manage Event Mapping code, writing code that other people will use, trying to work with Push Notifications and custom ACM modules. Kyle ends the podcast with a funny story about searching for images.
 

Show Notes

 

Using Puppet Environments with the DPK

Since the Deployment Packages were released with PeopleTools 8.55, one of my criticisms has been that the DPK is a bit of a sledgehammer. If you define multiple PeopleSoft environments on a server and you want to configure one web server, ALL the domains that the DPK knows about are shut down.

Puppet has an Environments feature that lets you segregate your code and data. While the DPK does not support Puppet Environments out of the box, we can use them to make the DPK less of a sledgehammer when managing our domains. (There is still some sledgehammering going on, so go vote for this idea).

While environments let you separate the modules, manifests and data folder, in this post we’ll separate just the data folder. This will let us share a common set of code (the manifests and modules folders) but the configuration of each domain will be different.

If you want to extend this to the modules and manifests folder, copy those into the environment folders with the environment-specific changes. This is useful for testing new code changes or if you want an environment to use a different DPK Role in the site.pp file.

Create Environment Folders

  1. Make a new dev and tst folders under c:\programdata\puppetlabs\puppet\etc\environments

You can have multiple environments under this folder – as many as you want. A strategy that I’m testing is using the database name as the environment name. For this post, I’ll stick with dev and tst

  1. Copy your YAML files from puppet\etc\data to puppet\etc\environments\dev\data and puppet\etc\ environments\tst\data.

Configure Puppet Environment

Under the puppet\etc folder, add (or modify) the puppet.conf file to look like this:

[main]
environment=production
parser=future
environmentpath=c:\programdata\puppetlabs\puppet\etc\environments
hiera_config=c:\programdata\puppetlabs\hiera\etc\hiera.yaml
basemodulepath=c:\programdata\puppetlabs\puppet\etc\modules

This file tells Puppet where to look for your environments, your Hiera configuration, your default module location, and the default Puppet Environment.

Last, we’ll modify the hiera.yaml file in c:\programdata\puppetlabs\hiera\etc to include environments:

---
:backends:
  - yaml

:hierarchy:
  - "environments/%{::environment}/data/psft_customizations"
  - "environments/%{::environment}/data/psft_configuration"
  - "environments/%{::environment}/data/psft_deployment"
  - "environments/%{::environment}/data/psft_unix_system"
  - "environments/%{::environment}/data/defaults"

:yaml:
  :datadir: c:\programdata\puppetlabs\puppet\etc

If you want to share some of the files, like the defaults.yaml or the psft_unix_system.yaml file, you could keep those under the main puppet\etc\data folder. Your hiera.yaml file would look like this:

---
:backends:
  - yaml

:hierarchy:
  - "environments/%{::environment}/data/psft_customizations"
  - "environments/%{::environment}/data/psft_configuration"
  - "environments/%{::environment}/data/psft_deployment"
  - data/psft_unix_system
  - data/defaults

:yaml:
  :datadir: c:\programdata\puppetlabs\puppet\etc

Test the Environments

Once our Puppet changes are complete we can test some builds. When we run puppet apply, we’ll add an additional paratemer: the environment. To build my dev environment domains, I’ll use this procedure:

cd c:\programdata\puppetlabs\puppet\etc\manifests
puppet apply .\site.pp --environment=dev --debug

Once the dev domains are built and running, you can kick off the tst build with:

puppet apply .\site.pp --environment=tst --debug

As the tst environment is building, your dev domains should stay up and not be affected by the Puppet run. If they are affected, you may have some YAML changes that need to be made. Make sure your configuration’s between the environment don’t overlap (e.g, same PS_CFG_HOME and domain names).

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:

:merge_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.