Handling Deployments When Provisioning JBoss domain.xml (With Ansible)
It is tricky to manage JBoss with a provisioner such as Puppet or Ansible because its
We will use XSLT stylesheets to extract the deployments sections via
Here are the Ansible tasks themselves:
The
The (quite similar)
The XSLT is so complex because we only have XSLT 1.0 and need to get rid of any namespace declarations that would normally be output. (See E. Lenz' Too Many Namespaces for background and better options in XSLT 2.0).
domain.xml
contains not only rather static configuration but also sections that change quite often such as deployments
. So how can we manage the static parts of domain.xml
with f.ex. Ansible while still enabling developers to deploy at will via jboss-cli
(and thus changing the <deployments>
sections of the file)? Here is one possible solution, based on extracting the sections from the current file and merging them into the template.We will use XSLT stylesheets to extract the deployments sections via
xsltproc
run as a command, storing their output into variables that will be then used in the domain.xml
template. (xsltproc
has been chosen since it already was on our servers.)Here are the Ansible tasks themselves:
## JBoss merge deployment info from the existing domain.xml if any and copy the final domain.xml
# Note: <deployments> is added at 2 places to domain.xml whenever an app is deployed via JBoss CLI, we need to keep them
- name: Make sure xsltproc is installed
yum: name=libxslt state=installed
tags: jboss_configuration
- name: Copy XSLT stylesheets for domain.xml data extraction
copy: src={{ item }} dest=/tmp
with_items:
- extract_domain_deployments.xslt
- extract_servergroup_deployments.xslt
tags: jboss_configuration
- name: Check if domain.xml already present
stat: path=/opt/jboss/jboss-{{ jboss_version_short }}/domain/configuration/domain.xml
register: domain_xml_stat
tags: jboss_configuration
- name: Extract domain/deployments from domain.xml, if present
command: /usr/bin/xsltproc /tmp/extract_domain_deployments.xslt /opt/jboss/jboss-{{ jboss_version_short }}/domain/configuration/domain.xml
register: domain_deployments
when: domain_xml_stat.stat.exists is defined and domain_xml_stat.stat.exists == true
tags: jboss_configuration
- name: Extract server-groups//deployments from domain.xml, if present
command: /usr/bin/xsltproc /tmp/extract_servergroup_deployments.xslt /opt/jboss/jboss-{{ jboss_version_short }}/domain/configuration/domain.xml
register: servergroup_deployments
when: domain_xml_stat.stat.exists is defined and domain_xml_stat.stat.exists == true
tags: jboss_configuration
- name: Copying domain.xml configuration file
template: src=domain.xml dest=/opt/jboss/jboss-{{ jboss_version_short }}/domain/configuration/
notify: restart jboss-eap
tags: jboss_configuration
The
extract_domain_deployments.xslt
stylesheet:
<xsl:stylesheet version="1.0"
xmlns:j="urn:jboss:domain:1.5"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Output the domain/deployments element of domain.xml as is, without namespaces etc. -->
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="j:domain/j:deployments" />
</xsl:template>
<xsl:template match="*" name="identity">
<xsl:element name="{name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<!-- Copy content as is -->
<xsl:template match="node()|@*" priority="-2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The (quite similar)
extract_servergroup_deployments.xslt
stylesheet:
<xsl:stylesheet version="1.0"
xmlns:j="urn:jboss:domain:1.5"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Output the domain/server-groups/server-group/deployments element of domain.xml as is, without namespaces etc. -->
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="j:domain/j:server-groups/j:server-group/j:deployments" />
</xsl:template>
<xsl:template match="*" name="identity">
<xsl:element name="{name()}">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<!-- Copy content as is -->
<xsl:template match="node()|@*" priority="-2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The XSLT is so complex because we only have XSLT 1.0 and need to get rid of any namespace declarations that would normally be output. (See E. Lenz' Too Many Namespaces for background and better options in XSLT 2.0).