diff --git a/README.md b/README.md index e0cb4a7..e2bed2d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,116 @@ # Ansible - Role - ERDDAP -A role that installs the ERDDAP Docker container \ No newline at end of file +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: + replace: https://XXX_ERDDAP_webDomainOrIPv4_XXX + - 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: Your Name + replace: XXX_YourName_XXX + - regexp: ERDDAP administrator + replace: ERDDAP administrator + # The \+ is for the python regexp - The real default value is +1 999-999-9999 + - regexp: \+1 999-999-9999 + replace: 000000000 + - regexp: 123 Main St. + replace: XXX_MyAddress_XXX + - regexp: Some Town + replace: XXX_YourTown_XXX + - regexp: CA + replace: XXX_State_XXX + - regexp: 99999 + replace: XXX_PostCode_XXX + - regexp: USA + replace: XXX_Country_XXX + - regexp: your.email@yourCompany.com + replace: XXX_adminMail_XXX + - regexp: CHANGE THIS TO YOUR FAVORITE QUOTE + replace: XXX_MyFlagKey_XXX + content_setup_xml_replace_email: false + content_setup_xml_replace_email_items: + - regexp: your.email@yourCompany.com + replace: XXX_YourEmail_XXX + - regexp: your.email@yourCompany.com + replace: XXX_YourEmailUsername_XXX + - regexp: yourPassword + replace: XXX_YourPassword_XXX + - regexp: + replace: + - regexp: your.smtp.host.edu + replace: XXX_YourEmailSmtp_XXX + - regexp: 25 + replace: 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 +``` \ No newline at end of file diff --git a/ansible-role-erddap/README.md b/ansible-role-erddap/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ansible-role-erddap/defaults/main.yml b/ansible-role-erddap/defaults/main.yml new file mode 100644 index 0000000..4624ec4 --- /dev/null +++ b/ansible-role-erddap/defaults/main.yml @@ -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: + replace: https://XXX_ERDDAP_webDomainOrIPv4_XXX + - 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: Your Name + replace: XXX_YourName_XXX + - regexp: ERDDAP administrator + replace: ERDDAP administrator + # The \+ is for the python regexp - The real default value is +1 999-999-9999 + - regexp: \+1 999-999-9999 + replace: 000000000 + - regexp: 123 Main St. + replace: XXX_MyAddress_XXX + - regexp: Some Town + replace: XXX_YourTown_XXX + - regexp: CA + replace: XXX_State_XXX + - regexp: 99999 + replace: XXX_PostCode_XXX + - regexp: USA + replace: XXX_Country_XXX + - regexp: your.email@yourCompany.com + replace: XXX_adminMail_XXX + - regexp: CHANGE THIS TO YOUR FAVORITE QUOTE + replace: XXX_MyFlagKey_XXX + content_setup_xml_replace_email: false + content_setup_xml_replace_email_items: + - regexp: your.email@yourCompany.com + replace: XXX_YourEmail_XXX + - regexp: your.email@yourCompany.com + replace: XXX_YourEmailUsername_XXX + - regexp: yourPassword + replace: XXX_YourPassword_XXX + - regexp: + replace: + - regexp: your.smtp.host.edu + replace: XXX_YourEmailSmtp_XXX + - regexp: 25 + replace: 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 \ No newline at end of file diff --git a/ansible-role-erddap/files/data/erddap/content.erddap_v211.tar.gz b/ansible-role-erddap/files/data/erddap/content.erddap_v211.tar.gz new file mode 100644 index 0000000..98c4c18 Binary files /dev/null and b/ansible-role-erddap/files/data/erddap/content.erddap_v211.tar.gz differ diff --git a/ansible-role-erddap/files/data/erddap/content.erddap_v214.tar.gz b/ansible-role-erddap/files/data/erddap/content.erddap_v214.tar.gz new file mode 100644 index 0000000..b8615b5 Binary files /dev/null and b/ansible-role-erddap/files/data/erddap/content.erddap_v214.tar.gz differ diff --git a/ansible-role-erddap/files/data/erddap/ssl/erddap-self.localhost_2122.pfx b/ansible-role-erddap/files/data/erddap/ssl/erddap-self.localhost_2122.pfx new file mode 100644 index 0000000..4259d68 Binary files /dev/null and b/ansible-role-erddap/files/data/erddap/ssl/erddap-self.localhost_2122.pfx differ diff --git a/ansible-role-erddap/files/data/erddap/tomcat/server.sslconnetor.xml b/ansible-role-erddap/files/data/erddap/tomcat/server.sslconnetor.xml new file mode 100644 index 0000000..279079e --- /dev/null +++ b/ansible-role-erddap/files/data/erddap/tomcat/server.sslconnetor.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/ansible-role-erddap/files/data/erddap/tomcat/server.sslconnetor.xml.tomcat8 b/ansible-role-erddap/files/data/erddap/tomcat/server.sslconnetor.xml.tomcat8 new file mode 100644 index 0000000..85a57a3 --- /dev/null +++ b/ansible-role-erddap/files/data/erddap/tomcat/server.sslconnetor.xml.tomcat8 @@ -0,0 +1,17 @@ + + diff --git a/ansible-role-erddap/files/data/erddap/tomcat/server.xml b/ansible-role-erddap/files/data/erddap/tomcat/server.xml new file mode 100644 index 0000000..e5411b7 --- /dev/null +++ b/ansible-role-erddap/files/data/erddap/tomcat/server.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ansible-role-erddap/handlers/main.yml b/ansible-role-erddap/handlers/main.yml new file mode 100644 index 0000000..b2a0dce --- /dev/null +++ b/ansible-role-erddap/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for ansible-role-erddap diff --git a/ansible-role-erddap/meta/main.yml b/ansible-role-erddap/meta/main.yml new file mode 100644 index 0000000..c572acc --- /dev/null +++ b/ansible-role-erddap/meta/main.yml @@ -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. diff --git a/ansible-role-erddap/tasks/00_0_erddap-docker-pre-check.yaml b/ansible-role-erddap/tasks/00_0_erddap-docker-pre-check.yaml new file mode 100644 index 0000000..b3d387a --- /dev/null +++ b/ansible-role-erddap/tasks/00_0_erddap-docker-pre-check.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_1_erddap-docker-users.yaml b/ansible-role-erddap/tasks/10_1_erddap-docker-users.yaml new file mode 100644 index 0000000..4b77668 --- /dev/null +++ b/ansible-role-erddap/tasks/10_1_erddap-docker-users.yaml @@ -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 }}" + + +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_2_erddap-docker-directories.yaml b/ansible-role-erddap/tasks/10_2_erddap-docker-directories.yaml new file mode 100644 index 0000000..b04af43 --- /dev/null +++ b/ansible-role-erddap/tasks/10_2_erddap-docker-directories.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_3_erddap-docker-copy-dataFiles.yaml b/ansible-role-erddap/tasks/10_3_erddap-docker-copy-dataFiles.yaml new file mode 100644 index 0000000..8f6862d --- /dev/null +++ b/ansible-role-erddap/tasks/10_3_erddap-docker-copy-dataFiles.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_4_erddap-docker-copy-templates.yaml b/ansible-role-erddap/tasks/10_4_erddap-docker-copy-templates.yaml new file mode 100644 index 0000000..8c0fc97 --- /dev/null +++ b/ansible-role-erddap/tasks/10_4_erddap-docker-copy-templates.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_5_erddap-docker-enabledSSL.yaml b/ansible-role-erddap/tasks/10_5_erddap-docker-enabledSSL.yaml new file mode 100644 index 0000000..855afb8 --- /dev/null +++ b/ansible-role-erddap/tasks/10_5_erddap-docker-enabledSSL.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_6_erddap-docker-extract-content-archive.yaml b/ansible-role-erddap/tasks/10_6_erddap-docker-extract-content-archive.yaml new file mode 100644 index 0000000..94866f7 --- /dev/null +++ b/ansible-role-erddap/tasks/10_6_erddap-docker-extract-content-archive.yaml @@ -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 }}" +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_7_erddap-docker-customazie-content.yaml b/ansible-role-erddap/tasks/10_7_erddap-docker-customazie-content.yaml new file mode 100644 index 0000000..c4c00c0 --- /dev/null +++ b/ansible-role-erddap/tasks/10_7_erddap-docker-customazie-content.yaml @@ -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 }}" +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/10_8_erddap-docker-generate-stack-compose.yaml b/ansible-role-erddap/tasks/10_8_erddap-docker-generate-stack-compose.yaml new file mode 100644 index 0000000..70fca99 --- /dev/null +++ b/ansible-role-erddap/tasks/10_8_erddap-docker-generate-stack-compose.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/20_1_docker_run.yaml b/ansible-role-erddap/tasks/20_1_docker_run.yaml new file mode 100644 index 0000000..2371f9e --- /dev/null +++ b/ansible-role-erddap/tasks/20_1_docker_run.yaml @@ -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 +### ### \ No newline at end of file diff --git a/ansible-role-erddap/tasks/99_1_ubuntu-install-docker.yaml b/ansible-role-erddap/tasks/99_1_ubuntu-install-docker.yaml new file mode 100644 index 0000000..2873457 --- /dev/null +++ b/ansible-role-erddap/tasks/99_1_ubuntu-install-docker.yaml @@ -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 \ No newline at end of file diff --git a/ansible-role-erddap/tasks/erddap-docker.yaml b/ansible-role-erddap/tasks/erddap-docker.yaml new file mode 100644 index 0000000..139967b --- /dev/null +++ b/ansible-role-erddap/tasks/erddap-docker.yaml @@ -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..." \ No newline at end of file diff --git a/ansible-role-erddap/tasks/main.yml b/ansible-role-erddap/tasks/main.yml new file mode 100644 index 0000000..a529fa9 --- /dev/null +++ b/ansible-role-erddap/tasks/main.yml @@ -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 +# # diff --git a/ansible-role-erddap/templates/docker/compose/docker-compose.yaml.j2 b/ansible-role-erddap/templates/docker/compose/docker-compose.yaml.j2 new file mode 100644 index 0000000..a88ecc4 --- /dev/null +++ b/ansible-role-erddap/templates/docker/compose/docker-compose.yaml.j2 @@ -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 %} diff --git a/ansible-role-erddap/templates/docker/entrypoint/erddap_entrypoint.sh.j2 b/ansible-role-erddap/templates/docker/entrypoint/erddap_entrypoint.sh.j2 new file mode 100644 index 0000000..6ef3229 --- /dev/null +++ b/ansible-role-erddap/templates/docker/entrypoint/erddap_entrypoint.sh.j2 @@ -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|org.apache.catalina.filters.CorsFilter|org.apache.catalina.filters.CorsFiltercors.allowed.origins*|' ${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 "//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 "$@" \ No newline at end of file diff --git a/ansible-role-erddap/templates/docker/environment/erddap-compose.env.j2 b/ansible-role-erddap/templates/docker/environment/erddap-compose.env.j2 new file mode 100644 index 0000000..89f0e6d --- /dev/null +++ b/ansible-role-erddap/templates/docker/environment/erddap-compose.env.j2 @@ -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 %} \ No newline at end of file diff --git a/ansible-role-erddap/tests/inventory b/ansible-role-erddap/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/ansible-role-erddap/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/ansible-role-erddap/tests/test.yml b/ansible-role-erddap/tests/test.yml new file mode 100644 index 0000000..cb3f319 --- /dev/null +++ b/ansible-role-erddap/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - ansible-role-erddap diff --git a/main.yaml b/main.yaml new file mode 100644 index 0000000..7221eed --- /dev/null +++ b/main.yaml @@ -0,0 +1,7 @@ +--- +- hosts: all + #remote_user: root + # Privilege escalation to root + become: true + roles: + - ansible-role-erddap