diff --git a/roles/service/meta/argument_specs.yaml b/roles/service/meta/argument_specs.yaml index b53c525..569de49 100644 --- a/roles/service/meta/argument_specs.yaml +++ b/roles/service/meta/argument_specs.yaml @@ -50,11 +50,13 @@ argument_specs: choices: - volume - bind + - template source: description: - Mount source. - If mount type is volume, name of the volume. - If mount type is bind, host path to bind mount inside the container. + - If mount type is template, the name of the template file, must end in .j2 type: str required: true destination: @@ -62,10 +64,11 @@ argument_specs: type: str required: true readonly: - description: If true, volume will be mounted as read only inside the container + description: + - If true, volume will be mounted as read only inside the container. + - Defaults to false for volume and bind, true for template type: bool required: false - default: false service_container_secrets: description: A list of secrets available to the service container in /run/secrets/- type: list @@ -145,11 +148,13 @@ argument_specs: choices: - volume - bind + - template source: description: - Mount source. - If mount type is volume, name of the volume. - If mount type is bind, host path to bind mount inside the container. + - If mount type is template, the name of the template file, must end in .j2 type: str required: true destination: @@ -157,10 +162,11 @@ argument_specs: type: str required: true readonly: - description: If true, volume will be mounted as read only inside the container + description: + - If true, volume will be mounted as read only inside the container + - Defaults to false for volume and bind, true for template type: bool required: false - default: false publish_ports: description: "A list of published ports in docker format (::)" type: list diff --git a/roles/service/tasks/main.yaml b/roles/service/tasks/main.yaml index b159017..a4b1869 100644 --- a/roles/service/tasks/main.yaml +++ b/roles/service/tasks/main.yaml @@ -25,7 +25,7 @@ when: service_container_mounts | length > 0 - name: Main container for {{ service_name }} - ansible.builtin.include_role: + ansible.builtin.import_role: name: container vars: container_name: "{{ service_name }}" diff --git a/roles/service/tasks/mount.yaml b/roles/service/tasks/mount.yaml new file mode 100644 index 0000000..82519f7 --- /dev/null +++ b/roles/service/tasks/mount.yaml @@ -0,0 +1,32 @@ +--- +- name: Set container named mounts + ansible.builtin.set_fact: + _service_container_mounts: > + {{ _service_container_mounts + + [mount | combine({'source': service_name + '-' + mount.source})] }} + when: mount.type == 'volume' + +- name: Set container named mounts + ansible.builtin.set_fact: + _service_container_mounts: "{{ _service_container_mounts + [mount] }}" + when: mount.type == 'bind' + +- name: Template mounts + when: mount.type == 'template' + block: + - name: Set template host path + ansible.builtin.set_fact: + _service_template_host_path: "{{ _service_host_directory }}/mounts/{{ (mount.source | split('.'))[0:-1] | join('.') }}" # Strip .j2 extension + + - name: Template files for template mounts + ansible.builtin.template: + src: "{{ mount.source }}" + dest: "{{ _service_template_host_path }}" + mode: "0644" + notify: "Restart container service {{ service_name }}" + + - name: Set container template mounts + ansible.builtin.set_fact: + _service_container_mounts: > + {{ _service_container_mounts + + [{'readonly': true} | combine(mount) | combine({'type': 'bind', 'source': _service_template_host_path})] }} diff --git a/roles/service/tasks/mounts.yaml b/roles/service/tasks/mounts.yaml index 459484a..4e6f9ac 100644 --- a/roles/service/tasks/mounts.yaml +++ b/roles/service/tasks/mounts.yaml @@ -1,18 +1,21 @@ --- -- name: Set container named mounts - ansible.builtin.set_fact: - _service_container_mounts: > - {{ _service_container_mounts + - [mount | combine({'source': service_name + '-' + mount.source})] }} - when: mount.type == 'volume' - loop: "{{ service_container_mounts }}" - loop_control: - loop_var: mount +- name: Create template mount directories under /srv + when: _service_template_mounts | length > 0 + block: + - name: Create directory {{ _service_host_directory }} + ansible.builtin.file: + path: "{{ _service_host_directory }}" + state: directory + mode: "0755" -- name: Set container named mounts - ansible.builtin.set_fact: - _service_container_mounts: "{{ _service_container_mounts + [mount] }}" - when: mount.type == 'bind' + - name: Create directory {{ _service_host_directory + '/mounts' }} + ansible.builtin.file: + path: "{{ _service_host_directory }}/mounts" + state: directory + mode: "0700" + +- name: Set mount definitions for {{ service_name }} + ansible.builtin.include_tasks: mount.yaml loop: "{{ service_container_mounts }}" loop_control: loop_var: mount diff --git a/roles/service/tasks/validation.yaml b/roles/service/tasks/validation.yaml index ecdedb5..e739e6c 100644 --- a/roles/service/tasks/validation.yaml +++ b/roles/service/tasks/validation.yaml @@ -8,3 +8,9 @@ ansible.builtin.fail: msg: "service_postgres_tag needs to be set when database type is postgres" when: "service_database_type == 'postgres' and service_postgres_tag is not defined" + +- name: Fail if template mount source doesn't end in .j2 + ansible.builtin.fail: + msg: "Template mount source file name needs to end in .j2. The file {{ item.source }} of {{ service_name }} doesn't." + when: "item.source | split('.') | last != 'j2'" + loop: "{{ _service_template_mounts }}" diff --git a/roles/service/vars/main.yaml b/roles/service/vars/main.yaml new file mode 100644 index 0000000..c3c21af --- /dev/null +++ b/roles/service/vars/main.yaml @@ -0,0 +1,3 @@ +--- +_service_template_mounts: "{{ service_container_mounts | selectattr('type', '==', 'template') | list }}" +_service_host_directory: "/srv/{{ service_name }}"