First commit

This commit is contained in:
Andrea Venturini 2024-06-03 19:22:15 +02:00
parent 20c54d2017
commit 42a4c7f0f1
30 changed files with 1009 additions and 1 deletions

116
README.md
View File

@ -1,2 +1,116 @@
# Ansible - Role - ERDDAP
A role that installs the ERDDAP Docker container
A role that installs the ERDDAP Docker container.
This role will
- create 2 linux users
- create some directories for the container files and volumes
- create the docker compose file
- configure and customize the ERDDAP configuration files and cotainer entrypoint
## Role Variables
In the `defaults\main.yaml` file you can find all the role variables.
You can find below a description of the main variables or variables group
```
# This set the directory where will be create the docker compose manifest and all the needed directories.
directory_base: /opt/data00/customdocker/
# This the directory where are the external data files that ERDDAP will read.
directory_external_data:
fullpath: "/opt/data00/appdata/"
create_if_not_exists: true
# If you want to create the yaml of a docker stack (aka customer project name) enable it and set
# the stack name.
stack:
enable: true
name: "XXX_dockstackname_XXX"
# WARNING: do not add trailing /
directory_relative_path: 'XXX_dockstackname_XXX'
start_after_configuration: true
# user_list: create the users that the container will use to run and access the data files.
# DO NOT change the user order in the list
user_list:
- name: 'usr{{ stack.name }}'
groups:
uid: 2000
gid: 2000
- name: usrtomcat
groups: 'usr{{ stack.name }}'
uid: 2001
gid: 2001
# ERDDAP Specific variables
erddap:
content_setup_xml_replace_items:
# bigParentDirectory - Same as volume mounted inside the container
- regexp: /home/yourName/erddap/
replace: /erddapData/
- regexp: http://localhost:8080
replace: http://XXX_ERDDAP_webDomainOrIPv4_XXX
- regexp: <baseHttpsUrl></baseHttpsUrl>
replace: <baseHttpsUrl>https://XXX_ERDDAP_webDomainOrIPv4_XXX</baseHttpsUrl>
- regexp: your.email@yourInstitution.edu
replace: asd@asd.com
- regexp: Your Institution
replace: XXX_MyInstutionString_XXX
- regexp: Your Institution's or Group's Url
replace: https://XXX_MyInstitutionUrl_XXX
- regexp: <adminIndividualName>Your Name
replace: <adminIndividualName>XXX_YourName_XXX
- regexp: <adminPosition>ERDDAP administrator
replace: <adminPosition>ERDDAP administrator
# The \+ is for the python regexp - The real default value is <adminPhone>+1 999-999-9999
- regexp: <adminPhone>\+1 999-999-9999
replace: <adminPhone>000000000
- regexp: <adminAddress>123 Main St.
replace: <adminAddress>XXX_MyAddress_XXX
- regexp: <adminCity>Some Town
replace: <adminCity>XXX_YourTown_XXX
- regexp: <adminStateOrProvince>CA
replace: <adminStateOrProvince>XXX_State_XXX
- regexp: <adminPostalCode>99999
replace: <adminPostalCode>XXX_PostCode_XXX
- regexp: <adminCountry>USA
replace: <adminCountry>XXX_Country_XXX
- regexp: <adminEmail>your.email@yourCompany.com
replace: <adminEmail>XXX_adminMail_XXX
- regexp: <flagKeyKey>CHANGE THIS TO YOUR FAVORITE QUOTE
replace: <flagKeyKey>XXX_MyFlagKey_XXX
content_setup_xml_replace_email: false
content_setup_xml_replace_email_items:
- regexp: <emailFromAddress>your.email@yourCompany.com
replace: <emailFromAddress>XXX_YourEmail_XXX
- regexp: <emailUserName>your.email@yourCompany.com
replace: <emailUserName>XXX_YourEmailUsername_XXX
- regexp: <emailPassword>yourPassword
replace: <emailPassword>XXX_YourPassword_XXX
- regexp: <emailProperties>
replace: <emailProperties>
- regexp: <emailSmtpHost>your.smtp.host.edu
replace: <emailSmtpHost>XXX_YourEmailSmtp_XXX
- regexp: <emailSmtpPort>25
replace: <emailSmtpPort>XXX_YourEmailSmtpPort_XXX
# This set which content.erddap archive will be deployed. It depends from the ERDDAP version. See the ERDDAP webpage.
content_archive_data_name: "content.erddap_v214.tar.gz"
# This is the main ERDDAP data directory
bigParentDirectory: /erddapData/
# This enable the container SSL endpoint. This is useful if ERDDAP is behind a reverse proxy. Because some web pages doesn't work the comunication from are HTTPS (reverse proxy) <---> HTTP (erddap).
# The reverse proxy must not check the certificate expire date and CN.
tomcatSsl:
enable: true
container_certPath: "erddap/data/erddap/ssl/erddap-self.localhost_2122.pfx"
certType: "PKCS12"
certPassword: "*********"
container:
image: axiom/docker-erddap:2.23-jdk17-openjdk
containername: '{{ stack.name }}-erddap'
# start_after_configuration - If stack is enabled, this variable is not used.
start_after_configuration: true
# container.volume_directory_relative_path_list: do not change the directory order in the list
volume_directory_relative_path_list:
- name: '{{ stack.name }}-erddap-docker/volumes/Content'
- name: '{{ stack.name }}-erddap-docker/volumes/Data'
- name: '{{ stack.name }}-erddap-docker/volumes/erddapSSLCerts'
- name: '{{ stack.name }}-erddap-docker/deployfiles'
- name: '{{ stack.name }}-erddap-docker/deployfiles/erddap-docker'
http_host_port: 12081
# https_host_port - Used if erddap.tomcatSsl.enable: true
https_host_port: 12082
```

View File

View File

@ -0,0 +1,110 @@
---
# vars file for ansible-role-erddap
arch_mapping: # Map ansible architecture {{ ansible_architecture }} names to Docker's architecture names
x86_64: amd64
aarch64: arm64
directory_base: /opt/data00/customdocker/
directory_external_data:
fullpath: "/opt/data00/appdata/"
create_if_not_exists: true
software:
- docker
- docker-compose
# If you want to create the yaml of a docker stack (aka customer project name) enable it and set
# the stack name.
stack:
enable: true
name: "XXX_dockstackname_XXX"
# WARNING: do not add trailing /
directory_relative_path: 'XXX_dockstackname_XXX'
start_after_configuration: true
# user_list: do not change the user order in the list
user_list:
- name: 'usr{{ stack.name }}'
groups:
uid: 2000
gid: 2000
- name: usrtomcat
groups: 'usr{{ stack.name }}'
uid: 2001
gid: 2001
# ERDDAP
erddap:
content_setup_xml_replace_items:
# bigParentDirectory - Same as volume mounted inside the container
- regexp: /home/yourName/erddap/
replace: /erddapData/
- regexp: http://localhost:8080
replace: http://XXX_ERDDAP_webDomainOrIPv4_XXX
- regexp: <baseHttpsUrl></baseHttpsUrl>
replace: <baseHttpsUrl>https://XXX_ERDDAP_webDomainOrIPv4_XXX</baseHttpsUrl>
- regexp: your.email@yourInstitution.edu
replace: asd@asd.com
- regexp: Your Institution
replace: XXX_MyInstutionString_XXX
- regexp: Your Institution's or Group's Url
replace: https://XXX_MyInstitutionUrl_XXX
- regexp: <adminIndividualName>Your Name
replace: <adminIndividualName>XXX_YourName_XXX
- regexp: <adminPosition>ERDDAP administrator
replace: <adminPosition>ERDDAP administrator
# The \+ is for the python regexp - The real default value is <adminPhone>+1 999-999-9999
- regexp: <adminPhone>\+1 999-999-9999
replace: <adminPhone>000000000
- regexp: <adminAddress>123 Main St.
replace: <adminAddress>XXX_MyAddress_XXX
- regexp: <adminCity>Some Town
replace: <adminCity>XXX_YourTown_XXX
- regexp: <adminStateOrProvince>CA
replace: <adminStateOrProvince>XXX_State_XXX
- regexp: <adminPostalCode>99999
replace: <adminPostalCode>XXX_PostCode_XXX
- regexp: <adminCountry>USA
replace: <adminCountry>XXX_Country_XXX
- regexp: <adminEmail>your.email@yourCompany.com
replace: <adminEmail>XXX_adminMail_XXX
- regexp: <flagKeyKey>CHANGE THIS TO YOUR FAVORITE QUOTE
replace: <flagKeyKey>XXX_MyFlagKey_XXX
content_setup_xml_replace_email: false
content_setup_xml_replace_email_items:
- regexp: <emailFromAddress>your.email@yourCompany.com
replace: <emailFromAddress>XXX_YourEmail_XXX
- regexp: <emailUserName>your.email@yourCompany.com
replace: <emailUserName>XXX_YourEmailUsername_XXX
- regexp: <emailPassword>yourPassword
replace: <emailPassword>XXX_YourPassword_XXX
- regexp: <emailProperties>
replace: <emailProperties>
- regexp: <emailSmtpHost>your.smtp.host.edu
replace: <emailSmtpHost>XXX_YourEmailSmtp_XXX
- regexp: <emailSmtpPort>25
replace: <emailSmtpPort>XXX_YourEmailSmtpPort_XXX
content_archive_data_name: "content.erddap_v214.tar.gz"
bigParentDirectory: /erddapData/
enviroments:
minMemory: "2G"
maxMemory: "4G"
baseUrl: "http://XXX_ERDDAP_webDomainOrIPv4_XXX"
baseHttpsUrl: "https://XXX_ERDDAP_webDomainOrIPv4_XXX"
emailEverythingTo: "XXX_adminMail_XXX"
tomcatSsl:
enable: true
container_certPath: "erddap/data/erddap/ssl/erddap-self.localhost_2122.pfx"
certType: "PKCS12"
certPassword: "*********"
container:
image: axiom/docker-erddap:2.23-jdk17-openjdk
containername: '{{ stack.name }}-erddap'
# start_after_configuration - If stack is enabled, this variable is not used.
start_after_configuration: true
# container.volume_directory_relative_path_list: do not change the directory order in the list
volume_directory_relative_path_list:
- name: '{{ stack.name }}-erddap-docker/volumes/Content'
- name: '{{ stack.name }}-erddap-docker/volumes/Data'
- name: '{{ stack.name }}-erddap-docker/volumes/erddapSSLCerts'
- name: '{{ stack.name }}-erddap-docker/deployfiles'
- name: '{{ stack.name }}-erddap-docker/deployfiles/erddap-docker'
http_host_port: 12081
# https_host_port - Used if erddap.tomcatSsl.enable: true
https_host_port: 12082

View File

@ -0,0 +1,23 @@
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
clientAuth="false"
maxThreads="150"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
SSLEnabled="true">
<SSLHostConfig
sslProtocol="TLSv1.2, TLSv1.3"
iphers="ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305,DHE-RSA-AES128-GCM-SHA256,DHE-RSA-AES256-GCM-SHA384"
>
<Certificate
certificateKeystoreFile="${catalina.base}/conf/erddap-self.localhost_2122.pfx"
certificateKeystoreType="ph_KEYSTORE_TYPE"
certificateKeystorePassword="ph_KEYSTORE_PASSWORD"
/>
</SSLHostConfig>
</Connector>

View File

@ -0,0 +1,17 @@
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
clientAuth="false"
sslProtocol="TLSv1.2, TLSv1.3"
ciphers="ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305,DHE-RSA-AES128-GCM-SHA256,DHE-RSA-AES256-GCM-SHA384"
maxThreads="150"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
SSLEnabled="true"
keystoreFile="${catalina.base}/conf/ph_KEYSTORE_FILENAME"
keystoreType="ph_KEYSTORE_TYPE"
keystorePass="ph_KEYSTORE_PASSWORD"
/>

View File

@ -0,0 +1,195 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector server="Apache" secure="true" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
relaxedPathChars='[]|'
relaxedQueryChars='[]:|{}^&#x5c;&#x60;&quot;&lt;&gt;' />
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
clientAuth="false"
sslProtocol="TLSv1.2, TLSv1.3"
ciphers="ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305,DHE-RSA-AES128-GCM-SHA256,DHE-RSA-AES256-GCM-SHA384"
maxThreads="150"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
SSLEnabled="true"
keystoreFile="${catalina.base}/conf/ph_KEYSTORE_FILENAME"
keystoreType="ph_KEYSTORE_TYPE"
keystorePass="ph_KEYSTORE_PASSWORD"
/>
<!--
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
This connector uses the NIO implementation. The default
SSLImplementation will depend on the presence of the APR/native
library and the useOpenSSL attribute of the
AprLifecycleListener.
Either JSSE or OpenSSL style configuration may be used regardless of
the SSLImplementation selected. JSSE style configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
This connector uses the APR/native implementation which always uses
OpenSSL for TLS.
Either JSSE or OpenSSL style configuration may be used. OpenSSL style
configuration is used below.
-->
<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true" >
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
<SSLHostConfig>
<Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
-->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<!--
<Connector protocol="AJP/1.3"
address="::1"
port="8009"
redirectPort="8443" />
-->
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />
</Host>
</Engine>
</Service>
</Server>

View File

@ -0,0 +1,2 @@
---
# handlers file for ansible-role-erddap

View File

@ -0,0 +1,52 @@
galaxy_info:
author: your name
description: your role description
company: your company (optional)
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -0,0 +1,23 @@
---
### PRE Check ###
- name: "PRE Check - If stack is enabled, test if the stack yaml already exists."
stat:
path: "{{ directory_base }}{{ stack.directory_relative_path }}/{{ stack.name }}-stack.yaml"
register: precheck_stack_yaml
when: stack.enable
- name: PRE Check - If stack is enabled and if the stack yaml already exist, block execution
fail:
msg: "PRE Check fail - The stack YAML file already exists. Disable the stack creation and manually copy the docker-compose.yaml content into it."
when: stack.enable and precheck_stack_yaml.stat.exists
- name: PRE Check - Test if the directory_external_data.fullpath exists
stat:
path: "{{ directory_external_data.fullpath }}"
register: precheck_directory_external_data_fullpath
- name: PRE Check - If the directory_external_data.fullpath NOT exists, block execution
fail:
msg: "PRE Check fail - The directory_external_data {{ directory_external_data.fullpath }} NOT exists"
when: not directory_external_data.create_if_not_exists and not precheck_directory_external_data_fullpath.stat.exists
### ###

View File

@ -0,0 +1,15 @@
### Create Linux users ###
- name: Create Linux application users
block:
- name: Create Linux application users
user:
name: "{{ item.name }}"
createhome: true
#password_lock: true
comment: ",,,,umask=0002"
groups: "{{ item.groups }}"
uid: "{{ item.uid }}"
with_items: "{{ user_list }}"
### ###

View File

@ -0,0 +1,26 @@
### Create deployment directories and set permissions ###
- name: Create Docker stack directories
file:
path: "{{ directory_base }}{{ item.name }}"
state: directory
owner: "{{ user_list[1].name }}"
group: "{{ user_list[1].name }}"
mode: 02775
with_items: "{{ container.volume_directory_relative_path_list }}"
- name: Create External data directory
file:
path: "{{ directory_external_data.fullpath }}"
state: directory
owner: "{{ user_list[0].name }}"
group: "{{ user_list[0].name }}"
mode: 02775
when: directory_external_data.create_if_not_exists
- name: Create stack directory
file:
path: "{{ directory_base }}{{ stack.directory_relative_path }}"
state: directory
mode: 02775
when: stack.enable
### ###

View File

@ -0,0 +1,9 @@
### Server - Copy ERDDAP deploy items ###
- name: Copy ERDDAP deploy items - data directory
copy:
src: "data/erddap/"
dest: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/data/"
owner: "{{ user_list[1].name }}"
group: "{{ user_list[1].name }}"
mode: 02775
### ###

View File

@ -0,0 +1,45 @@
# ERDDAP - Docker - Copy the container enviroment file
- name: Template - Docker - ERDDAP - Copy environment file
block:
- name: Ensures {{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/environments dir exists
file:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/environments"
state: directory
- name: Copy environment file
template:
src: "docker/environment/erddap-compose.env.j2"
dest: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/environments/erddap-compose.env"
owner: "{{ user_list[1].name }}"
group: "{{ user_list[1].name }}"
mode: 02775
# ERDDAP - Docker - Copy the container entrypoint
- name: Template - Docker - ERDDAP - Copy entrypoint file
block:
- name: Ensures {{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/entrypoints dir exists
file:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/entrypoints"
state: directory
- name: Copy entrypoint file
template:
src: "docker/entrypoint/erddap_entrypoint.sh.j2"
dest: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/entrypoints/erddap_entrypoint.sh"
owner: "{{ user_list[1].name }}"
group: "{{ user_list[1].name }}"
mode: 02775
### ERDDAP - Docker - Copy compose ###
- name: Template - Docker - ERDDAP - Copy docker-compose file
block:
- name: Ensures {{ directory_base }}{{ container.volume_directory_relative_path_list[4].name }}/ dir exists
file:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[4].name }}/"
state: directory
- name: Copy docker-compose file
template:
src: "docker/compose/docker-compose.yaml.j2"
dest: "{{ directory_base }}{{ container.volume_directory_relative_path_list[4].name }}/docker-compose.yaml"
owner: "{{ user_list[1].name }}"
group: "{{ user_list[1].name }}"
mode: 02775
### ###

View File

@ -0,0 +1,35 @@
### ERDDAP - Setup container SSL endpoint ###
- name: ERDDAP - Setup container SSL endpoint
block:
# ERDDAP - If SSL Endpoint enabled #
# SSL files are copied in 10_3_erddap-docker-copy-dataFiles.yaml
#- name: Copy ERDDAP SelfSigned certificate for HTTPS endpoint
# copy:
# src: "{{ playbook_dir }}/../../../data/erddap/ssl/"
# dest: "{{ directory_base }}{{ container.volume_directory_relative_path_list[2].name }}/"
# owner: "{{ user_list[1].name }}"
# group: "{{ user_list[1].name }}"
# mode: 02775
# #
# ERDDAP - customize data/tomcat/server.sslconnetor.xml if SSL endpoint enabled #
- name: ERDDAP - Set SSL Connector - Certificate keystore filename
ansible.builtin.replace:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/data/tomcat/server.sslconnetor.xml"
regexp: "ph_KEYSTORE_FILENAME"
replace: "{{ erddap.tomcatSsl.container_certPath | basename }}"
- name: ERDDAP - Set SSL Connector - Certificate type
ansible.builtin.replace:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/data/tomcat/server.sslconnetor.xml"
regexp: "ph_KEYSTORE_TYPE"
replace: "{{ erddap.tomcatSsl.certType }}"
- name: ERDDAP - Set SSL Connector - Certificate password
ansible.builtin.replace:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/data/tomcat/server.sslconnetor.xml"
regexp: "ph_KEYSTORE_PASSWORD"
replace: "{{ erddap.tomcatSsl.certPassword }}"
# #
when: erddap.tomcatSsl.enable
### ###

View File

@ -0,0 +1,6 @@
### ERDDAP - Unarchive Content data ###
- name: ERDDAP - Unarchive Content data
ansible.builtin.unarchive:
src: "data/erddap/{{erddap.content_archive_data_name}}"
dest: "{{ directory_base }}{{ container.volume_directory_relative_path_list[0].name }}"
### ###

View File

@ -0,0 +1,27 @@
### ERDDAP Content setup.xml customization ###
- name: Replace ERDDAP - Content set setup.xml basic values
ansible.builtin.replace:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[0].name }}/setup.xml"
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
with_items:
- "{{ erddap.content_setup_xml_replace_items }}"
- name: Replace ERDDAP - Content set setup.xml mail values
ansible.builtin.replace:
path: "{{ directory_base }}{{ container.volume_directory_relative_path_list[0].name }}/setup.xml"
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
with_items:
- "{{ erddap.content_setup_xml_replace_email_items }}"
when: erddap.content_setup_xml_replace_email
#- name: "Read a file content"
# shell: |
# cat "{{ directory_base }}{{ container.volume_directory_relative_path_list[0].name }}/setup.xml"
# register: file_content
#- name: "Print the file content to a console"
# debug:
# msg: "{{ file_content.stdout }}"
### ###

View File

@ -0,0 +1,7 @@
### Docker - Generate final docker-compose.yaml ###
- name: Docker - Stack - Generate final docker-compose.yaml
ansible.builtin.shell: docker compose -f {{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/erddap-docker/docker-compose.yaml config > {{ directory_base }}{{ stack.directory_relative_path }}/docker-compose.yaml
args:
executable: /bin/bash
when: stack.enable
### ###

View File

@ -0,0 +1,13 @@
### Docker - Start container or stack docker-compose.yaml ###
- name: Docker - Container - Start
ansible.builtin.shell: docker compose -f {{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/erddap-docker/docker-compose.yaml up -d
args:
executable: /bin/bash
when: container.start_after_configuration and not stack.start_after_configuration
- name: Docker - Stack - Start
ansible.builtin.shell: docker compose -f {{ directory_base }}{{ stack.directory_relative_path }}/docker-compose.yaml up -d
args:
executable: /bin/bash
when: stack.start_after_configuration
### ###

View File

@ -0,0 +1,89 @@
### example inventory.ini ###
# [all]
# # In this case, node1 is the hostname with 192.168.18.131 IP address and garis is sudo user.
# node1 ansible_host=192.168.18.131 ansible_user=garis ansible_ssh_common_args='-o StrictHostKeyChecking=no'
### ###
---
#- name: Install Docker on Ubuntu
# hosts: all
# #remote_user: garis # Change remote user to your sudo user!
# become: true
# vars:
# arch_mapping: # Map ansible architecture {{ ansible_architecture }} names to Docker's architecture names
# x86_64: amd64
# aarch64: arm64
# tasks:
- name: Update and upgrade all packages to the latest version
ansible.builtin.apt:
update_cache: true
upgrade: dist
cache_valid_time: 3600
- name: Install required packages
ansible.builtin.apt:
pkg:
- apt-transport-https
- ca-certificates
- curl
- gnupg
- software-properties-common
- name: Create directory for Docker's GPG key
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Add Docker's official GPG key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
keyring: /etc/apt/keyrings/docker.gpg
state: present
- name: Print architecture variables
ansible.builtin.debug:
msg: "Architecture: {{ ansible_architecture }}, Codename: {{ ansible_lsb.codename }}"
- name: Add Docker repository
ansible.builtin.apt_repository:
repo: >-
deb [arch={{ arch_mapping[ansible_architecture] | default(ansible_architecture) }}
signed-by=/etc/apt/keyrings/docker.gpg]
https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} stable
filename: docker
state: present
- name: Install Docker and related packages
ansible.builtin.apt:
name: "{{ item }}"
state: present
update_cache: true
loop:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
- name: Add Docker group
ansible.builtin.group:
name: docker
state: present
#- name: Add user to Docker group
# ansible.builtin.user:
# name: "{{ ansible_user }}"
# groups: docker
# append: true
#- name: Enable and start Docker services
# ansible.builtin.systemd:
# name: "{{ item }}"
# enabled: true
# state: started
# loop:
# - docker.service
# - containerd.service

View File

@ -0,0 +1,15 @@
### Install software from repositories ###
#- name: Install software from repositories
# ansible.builtin.apt:
# pkg: "{{ software }}"
### ###
- name: Pause - Wait for user prompt
ansible.builtin.pause:
prompt: "Enter to continue..."

View File

@ -0,0 +1,27 @@
---
# Uncomment to also install Docker #
#- name: 99_1
# ansible.builtin.import_tasks: 99_1_ubuntu-install-docker.yaml
# #
- name: 00_0
ansible.builtin.import_tasks: 00_0_erddap-docker-pre-check.yaml
- name: 10_1
ansible.builtin.import_tasks: 10_1_erddap-docker-users.yaml
- name: 10_2
ansible.builtin.import_tasks: 10_2_erddap-docker-directories.yaml
- name: 10_3
ansible.builtin.import_tasks: 10_3_erddap-docker-copy-dataFiles.yaml
- name: 10_4
ansible.builtin.import_tasks: 10_4_erddap-docker-copy-templates.yaml
- name: 10_5
ansible.builtin.import_tasks: 10_5_erddap-docker-enabledSSL.yaml
- name: 10_6
ansible.builtin.import_tasks: 10_6_erddap-docker-extract-content-archive.yaml
- name: 10_7
ansible.builtin.import_tasks: 10_7_erddap-docker-customazie-content.yaml
- name: 10_8
ansible.builtin.import_tasks: 10_8_erddap-docker-generate-stack-compose.yaml
# Uncomment to also run the docker compose at the end #
#- name: 20_1
# ansible.builtin.import_tasks: 20_1_docker_run.yaml
# #

View File

@ -0,0 +1,48 @@
version: '3.3'
services:
# ERDDAP container
erddap:
image: '{{ container.image }}'
container_name: '{{ container.containername }}'
ports:
- '{{ container.http_host_port }}:8080'
{%- if erddap.tomcatSsl.enable %}
{% raw %}
# ERDDAP_ScriptPortsPinPoint
- '{% endraw %}{{ container.https_host_port }}{% raw %}:8443'{% endraw %}
{% endif %}
{% raw %}
env_file:
- '{% endraw %}{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/environments/erddap-compose.env'
volumes:
# ERDDAP data volume (bigParentDirectory) - logs, cache, ecc...
- type: bind
source: '{{ directory_base }}{{ container.volume_directory_relative_path_list[1].name }}'
target: /erddapData
# ERDDAP configuration volume
- type: bind
source: '{{ directory_base }}{{ container.volume_directory_relative_path_list[0].name }}'
target: /usr/local/tomcat/content/erddap
# ERDDAP custom data volume - Data that will be ingested by ERDDAP
- type: bind
source: '{{ directory_external_data.fullpath }}'
target: /Data
# ERDDAP custom entrypoint - Because we add some commands to the entrypoint file
- type: bind
source: '{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/entrypoints/erddap_entrypoint.sh'
target: /entrypoint.sh
# ERDDAP_ScriptVolumePinPoint
{%- if erddap.tomcatSsl.enable %}
{% raw %}
# ERDDAP HTTPS certificate file
- {% endraw %}type: bind
source: '{{ directory_base }}{{ container.volume_directory_relative_path_list[2].name }}/{{erddap.tomcatSsl.container_certPath | basename }}'
target: /usr/local/tomcat/conf/ph_KEYSTORE_FILENAME
# ERDDAP Tomcat server.sslconnetor.xml
- type: bind
source: '{{ directory_base }}{{ container.volume_directory_relative_path_list[3].name }}/data/tomcat/server.sslconnetor.xml'
target: /usr/local/tomcat/conf/server.sslconnetor.xml
{%- endif %}
{% raw %}
restart: unless-stopped
{% endraw %}

View File

@ -0,0 +1,61 @@
#!/bin/bash
set -e
# preferable to fire up Tomcat via start-tomcat.sh which will start Tomcat with
# security manager, but inheriting containers can also start Tomcat via
# catalina.sh
if [ "$1" = 'start-tomcat.sh' ] || [ "$1" = 'catalina.sh' ]; then
###
# ETT Custom user
groupadd --gid '{{ user_list[1].gid }}' '{{ user_list[1].name }}' && \
useradd -u '{{ user_list[1].uid }}' -g '{{ user_list[1].gid }}' -s /bin/bash '{{ user_list[1].name }}'
###
USER_ID=${TOMCAT_USER_ID:-1000}
GROUP_ID=${TOMCAT_GROUP_ID:-1000}
###
# Tomcat user
###
groupadd -r tomcat -g ${GROUP_ID} && \
useradd -u ${USER_ID} -g tomcat -d ${CATALINA_HOME} -s /bin/bash \
-c "Tomcat user" tomcat
#chfn --other='umask=0002' tomcat
### ETT set cors.allowed.origins
#
if ! grep -q 'cors.allowed.origins' ${CATALINA_HOME}/conf/web.xml; then
sed -i 's|<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>|<filter-class>org.apache.catalina.filters.CorsFilter</filter-class><init-param><param-name>cors.allowed.origins</param-name><param-value>*</param-value></init-param>|' ${CATALINA_HOME}/conf/web.xml
fi
sed -i 's|connectionTimeout="20000"|connectionTimeout="300000"|g' ${CATALINA_HOME}/conf/server.xml
###
{% if erddap.tomcatSsl.enable %}
# ETT SSL Connector placeholder
if [ ! -e ${CATALINA_HOME}/conf/sslconnectoradded.txt ]
then
sed -i -e "/<Service name=\"Catalina\">/r ${CATALINA_HOME}/conf/server.sslconnetor.xml" ${CATALINA_HOME}/conf/server.xml
touch ${CATALINA_HOME}/conf/sslconnectoradded.txt
fi
{% endif %}
###
# Change CATALINA_HOME ownership to tomcat user and tomcat group
# Restrict permissions on conf
###
chown -R tomcat:tomcat ${CATALINA_HOME} && chmod 400 ${CATALINA_HOME}/conf/*
sync
###
# ETT Give permissions to the custom directory 'erddapData'
chown -R tomcat:tomcat /erddapData
# ETT Custom user
usermod -a -G ph_HOST_ERDDAP_DATA_user_group tomcat
###
exec gosu tomcat "$@"
fi
exec "$@"

View File

@ -0,0 +1,35 @@
# Set user and group with host ID
TOMCAT_USER_ID={{ user_list[1].name }}
TOMCAT_GROUP_ID={{ user_list[1].name }}
# ETT - Set UMASK - For TOMCAT
# All'avvio Tomcat, se non è già presente, setta la variabile d'ambiente UMASK e reimposta il valore di UMASK.
UMASK=0002
# ETT - Java Options
#JAVA_OPTS="$JAVA_OPTS -Xmx4g"
## Disable log4j vulnerability 20211210
JAVA_OPTS="-Dlog4j2.formatMsgNoLookups=true"
# ETT - No Log4j fix
#CATALINA_OPTS=-server -Djava.awt.headless=true -Xms768m -Xmx4G -XX:+UseConcMarkSweepGC -XX:NewSize=48m
CATALINA_OPTS=-server -Djava.awt.headless=true -Xms768m -Xmx4G -XX:NewSize=48m -Dlog4j2.formatMsgNoLookups=true
{% if erddap.enviroments.minMemory is defined and erddap.enviroments.minMemory|d('')|length > 0 %}
ERDDAP_MIN_MEMORY='{{ erddap.enviroments.minMemory }}'
{% endif %}
{% if erddap.enviroments.maxMemory is defined and erddap.enviroments.maxMemory|d('')|length > 0 %}
ERDDAP_MAX_MEMORY='{{ erddap.enviroments.maxMemory }}'
{% endif %}
{% if erddap.bigParentDirectory is defined and erddap.bigParentDirectory|d('')|length > 0 %}
ERDDAP_bigParentDirectory='{{ erddap.bigParentDirectory }}'
{% endif %}
{% if erddap.enviroments.baseUrl is defined and erddap.enviroments.baseUrl|d('')|length > 0 %}
ERDDAP_baseUrl='{{ erddap.enviroments.baseUrl }}'
{% endif %}
{% if erddap.enviroments.baseHttpsUrl is defined and erddap.enviroments.baseHttpsUrl|d('')|length > 0 %}
ERDDAP_baseHttpsUrl='{{ erddap.enviroments.baseHttpsUrl }}'
{% endif %}
{% if erddap.enviroments.emailEverythingTo is defined and erddap.enviroments.emailEverythingTo|d('')|length > 0 %}
ERDDAP_emailEverythingTo='{{ erddap.enviroments.emailEverythingTo }}'
{% endif %}

View File

@ -0,0 +1,2 @@
localhost

View File

@ -0,0 +1,5 @@
---
- hosts: localhost
remote_user: root
roles:
- ansible-role-erddap

7
main.yaml Normal file
View File

@ -0,0 +1,7 @@
---
- hosts: all
#remote_user: root
# Privilege escalation to root
become: true
roles:
- ansible-role-erddap