GitHub: https://github.com/joshbeard/puppet-websphere
Puppet Forge: https://forge.puppetlabs.com/joshbeard/websphere
Manages the deployment and configuration of IBM WebSphere Cells.
- DMGR systems and configuration
- Application Servers and configuration
- IHS Servers in the context of WebSphere
Most documentation has been split into individual documents in the docs directory and linked to, in context, throughout this document.
There's plenty to do here. WebSphere is a huge stack and this module only manages some core functions. See CONTRIBUTING.md for information on contributing.
Some of the immediate needs:
- Revise types/providers. Clean up the code, add validation and documentation.
websphere_cluster_member
doesn't manage the individual properties on the first run. The first run creates the member and subsequent runs configure it. Need to resolve this - it's a provider issue.
- Manage WAS security.
- Manage certificates.
- Improve the run order issues. See the ISSUES.md file for details.
- Documentation and examples.
- Vagrant environment (I have one, just need to clean it up)
The following facts are provided by this module:
Fact name | Description |
---|---|
instance_name | This is the name of a WebSphere instance. Basically, the base directory name. |
instance_target | The full path to where a particular instance is installed. |
instance_user | The user that "owns" this instance. |
instance_group | The group that "owns" this instance. |
instance_profilebase | The full path to where profiles for this instance are located. |
instance_version | The version of WebSphere an instance is running. |
instance_package | The package name a WebSphere instance was installed from. |
websphere_profiles | A comma-separated list of profiles discovered on a system across instances. |
websphere_profile_cell_node_soap | The SOAP port for an instance. This is particuarily relevant on the DMGR so App servers can federate with it. |
Examples:
Assuming we've installed a WebSphere instance called "WebSphere":
websphere_group => webadmins
websphere_name => WebSphere
websphere_package => com.ibm.websphere.NDTRIAL.v85
websphere_profile_base => /opt/IBM/WebSphere/AppServer/profiles
websphere_target => /opt/IBM/WebSphere/AppServer
websphere_user => webadmin
websphere_version => 8.5.5004.20141119_1746
websphere_base_dir => /optIBM
websphere_profile_dmgr_01_cell_01_appnode01_soap => 8878
websphere_profile_dmgr_01_cell_01_node_dmgr_01_soap => 8879
websphere_profiles => PROFILE_DMGR_01
Or if we've installed a WebSphere instance called "WebSphere85" to a custom location:
websphere85_group => webadmins
websphere85_name => WebSphere85
websphere85_package => com.ibm.websphere.NDTRIAL.v85
websphere85_profile_base => /opt/myorg/IBM/WebSphere85/AppServer/profiles
websphere85_target => /opt/myorg/IBM/WebSphere85/AppServer
websphere85_user => webadmin
websphere85_version => 8.5.5004.20141119_1746
websphere_base_dir => /opt/myorg/IBM
websphere_profile_dmgr_01_cell_01_appnode01_soap => 8878
websphere_profile_dmgr_01_cell_01_node_dmgr_01_soap => 8879
websphere_profiles => PROFILE_DMGR_01
Only one class currently exists in this class - the base class. Since this module was designed for "multiple instances of anything", most things are defined types.
Class Name | Description |
---|---|
websphere | Base class. Manages a user and group, a couple of data directories for WebSphere, and a YAML fact that includes metadata about WebSphere installations. |
The following directories will be managed by the base class:
${base_dir}/.java
${base_dir}/.java/systemPrefs
${base_dir}/.java/userPrefs
${base_dir}/workspace
/opt/IBM/.java
/opt/IBM/.java/systemPrefs
/opt/IBM/.java/userPrefs
/opt/IBM/workspace
These directories appear to be necessary for the proper functionality of the various IBM tools we use to manage the WebSphere deployment.
The following defined types are provided by this module.
Each defined type is documented in a separate document in the docs/defines directory.
Defined Type Name | Description |
---|---|
websphere::instance | Manages the base installation of a WebSphere instance. |
websphere::package | Manages the installation of IBM packages and the ownership of the installation directory. |
websphere::ownership | Manages the ownership of a specified path. See notes below for the usecase for this. |
websphere::profile::dmgr | Manages a DMGR profile. |
websphere::profile::appserver | Manages an application server profile. |
websphere::profile::service | Manages the service for a profile (DMGR or Application Server). |
websphere::ihs::instance | Manages the installation of an IHS instance. |
websphere::ihs::server | Manages server instances on an IHS system. |
websphere::cluster | Manage WebSphere clusters. |
websphere::cluster::member | Manage WebSphere cluster members and their services. |
The following native (Ruby) types are provided by this module.
Each type is documented in a separate document in the docs/types directory.
Type | Description |
---|---|
websphere_app_server | Manages WebSphere Application Servers |
websphere_cluster | Manages the creation of WebSphere clusters on a DMGR. |
websphere_cluster_member | Manages cluster members, including various settings. |
websphere_cluster_member_service | Manages a cluster member service. |
websphere_federate | Manages the federation of an application server with a cell. |
websphere_jdbc_datasource | Manages datasources. |
websphere_jdbc_provider | Manages JDBC providers. |
websphere_jvm_log | Manages the JVM logging properties for nodes or servers. |
websphere_node | Manages the creation of unmanaged nodes in a WebSphere cell. |
websphere_sdk | Manages the SDK version for a WebSphere profile or server. |
websphere_variable | Manages WebSphere environment variables. |
websphere_web_server | Manages the creation and configuration of WebSphere web servers. |
Before you do anything with this module, you need IBM Installation Manager installed.
A module has been created to manage the IBM Installation Manager, available at https://github.com/joshbeard/puppet-ibm_installation_manager
Once you have the module, you can manage the installation of the Installation Manager like this:
class { 'ibm_installation_manager':
source_dir => '/mnt/myorg/IM',
target => '/opt/IBM/InstallationManager',
}
Here, we assume the package downloaded from IBM has been extracted to
/mnt/myorg/IM
and we want to install it to /opt/IBM/InstallationManager
References:
To get started, declare the base class. You should declare this on any server that will use this module - DMGR, App Servers, and IHS.
In this example, we provide a user and a group. We want the installation to be owned and ran by this user/group.
We also specify a base_dir
(although /opt/IBM
is the default). This is
the directory where our IBM software goes. This is the IBM default.
class { 'websphere':
user => 'webadmin',
group => 'webadmins',
base_dir => '/opt/IBM',
}
The word "instance" used throughout this module basically refers to a complete installation of WebSphere. Ideally, you'd just have a single instance of WebSphere on a given system. This module, however, does offer the flexibility to have multiple installations. This is useful for cases where you want two different major versions available (e.g. WAS 7 and WAS 8).
In this example, we're installing to the IBM-default location of
/opt/IBM/WebSphere/AppServer
. This is actually the module default as well,
but it's specified here for clarity. We also provide a package and version.
We're assuming the WebSphere installer has been downloaded and extracted to
/mnt/myorg/was
and the corresponding repository.config
file is located
there.
The user and group don't need to be specified here, because we specified them
when we declared the base class. The instance
defined type will use those
as its defaults.
websphere::instance { 'WebSphere85':
target => '/opt/IBM/WebSphere/AppServer',
package => 'com.ibm.websphere.NDTRIAL.v85',
version => '8.5.5000.20130514_1044',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
repository => '/mnt/myorg/was/repository.config',
Let's assume we have a response file that we want to use. The response file contains the package name, version, repository location, and the target to install to. We can use it like this:
websphere::instance { 'WebSphere85':
response => '/mnt/myorg/was/was85_response.xml',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
}
References:
It's common to install an IBM "FixPack" after the base installation. Following
the examples above, we've installed WebSphere 8.5.5.0. Let's say we want to
install the WebSphere 8.5.5.4 fixpack. We can do so using the
websphere::package
defined type:
websphere::package { 'WebSphere_8554':
ensure => 'present',
package => 'com.ibm.websphere.NDTRIAL.v85',
version => '8.5.5004.20141119_1746',
repository => '/mnt/myorg/was_8554/repository.config',
target => '/opt/IBM/WebSphere/AppServer',
require => Websphere::Instance['WebSphere85'],
}
In the above example, we're installing the 8.5.5.4 FixPack right on top of
the existing 8.5.5.0 installation. We also use the require
metaparameter
to enforce the ordering.
An example of installing Java 7:
websphere::package { 'Java7':
ensure => 'present',
package => 'com.ibm.websphere.IBMJAVA.v71',
version => '7.1.2000.20141116_0823',
target => '/opt/IBM/WebSphere/AppServer',
repository => '/mnt/myorg/java7/repository.config',
require => Websphere::Package['WebSphere_8554'],
}
In the above example, we install the Java 7 package to our WebSphere location.
We also use the require
metaparameter here to enforce ordering - we want
the Java7 installation to be managed after WebSphere 8.5.5.4 is.
References:
- websphere::package
- websphere::ownership
- ibm_pkg (external)
Once we have the base software installed, we need to create a profile. A profile is basically the runtime enironment. A server can potentially have multiple profiles. A DMGR profile is ultimately what defines a given "cell" in WebSphere.
In the following example, we create a DMGR profile called PROFILE_DMGR_01
and call the cell that gets created CELL_01
. We also call the DMGR node
dmgrNode01
in this example.
Finally, we use the subscribe
metaparameter to set relationships with our
base installations. If those change, the resources in
websphere::profile::dmgr
will be refreshed if needed.
# Example DMGR profile
websphere::profile::dmgr { 'PROFILE_DMGR_01':
instance_base => '/opt/IBM/WebSphere/AppServer',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
cell => 'CELL_01',
node_name => 'dmgrNode01',
subscribe => [
Websphere::Package['Websphere_8554'],
Websphere::Package['Java7'],
],
}
When a DMGR profile is created, this module will use Puppet's exported resources to export a file resource that contains information needed for application servers to federate with it. This includes the SOAP port and the host name (fqdn).
The DMGR profile will, by default, collect any exported websphere_node
,
websphere_web_server
, and websphere_jvm_log
resources.
An application server's profile looks quite similar:
# Example Application Server profile
websphere::profile::appserver { 'PROFILE_APP_001':
instance_base => '/opt/IBM/WebSphere/AppServer',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
cell => 'CELL_01',
template_path => '/opt/IBM/WebSphere/AppServer/profileTemplates/managed',
dmgr_host => 'dmgr.example.com',
node_name => 'appNode01',
manage_sdk => true,
sdk_name => '1.7.1_64',
}
Here, we provide the cell that we want to federate with. We also want to manage the SDK version and ensure it's set to '1.7.1_64'.
When creating an application server profile, the file resource that was exported by the DMGR will be collected. The criteria for collecting is a DMGR hostname and cell name. This allows the application server to know which SOAP port to use for federation. This is the default behavior of the module.
References:
- websphere::profile::dmgr
- websphere::profile::appserver
- websphere::profile::service
- websphere_sdk
- websphere_node
- websphere_web_server
- websphere_jvm_log
Once profiles are created on the DMGR and an application server, we're probably interested in creating a cluster and adding application servers to it.
DMGR
The DMGR should declare a websphere::cluster
resource:
# Manage a cluster on the DMGR
websphere::cluster { 'MyCluster01':
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
dmgr_profile => 'PROFILE_DMGR_01',
cell => 'CELL_01',
require => Websphere::Profile::Dmgr['PROFILE_DMGR_01'],
}
In this example, a cluster called MyCluster01
will be created. We need to
provide a profile_base
and dmgr_profile
to know where this cluster
should be created. Additionally, we use the require
metaparameter to set
a relationship between the profile and the cluster. We want to ensure that
the profile has been managed before attempting to manage the cluster.
Application Server
There's a couple of ways to add cluster members. The DMGR can explicitly declare each one or the members themselves can export a resource to do so.
In the following example, we define a websphere::cluster::member
resource
on an application server and export it. The two "at" symbols (@@) indicate
that this is an exported resource.
# Export myself as a cluster member
@@websphere::cluster::member { 'AppServer01':
ensure => 'present',
cluster => 'MyCluster01',
node => 'appNode01',
cell => 'CELL_01',
jvm_maximum_heap_size => '512',
jvm_verbose_mode_class => true,
jvm_verbose_garbage_collection => false,
total_transaction_timeout => '120',
client_inactivity_timeout => '20',
threadpool_webcontainer_max_size => '75',
runas_user => 'webadmin',
runas_group => 'webadmins',
}
In this example, we're adding a member from the node appNode01
that we
created when we managed the profile to the MyCluster01
cluster in the
CELL_01
cell. We're also specifying a few various JVM parameters, including
the "runas" user and group.
How does this work?
The DMGR declared the websphere::cluster
defined type, which will
automatically collect any exported resources that match its cell. Every
time Puppet runs on the DMGR, it will search for exported resources to
declare on that host.
On the application server, the "@@" prefixed to the resource type exports that resource, which can be collected by the DMGR the next time Puppet runs.
The examples above illustrate the module's default behavior. It is possible to manage clusters without exported resources.
If you do not want to use exported resources, the DMGR host can explicitly declare each member that it should add. For example:
websphere::cluster::member { 'AppServer01':
ensure => 'present',
cluster => 'MyCluster01',
node => 'appNode01',
cell => 'CELL_01',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
dmgr_profile => 'PROFILE_DMGR_01',
}
This is obviously less dynamic. The user also needs to ensure that the profile is ready on the application server.
References:
- websphere::cluster
- websphere::cluster::member
- websphere_cluster
- websphere_cluster_member
- websphere_cluster_member_service
Following the examples above, WebSphere should be installed with a fixpack and Java7, profiles should be created and federated, and a cluster should be created with the application server as a member.
At this point, we can tune our installation.
This module provides a type to manage WebSphere environment variables.
In the example below, we want to ensure a variable called LOG_ROOT
is set
for the node appNode01
.
Node scoped variable
# Example of a node scoped variable
websphere_variable { 'appNode01Logs':
ensure => 'present',
variable => 'LOG_ROOT',
value => '/var/log/websphere/wasmgmtlogs/appNode01',
scope => 'node',
node => 'appNode01',
cell => 'CELL_01',
dmgr_profile => 'PROFILE_APP_001',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
user => 'webadmin',
require => Websphere::Profile::Appserver['PROFILE_APP_001'],
}
Server scoped variable
# Example of a server scoped variable
# NOTE: This will cause a FAILURE during the first Puppet run because the
# cluster member has not yet been created on the DMGR.
websphere_variable { 'AppServer01Logs':
ensure => 'present',
variable => 'LOG_ROOT',
value => '/opt/log/websphere/appserverlogs',
scope => 'server',
server => 'AppServer01',
node => 'appNode01',
cell => 'CELL_01',
dmgr_profile => 'PROFILE_APP_001',
profile_base => $profile_base,
user => $user,
require => Websphere::Profile::Appserver['PROFILE_APP_001'],
}
In the example above, we manage a server scoped variable for the
AppServer01
server. The AppServer01
server was created as part of the
websphere::cluster::member
defined type.
A caveat here is that server-scoped variables cannot be managed until/unless a corresponding cluster member exists on the DMGR. Some solutions to this are being thought about, but that's the current reality.
Optionally, these variables can be declared on the DMGR. This will enable you to set relationships between the cluster member and the variable resource. However, this sacrifices some of the dynamic nature of the module.
Reference:
This module provides a websphere_jvm_log
type that can be used to manage
JVM logging properties, such as log rotation criteria.
websphere_jvm_log { "AppNode01":
profile => 'PROFILE_APP_001',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
cell => 'CELL_01',
scope => 'node',
node => 'appNode01',
server => 'AppServer01',
out_filename => '/tmp/SystemOut.log',
out_rollover_type => 'BOTH',
out_rollover_size => '7',
out_maxnum => '200',
out_start_hour => '13',
out_rollover_period => '24',
err_filename => '/tmp/SystemErr.log',
err_rollover_type => 'BOTH',
err_rollover_size => '7',
err_maxnum => '3',
err_start_hour => '13',
err_rollover_period => '24',
require => Websphere::Profile::Appserver['PROFILE_APP_001'],
}
In the example above, we want to manage the JVM logs for the appNode01
node.
We want to rotate the "out" log based on time and size. We specify that via
the _rollover_type
parameter for each. We want to rotate every 7MB, which
we specify via the _rollover_size
parameter. We want to keep a maximum of
200 historical logs for the SystemOut, and only 3 for the SystemErr. We want
the time-based log rotation to occur at "1300" hours (1PM), and rotate every
24 hours.
Reference:
This module supports creating JDBC providers and data sources. At this time, it does not support the removal of JDBC providers or datasources or changing their configuration after they're created.
JDBC Provider:
An example of creating a JDBC provider called "Puppet Test", using Oracle, at node scope:
websphere_jdbc_provider { 'Puppet Test':
ensure => 'present',
dmgr_profile => 'PROFILE_DMGR_01',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
user => 'webadmin',
scope => 'node',
cell => 'CELL_01',
node => 'appNode01',
server => 'AppServer01',
dbtype => 'Oracle',
providertype => 'Oracle JDBC Driver',
implementation => 'Connection pool data source',
description => 'Created by Puppet',
classpath => '${ORACLE_JDBC_DRIVER_PATH}/ojdbc6.jar',
}
JDBC Datasource:
An example of creating a datasource, utilizing the JDBC provider we created, at node scope:
websphere_jdbc_datasource { 'Puppet Test':
ensure => 'present',
dmgr_profile => 'PROFILE_DMGR_01',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
user => 'webadmin',
scope => 'node',
cell => 'CELL_01',
node => 'appNode01',
server => 'AppServer01',
jdbc_provider => 'Puppet Test',
jndi_name => 'myTest',
data_store_helper_class => 'com.ibm.websphere.rsadapter.Oracle11gDataStoreHelper',
container_managed_persistence => true,
url => 'jdbc:oracle:thin:@//localhost:1521/sample',
description => 'Created by Puppet',
}
JDBC Provider at cell scope:
websphere_jdbc_provider { 'Puppet Test':
ensure => 'present',
dmgr_profile => 'PROFILE_DMGR_01',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
user => 'webadmin',
scope => 'cell',
cell => 'CELL_01',
dbtype => 'Oracle',
providertype => 'Oracle JDBC Driver',
implementation => 'Connection pool data source',
description => 'Created by Puppet',
classpath => '${ORACLE_JDBC_DRIVER_PATH}/ojdbc6.jar',
}
JDBC Datasource at cell scope:
websphere_jdbc_datasource { 'Puppet Test':
ensure => 'present',
dmgr_profile => 'PROFILE_DMGR_01',
profile_base => '/opt/IBM/WebSphere/AppServer/profiles',
user => 'webadmin',
scope => 'cell',
cell => 'CELL_01',
jdbc_provider => 'Puppet Test',
jndi_name => 'myTest',
data_store_helper_class => 'com.ibm.websphere.rsadapter.Oracle11gDataStoreHelper',
container_managed_persistence => true,
url => 'jdbc:oracle:thin:@//localhost:1521/sample',
description => 'Created by Puppet',
}
References:
This module has basic support for managing IBM HTTP Server (IHS) in the context of WebSphere.
In the example below, we install IHS to /opt/IBM/HTTPServer
, install the
WebSphere plug-ins for IHS, and create a server instance. By default, this
module will automatically export a websphere_node
and
websphere_web_server
resource via the websphere::ihs::server
defined type.
These exported resources will, by default, be collected by the DMGR and
realized. Basically, by default, an IHS server will automatically be
setup in the DMGR's cell.
websphere::ihs::instance { 'HTTPServer':
target => '/opt/IBM/HTTPServer',
package => 'com.ibm.websphere.IHSILAN.v85',
version => '8.5.5000.20130514_1044',
repository => '/mnt/myorg/ihs/repository.config',
install_options => '-properties user.ihs.httpPort=80',
user => 'webadmin',
group => 'webadmins',
manage_user => false,
manage_group => false,
log_dir => '/opt/log/websphere/httpserver',
admin_username => 'httpadmin',
admin_password => 'password',
webroot => '/opt/web',
}
websphere::package { 'Plugins':
ensure => 'present',
target => '/opt/IBM/Plugins',
repository => '/mnt/myorg/plugins/repository.config',
package => 'com.ibm.websphere.PLGILAN.v85',
version => '8.5.5000.20130514_1044',
require => Websphere::Ihs::Instance['HTTPServer'],
}
websphere::ihs::server { 'test':
target => '/opt/IBM/HTTPServer',
log_dir => '/opt/log/websphere/httpserver',
plugin_dir => '/opt/IBM/Plugins/config/test',
plugin_base => '/opt/IBM/Plugins',
cell => 'CELL_01',
config_file => '/opt/IBM/HTTPServer/conf/httpd_test.conf',
access_log => '/opt/log/websphere/httpserver/access_log',
error_log => '/opt/log/websphere/httpserver/error_log',
listen_port => '10080',
require => Websphere::Package['Plugins'],
}
References:
- websphere::ihs::instance
- websphere::package
- websphere::ihs::server
- websphere_node
- websphere_web_server
TODO: Add more examples here.
See the examples directory for now.
Once it's up, you should be able to reach the DMGR console at something like:
http://<host>:9060/ibm/console/unsecureLogon.jsp
Tested and developed with IBM WebSphere Application Server Network Deployment.
Tested and developed with IBM WebSphere 8.5.0.x and 8.5.5.x on:
- CentOS 6 x86_64
- RHEL 6 x86_64
- AIX 6.1, 7.1
Copyright 2015 Puppet Labs, Inc.
Josh Beard [email protected]
- Gabe Schuyler [email protected]
- Jonathan Hooker