Ansible playbook setup
Setup variables
If you setup the four variables we needed in the encrypted vault file, you're ready. Those variables are setup like the following.
Warning
Make sure not to ever let your real values for these end up in a public git repo. The ones shown here I generated just for this article and are not what are in use in my environment.
roles/cas6/vars/cas-vault.yml:
DEV_TGC_SIGNING_KEY: dYffipMGbhIoyUsSHwzEDcBk5nbETZtH-lR3R776wNavS4koAHyQkDdK_rJIWrYYgZZ2TsLW5NXfcDI_Ivn4Uw
DEV_TGC_ENCRYPTION_KEY: Gpy6fxMnh5RhmFUJWVcJL9WIAuFODzTlPIaQOTq9-jM
DEV_WEBFLOW_SIGNING_KEY: xoWJ9S2vmTgvB_CdZeddb1qmqPihBGIw5Op27MsNxfR8KWgPgrx4VXpssTTM3IcXkLJVoxTylg_hSxvH65M88g
DEV_WEBFLOW_ENCRYPTION_KEY: qnHUX0kyFHc718oh/f+ebw==
Setup templates
To start - the only template files we need are:
- dev-cas.properties.j2 (which will be /etc/cas/config/cas.properties on the Dev CAS systems)
- log4j2.xml (which will be /etc/cas/config/log4j2.xml on the CAS systems, as so far I haven't had a reason to have a different log4j2 config on DEV/TEST/PROD like I have for cas.properties).
Setup handlers
You can copy over the handlers/main.yml file from the Apache Tomcat role since you'll need it here, but we'll also need one to reload httpd (once the AJP proxy config is added to httpd):
roles/cas6/handlers/main.yml:
# handlers file for cas6
- name: stop tomcat
ansible.builtin.systemd:
name: tomcat
state: stopped
- name: start tomcat
ansible.builtin.systemd:
name: tomcat
state: started
- name: restart tomcat
ansible.builtin.systemd:
name: tomcat
state: restarted
- name: reload httpd
ansible.builtin.systemd:
name: httpd
state: reloaded
Create tasks
We're going to have multiple plays within the CAS6 role, so we'll break them up like we did for Tomcat, but to start with, it's just two includes for 'base-cas-config.yml'.
roles/cas6/tasks/main.yml:
- include_tasks: base-cas-config.yml
- include_tasks: service-config.yml
- include_tasks: cas-ajp-proxy.yml
Base CAS Config tasks
For the first include, the only tasks are:
- Make sure the cas config and services directories exist
- Make sure that the cas.properties file we have in our templates directory matches the one in /etc/cas/config (and if not - update it and use notify to restart Tomcat when the play is done).
- Make sure that the log4j2.xml file we have in our files directory matches the one in /etc/cas/config (and if not - update it and use notify to restart Tomcat when the play is done).
- Make sure that the cas.war file we have in our files directory matches the one in /opt/tomcat/latest/webapps (and if not - update it and use notify to restart Tomcat when the play is done).
roles/cas6/tasks/base-cas-config.yml:
---
- include_vars: cas-vault.yml
- name: Ensure base CAS config directory exists
ansible.builtin.file:
path: /etc/cas/config
state: directory
mode: 770
owner: root
group: tomcat
- name: Ensure base CAS services directory exists
ansible.builtin.file:
path: /etc/cas/services
state: directory
mode: 750
owner: root
group: tomcat
- name: Ensure base CAS log directory exists
ansible.builtin.file:
path: /var/log/cas
state: directory
mode: 0750
owner: tomcat
group: tomcat
# Note: This is for dev specifically. If we have multiple environments, there's
# a different config file for each. The 'when' on inventory_hostname is used to
# differentiate here.
- name: Configure cas.properties file (dev)
ansible.builtin.template:
src: dev-cas.properties.j2
dest: /etc/cas/config/cas.properties
mode: 0640
owner: root
group: tomcat
when: ("login6dev" in inventory_hostname)
notify: restart tomcat
# For us at least, log4j2 is the same on production, dev, or test,
# so it's not tier dependent and doesn't need the 'when' statement.
# This uses the 'copy' module instead of the 'template' module since
# Ansible does not like the {} all over that file. If you need to change that per-server
# You'll need to create an version of log4j2.xml with {} escaped.
- name: Copy log4j2.xml
ansible.builtin.copy:
src: log4j2.xml
dest: /etc/cas/config/log4j2.xml
mode: 0640
owner: root
group: tomcat
notify: restart tomcat
# Note: cas6.war file should be placed in the 'files' subdirectory of your cas role.
# You can explicitly replace 'src' with the path to it, i.e. /home/your-user/cas-overlay-template/build/libs/cas.war if you
# want, or you can manually copy the cas.war file into the files directory.
- name: Copy CAS war file
ansible.builtin.copy:
src: cas.war
dest: /opt/tomcat/latest/webapps/cas.war
mode: 0750
owner: tomcat
group: tomcat
when: ("login6dev" in inventory_hostname)
notify: restart tomcat
Setup AJP proxy between Tomcat and httpd
This is what handles the connections on Apache httpd's side from Apache Tomcat. We setup the AJP proxy on the Tomcat side earlier.
roles/cas6/tasks/cas-ajp-proxy.yml:
---
- name: "Copy CAS Apache AJP proxy config"
ansible.builtin.template:
src: cas-ajp.conf.j2
dest: /etc/httpd/conf.d/cas-ajp.conf
owner: root
group: root
mode: 0644
notify: reload httpd
Run the play
In this example below, I'm running the play but limiting it to only one host.
[chauvetp@ansible templates]$ ansible-playbook ~/ansible/site.yml --ask-vault-pass --limit login6devb
Vault password:
This will cause the dev-cas.properties.j2 template to be copied over to /etc/cas/config/cas.properties. It will also copy the log4j2.xml file from the files directory on the ansible host to /etc/cas/config/log4j2.xml on the system or systems specified in the limit command. It will also substitute the variables in the cas properties file using the contents of cas-vault.yml, which were decrypted via the --ask-vault-pass option. If the cas.properties file on the target system is different than the template (after variable substitution), then it will also restart Tomcat.
Test the install
Once your play goes through - you will want to go to your server (i.e. https://YourCASServer.domain.edu/cas/login) and check that it loads. If you left in a test user defined by cas.authn.accept.users in cas.properties, you can test those credentials here. If it succeeds, you'll receive a "Log In Successful" message.