├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── defaults └── main.yml ├── handlers └── main.yml ├── meta └── main.yml ├── tasks ├── CentOS.yml ├── Ubuntu.yml └── main.yml ├── templates ├── atlas.hcl.j2 ├── client.hcl.j2 ├── nomad.conf.j2 ├── nomad.hcl.j2 ├── nomad.systemd.j2 └── server.hcl.j2 ├── tests ├── Dockerfile.centos-6 ├── Dockerfile.centos-7 ├── Dockerfile.ubuntu-14.04 ├── Dockerfile.ubuntu-16.04 └── test.yml └── vars ├── CentOS.yml ├── Ubuntu.yml └── main.yml /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | *.iml 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | 4 | language: generic 5 | 6 | env: 7 | global: 8 | # https://github.com/travis-ci/travis-ci/issues/6461#issuecomment-239577307 9 | DOCKER_VERSION: "1.9.1-0~trusty" 10 | matrix: 11 | - distribution: ubuntu 12 | version: 14.04 13 | init: /sbin/init 14 | run_opts: "" 15 | # - distribution: ubuntu 16 | # version: 16.04 17 | # init: /bin/systemd 18 | # run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" 19 | # - distribution: centos 20 | # version: 6 21 | # init: /sbin/init 22 | # run_opts: "" 23 | # - distribution: centos 24 | # version: 7 25 | # init: /usr/lib/systemd/systemd 26 | # run_opts: "--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro" 27 | 28 | services: 29 | - docker 30 | 31 | before_install: 32 | # Downgrade to specific version of Docker engine 33 | - sudo apt-get update 34 | - sudo apt-get remove docker-engine -yq 35 | - sudo apt-get install docker-engine=$DOCKER_VERSION -yq --no-install-suggests --no-install-recommends --force-yes -o Dpkg::Options::="--force-confnew" 36 | 37 | # Build container 38 | - docker pull ${distribution}:${version} 39 | - docker build --rm=true --file=tests/Dockerfile.${distribution}-${version} --tag=${distribution}-${version}:ansible tests 40 | 41 | script: 42 | - container_id=$(mktemp) 43 | 44 | # Run container in detached state 45 | - docker run --detach --volume="${PWD}":/etc/ansible/roles/ansible-nomad:ro ${run_opts} ${distribution}-${version}:ansible "${init}" > "${container_id}" 46 | 47 | # Display Ansible version 48 | - docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible --version 49 | 50 | # Basic role syntax check 51 | - docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/ansible-nomad/tests/test.yml --syntax-check 52 | 53 | # Run the role/playbook with ansible-playbook 54 | - docker exec --tty "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/ansible-nomad/tests/test.yml 55 | 56 | # Run the role/playbook again, checking to make sure it's idempotent 57 | - > 58 | docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-nomad/tests/test.yml 59 | | grep -q 'changed=0.*failed=0' 60 | && (echo 'Idempotence test: pass' && exit 0) 61 | || (echo 'Idempotence test: fail' && exit 1) 62 | 63 | # Playbook specific tests 64 | # ... 65 | 66 | # Clean up 67 | - docker stop "$(cat ${container_id})" 68 | 69 | notifications: 70 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Kevin Brebanov 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) 2 | 3 | nomad 4 | ===== 5 | 6 | [![Build Status](https://travis-ci.org/kbrebanov/ansible-nomad.svg?branch=master)](https://travis-ci.org/kbrebanov/ansible-nomad) 7 | 8 | Installs and configures Nomad 9 | 10 | Requirements 11 | ------------ 12 | 13 | This role requires Ansible 1.9 or higher. 14 | 15 | Role Variables 16 | -------------- 17 | 18 | | Name | Default | Description | 19 | |:----------------------------------|:-----------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 20 | | nomad_version | 0.4.1 | Version of Nomad to install | 21 | | nomad_sha256sum | 0cdb5dd95c918c6237dddeafe2e9d2049558fea79ed43eacdfcd247d5b093d67 | SHA 256 checksum of package | 22 | | nomad_client | true | Install Nomad client (nomad_server must be false) | 23 | | nomad_server | false | Install Nomad server (nomad_client must be false) | 24 | | nomad_telemetry | false | Enable Nomad telemetry | 25 | | nomad_atlas | false | Enable Atlas | 26 | | nomad_region | "global" | Specifies the region the Nomad agent is a member of | 27 | | nomad_datacenter | "dc1" | Datacenter of the local agent | 28 | | nomad_name | '' | The name of the local node | 29 | | nomad_log_level | "INFO" | Controls the verbosity of logs the Nomad agent will output. Valid log levels include "WARN", "INFO", or "DEBUG" in increasing order of verbosity | 30 | | nomad_bind_addr | "127.0.0.1" | Used to indicate which address the Nomad agent should bind to for network services, including the HTTP interface as well as the internal gossip protocol and RPC mechanism | 31 | | nomad_enable_debug | false | Enables the debugging HTTP endpoints | 32 | | nomad_ports_http | 4646 | The port used to run the HTTP server | 33 | | nomad_ports_rpc | 4647 | The port used for internal RPC communication between agents and servers, and for inter-server traffic for the consensus algorithm (raft) | 34 | | nomad_ports_serf | 4648 | The port used for the gossip protocol for cluster membership | 35 | | nomad_addresses_http | "{{ nomad_bind_addr }}" | The address the HTTP server is bound to | 36 | | nomad_addresses_rpc | "{{ nomad_bind_addr }}" | The address to bind the internal RPC interfaces to | 37 | | nomad_addresses_serf | "{{ nomad_bind_addr }}" | The address used to bind the gossip layer to | 38 | | nomad_advertise_rpc | "{{ nomad_bind_addr }}" | The address to advertise for the RPC interface | 39 | | nomad_advertise_serf | "{{ nomad_bind_addr }}" | The address advertised for the gossip layer | 40 | | nomad_leave_on_interrupt | false | Enables gracefully leaving when receiving the interrupt signal | 41 | | nomad_leave_on_terminate | false | Enables gracefully leaving when receiving the terminate signal | 42 | | nomad_enable_syslog | false | Enables logging to syslog | 43 | | nomad_syslog_facility | "LOCAL0" | Controls the syslog facility that is used | 44 | | nomad_disable_update_check | false | Disables automatic checking for security bulletins and new version releases | 45 | | nomad_disable_anonymous_signature | false | Disables providing an anonymous signature for de-duplication with the update check | 46 | | nomad_telemetry_statsite_address | '' | Address of a statsite server to forward metrics data to | 47 | | nomad_telemetry_statsd_address | '' | Address of a statsd server to forward metrics to | 48 | | nomad_telemetry_disable_hostname | false | Indicates if gauge values should not be prefixed with the local hostname | 49 | | nomad_server_bootstrap_expect | 3 | This is an integer representing the number of server nodes to wait for before bootstrapping | 50 | | nomad_server_data_dir | "{{ nomad_data_dir }}/server" | This is the data directory used for server-specific data, including the replicated log | 51 | | nomad_server_protocol_version | '' | The Nomad protocol version spoken when communicating with other Nomad servers | 52 | | nomad_server_num_schedulers | "{{ ansible_processor_cores }}" | The number of parallel scheduler threads to run. This can be as many as one per core, or 0 to disallow this server from making any scheduling decisions | 53 | | nomad_server_enabled_schedulers | [] | This is an array of strings indicating which sub-schedulers this server will handle | 54 | | nomad_client_state_dir | "{{ nomad_data_dir }}/client" | This is the state dir used to store client state | 55 | | nomad_client_alloc_dir | "{{ nomad_data_dir }}/alloc" | A directory used to store allocation data | 56 | | nomad_client_servers | [] | An array of server addresses | 57 | | nomad_client_node_id | '' | This is the value used to uniquely identify the local agent's node registration with the servers. This can be any arbitrary string but must be unique to the cluster. By default, if not specified, a randomly- generate UUID will be used | 58 | | nomad_client_node_class | '' | A string used to logically group client nodes by class. This can be used during job placement as a filter | 59 | | nomad_client_meta | {} | This is a key/value mapping of metadata pairs | 60 | | nomad_atlas_infrastructure | '' | The Atlas infrastructure name to connect this agent to | 61 | | nomad_atlas_token | '' | The Atlas token to use for authentication | 62 | | nomad_atlas_join | false | Indicates if the auto-join feature of Atlas should be enabled | 63 | | nomad_atlas_endpoint | '' | The address of the Atlas instance to connect to | 64 | | nomad_server_node_gc_threshold | '' | Controls how long a node must be in a terminal state before it is garbage collected and purged from the system | 65 | | nomad_server_rejoin_after_leave | '' | When provided, Nomad will ignore a previous leave and attempt to rejoin the cluster when starting | 66 | | nomad_server_retry_join | [] | Similar to start_join but allows retrying a join if the first attempt fails | 67 | | nomad_server_retry_interval | 30s | The time to wait between join attempts | 68 | | nomad_server_retry_max | 0 | The maximum number of join attempts to be made before exiting with a return code of 1. By default, this is set to 0 which is interpreted as infinite retries | 69 | | nomad_server_start_join | [] | An array of strings specifying addresses of nodes to join upon startup. If Nomad is unable to join with any of the specified addresses, agent startup will fail. | 70 | 71 | 72 | Dependencies 73 | ------------ 74 | 75 | - [kbrebanov.unzip](https://github.com/kbrebanov/ansible-unzip) 76 | 77 | Example Playbook 78 | ---------------- 79 | 80 | Install Nomad 81 | 82 | ```yaml 83 | - hosts: all 84 | roles: 85 | - kbrebanov.nomad 86 | ``` 87 | 88 | License 89 | ------- 90 | 91 | BSD 92 | 93 | Author Information 94 | ------------------ 95 | 96 | Kevin Brebanov 97 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for nomad 3 | 4 | nomad_version: 0.4.1 5 | nomad_sha256sum: 0cdb5dd95c918c6237dddeafe2e9d2049558fea79ed43eacdfcd247d5b093d67 6 | 7 | nomad_client: true 8 | nomad_server: false 9 | nomad_telemetry: false 10 | nomad_atlas: false 11 | 12 | nomad_region: "global" 13 | nomad_datacenter: "dc1" 14 | nomad_name: '' 15 | nomad_log_level: "INFO" 16 | nomad_bind_addr: "127.0.0.1" 17 | nomad_enable_debug: false 18 | nomad_ports_http: 4646 19 | nomad_ports_rpc: 4647 20 | nomad_ports_serf: 4648 21 | nomad_addresses_http: "{{ nomad_bind_addr }}" 22 | nomad_addresses_rpc: "{{ nomad_bind_addr }}" 23 | nomad_addresses_serf: "{{ nomad_bind_addr }}" 24 | nomad_advertise_rpc: "{{ nomad_bind_addr }}" 25 | nomad_advertise_serf: "{{ nomad_bind_addr }}" 26 | nomad_leave_on_interrupt: false 27 | nomad_leave_on_terminate: false 28 | nomad_enable_syslog: false 29 | nomad_syslog_facility: "LOCAL0" 30 | nomad_disable_update_check: false 31 | nomad_disable_anonymous_signature: false 32 | 33 | nomad_telemetry_statsite_address: '' 34 | nomad_telemetry_statsd_address: '' 35 | nomad_telemetry_disable_hostname: false 36 | 37 | nomad_server_bootstrap_expect: 3 38 | nomad_server_data_dir: "{{ nomad_data_dir }}/server" 39 | nomad_server_protocol_version: '' 40 | nomad_server_num_schedulers: "{{ ansible_processor_cores }}" 41 | nomad_server_enabled_schedulers: [] 42 | nomad_server_node_gc_threshold: '' 43 | nomad_server_rejoin_after_leave: '' 44 | nomad_server_retry_join: [] 45 | nomad_server_retry_interval: 30s 46 | nomad_server_retry_max: 0 47 | nomad_server_start_join: [] 48 | 49 | nomad_client_state_dir: "{{ nomad_data_dir }}/client" 50 | nomad_client_alloc_dir: "{{ nomad_data_dir }}/alloc" 51 | nomad_client_servers: [] 52 | nomad_client_node_id: '' 53 | nomad_client_node_class: '' 54 | nomad_client_meta: {} 55 | 56 | nomad_atlas_infrastructure: '' 57 | nomad_atlas_token: '' 58 | nomad_atlas_join: false 59 | nomad_atlas_endpoint: '' 60 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for nomad 3 | 4 | - name: restart nomad 5 | become: yes 6 | service: 7 | name: "{{ nomad_service_name }}" 8 | state: restarted 9 | tags: 10 | - nomad 11 | 12 | - name: reload nomad 13 | become: yes 14 | service: 15 | name: "{{ nomad_service_name }}" 16 | state: reloaded 17 | tags: 18 | - nomad 19 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Kevin Brebanov 4 | description: Installs Nomad 5 | company: 6 | license: BSD 7 | min_ansible_version: 1.9 8 | github_branch: master 9 | platforms: 10 | - name: Ubuntu 11 | versions: 12 | - trusty 13 | galaxy_tags: 14 | - cloud 15 | - clustering 16 | dependencies: 17 | - kbrebanov.unzip 18 | -------------------------------------------------------------------------------- /tasks/CentOS.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for nomad (CentOS specific) 3 | -------------------------------------------------------------------------------- /tasks/Ubuntu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for nomad (Ubuntu specific) 3 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for nomad 3 | 4 | - name: Check if both nomad_server and nomad_client set 5 | fail: msg='nomad_server and nomad_client were both set. According to https://nomadproject.io/docs/agent/config.html, "Note that it is strongly recommended not to operate a node as both client and server".' 6 | when: nomad_server and nomad_client 7 | 8 | - name: Include distribution specific variables 9 | include_vars: "{{ ansible_distribution }}.yml" 10 | tags: 11 | - nomad 12 | 13 | - include: CentOS.yml 14 | when: ansible_distribution == "CentOS" 15 | tags: 16 | - nomad 17 | 18 | - include: Ubuntu.yml 19 | when: ansible_distribution == "Ubuntu" 20 | tags: 21 | - nomad 22 | 23 | - name: Create Nomad group 24 | become: yes 25 | group: 26 | name: "{{ nomad_group }}" 27 | system: yes 28 | state: present 29 | when: nomad_server 30 | tags: 31 | - nomad 32 | 33 | - name: Create Nomad user 34 | become: yes 35 | user: 36 | name: "{{ nomad_user }}" 37 | shell: /bin/false 38 | createhome: no 39 | group: "{{ nomad_group }}" 40 | system: yes 41 | state: present 42 | when: nomad_server 43 | tags: 44 | - nomad 45 | 46 | - name: Check if Nomad is already installed 47 | stat: 48 | path: "{{ nomad_install_dir }}/nomad" 49 | register: nomad_bin 50 | changed_when: false 51 | tags: 52 | - nomad 53 | 54 | - name: Get currently installed Nomad version 55 | shell: "{{ nomad_install_dir }}/nomad version | grep '^Nomad' | cut -d' ' -f2 | sed -e 's/^v//'" 56 | register: installed_nomad_version 57 | when: nomad_bin.stat.exists 58 | changed_when: false 59 | tags: 60 | - nomad 61 | 62 | - name: Get list of installed Nomad files 63 | shell: ls -1 {{ nomad_install_dir }}/nomad* 64 | register: nomad_files 65 | when: not installed_nomad_version | skipped 66 | changed_when: false 67 | tags: 68 | - nomad 69 | 70 | - name: Download Nomad 71 | become: yes 72 | get_url: 73 | url: "{{ nomad_url }}" 74 | dest: "{{ nomad_download_dir }}/nomad.zip" 75 | sha256sum: "{{ nomad_sha256sum }}" 76 | tags: 77 | - nomad 78 | 79 | - name: Remove Nomad files if version is different 80 | become: yes 81 | file: 82 | path: "{{ item }}" 83 | state: absent 84 | with_items: 85 | - "{{ nomad_files.stdout_lines | default([]) }}" 86 | when: 87 | - not installed_nomad_version | skipped 88 | - installed_nomad_version.stdout | version_compare(nomad_version, operator='lt', strict=True) 89 | notify: 90 | - restart nomad 91 | tags: 92 | - nomad 93 | 94 | - name: Unzip Nomad to installation directory 95 | become: yes 96 | command: unzip {{ nomad_download_dir }}/nomad.zip -d {{ nomad_install_dir }} 97 | args: 98 | creates: "{{ nomad_install_dir }}/nomad" 99 | tags: 100 | - nomad 101 | 102 | - name: Create Nomad configuration directory 103 | become: yes 104 | file: 105 | path: "{{ nomad_config_dir }}" 106 | owner: root 107 | group: root 108 | mode: 0755 109 | state: directory 110 | tags: 111 | - nomad 112 | 113 | - name: Create Nomad data directory 114 | become: yes 115 | file: 116 | path: "{{ nomad_data_dir }}" 117 | owner: "{{ nomad_user }}" 118 | group: "{{ nomad_group }}" 119 | mode: 0755 120 | state: directory 121 | tags: 122 | - nomad 123 | 124 | - name: Create Nomad upstart configuration 125 | become: yes 126 | template: 127 | src: nomad.conf.j2 128 | dest: /etc/init/nomad.conf 129 | owner: root 130 | group: root 131 | mode: 0644 132 | notify: 133 | - restart nomad 134 | tags: 135 | - nomad 136 | when: not (ansible_distribution == "Ubuntu" and ansible_distribution_version|int >= 16) 137 | 138 | - name: Create Nomad systemd configuration 139 | become: yes 140 | template: 141 | src: nomad.systemd.j2 142 | dest: /etc/systemd/system/nomad.service 143 | owner: root 144 | group: root 145 | mode: 0644 146 | notify: 147 | - restart nomad 148 | tags: 149 | - nomad 150 | when: ansible_distribution == "Ubuntu" and ansible_distribution_version|int >= 16 151 | 152 | - name: Create Nomad configuration file 153 | become: yes 154 | template: 155 | src: nomad.hcl.j2 156 | dest: "{{ nomad_config_dir }}/nomad.hcl" 157 | owner: root 158 | group: root 159 | mode: 0644 160 | notify: 161 | - restart nomad 162 | tags: 163 | - nomad 164 | 165 | - name: Create Nomad server configuration file 166 | become: yes 167 | template: 168 | src: server.hcl.j2 169 | dest: "{{ nomad_config_dir }}/server.hcl" 170 | owner: root 171 | group: root 172 | mode: 0644 173 | notify: 174 | - restart nomad 175 | when: nomad_server 176 | tags: 177 | - nomad 178 | 179 | - name: Create Nomad client configuration file 180 | become: yes 181 | template: 182 | src: client.hcl.j2 183 | dest: "{{ nomad_config_dir }}/client.hcl" 184 | owner: root 185 | group: root 186 | mode: 0644 187 | notify: 188 | - restart nomad 189 | when: nomad_client 190 | tags: 191 | - nomad 192 | 193 | - name: Create Nomad Atlas configuration file 194 | become: yes 195 | template: 196 | src: atlas.hcl.j2 197 | dest: "{{ nomad_config_dir }}/atlas.hcl" 198 | owner: root 199 | group: root 200 | mode: 0644 201 | notify: 202 | - restart nomad 203 | when: nomad_atlas 204 | tags: 205 | - nomad 206 | 207 | - name: Ensure Nomad service is started and enabled on boot 208 | become: yes 209 | service: 210 | name: "{{ nomad_service_name }}" 211 | state: started 212 | enabled: yes 213 | tags: 214 | - nomad 215 | -------------------------------------------------------------------------------- /templates/atlas.hcl.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | atlas { 4 | {% if nomad_atlas_infrastructure and nomad_atlas %} 5 | infrastructure = "{{ nomad_atlas_infrastructure }}" 6 | {% endif %} 7 | {% if nomad_atlas_token and nomad_atlas %} 8 | token = "{{ nomad_atlas_token }}" 9 | {% endif %} 10 | {% if nomad_atlas_join and nomad_atlas %} 11 | {% if nomad_atlas_join %} 12 | join = true 13 | {% else %} 14 | join = false 15 | {% endif %} 16 | {% endif %} 17 | {% if nomad_atlas_endpoint and nomad_atlas %} 18 | endpoint = "{{ nomad_atlas_endpoint }}" 19 | {% endif %} 20 | } 21 | -------------------------------------------------------------------------------- /templates/client.hcl.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | client { 4 | {% if nomad_client %} 5 | enabled = true 6 | {% else %} 7 | enabled = false 8 | {% endif %} 9 | {% if nomad_client_state_dir and nomad_client %} 10 | state_dir = "{{ nomad_client_state_dir }}" 11 | {% endif %} 12 | {% if nomad_client_alloc_dir and nomad_client %} 13 | alloc_dir = "{{ nomad_client_alloc_dir }}" 14 | {% endif %} 15 | {% if nomad_client_servers and nomad_client %} 16 | servers = [ 17 | {% for server in nomad_client_servers %} 18 | {% if not loop.last %} 19 | "{{ server }}", 20 | {% else %} 21 | "{{ server }}" 22 | {% endif %} 23 | {% endfor %} 24 | ] 25 | {% endif %} 26 | {% if nomad_client_node_id and nomad_client %} 27 | node_id = "{{ nomad_client_node_id }}" 28 | {% endif %} 29 | {% if nomad_client_node_class and nomad_client %} 30 | node_class = "{{ nomad_client_node_class }}" 31 | {% endif %} 32 | {% if nomad_client_meta and nomad_client %} 33 | meta { 34 | {% for meta in nomad_client %} 35 | "{{ meta }}" = "{{ nomad_client_meta[meta] }}" 36 | {% endfor %} 37 | } 38 | {% endif %} 39 | } 40 | -------------------------------------------------------------------------------- /templates/nomad.conf.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | description "Service for nomad" 4 | author "Kevin Brebanov" 5 | 6 | start on filesystem or runlevel [2345] 7 | stop on shutdown 8 | 9 | reload signal SIGHUP 10 | 11 | respawn 12 | respawn limit 10 10 13 | kill timeout 10 14 | 15 | script 16 | {% if nomad_client and not nomad_server %} 17 | exec start-stop-daemon --start --chuid {{ nomad_user }} --group {{ nomad_group }} --pidfile {{ nomad_pid_file }} --make-pidfile --exec {{ nomad_install_dir }}/nomad -- agent -client -config={{ nomad_config_dir }} > {{ nomad_log_file }} 2>&1 18 | {% endif %} 19 | {% if nomad_server and not nomad_client %} 20 | exec start-stop-daemon --start --chuid {{ nomad_user }} --group {{ nomad_group }} --pidfile {{ nomad_pid_file }} --make-pidfile --exec {{ nomad_install_dir }}/nomad -- agent -server -config={{ nomad_config_dir }} > {{ nomad_log_file }} 2>&1 21 | {% endif %} 22 | end script 23 | 24 | post-stop script 25 | rm -f {{ nomad_pid_file }} 26 | end script 27 | -------------------------------------------------------------------------------- /templates/nomad.hcl.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | region = "{{ nomad_region }}" 4 | datacenter = "{{ nomad_datacenter }}" 5 | {% if nomad_name %} 6 | name = "{{ nomad_name }}" 7 | {% endif %} 8 | data_dir = "{{ nomad_data_dir }}" 9 | log_level = "{{ nomad_log_level }}" 10 | bind_addr = "{{ nomad_bind_addr }}" 11 | {% if nomad_enable_debug %} 12 | enable_debug = true 13 | {% else %} 14 | enable_debug = false 15 | {% endif %} 16 | ports { 17 | http = {{ nomad_ports_http }} 18 | {% if nomad_ports_rpc and nomad_server %} 19 | rpc = {{ nomad_ports_rpc }} 20 | {% endif %} 21 | {% if nomad_ports_serf and nomad_server %} 22 | serf = {{ nomad_ports_serf }} 23 | {% endif %} 24 | } 25 | addresses { 26 | http = "{{ nomad_addresses_http }}" 27 | {% if nomad_addresses_rpc and nomad_server %} 28 | rpc = "{{ nomad_addresses_rpc }}" 29 | {% endif %} 30 | {% if nomad_addresses_serf and nomad_server %} 31 | serf = "{{ nomad_addresses_serf }}" 32 | {% endif %} 33 | } 34 | advertise { 35 | {% if nomad_advertise_rpc and nomad_ports_rpc and nomad_server %} 36 | rpc = "{{ nomad_advertise_rpc }}:{{ nomad_ports_rpc }}" 37 | {% endif %} 38 | {% if nomad_advertise_serf and nomad_ports_serf and nomad_server %} 39 | serf = "{{ nomad_advertise_serf }}:{{ nomad_ports_serf }}" 40 | {% endif %} 41 | } 42 | {% if nomad_telemetry %} 43 | telemetry { 44 | {% if nomad_telemetry_statsite_address %} 45 | statsite_address = "{{ nomad_telemetry_statsite_address }}" 46 | {% endif %} 47 | {% if nomad_telemetry_statsd_address %} 48 | statsd_address = "{{ nomad_telemetry_statsd_address }}" 49 | {% endif %} 50 | {% if nomad_telemetry_disable_hostname %} 51 | disable_hostname = true 52 | {% else %} 53 | disable_hostname = false 54 | {% endif %} 55 | } 56 | {% endif %} 57 | {% if nomad_leave_on_interrupt %} 58 | leave_on_interrupt = true 59 | {% else %} 60 | leave_on_interrupt = false 61 | {% endif %} 62 | {% if nomad_leave_on_terminate %} 63 | leave_on_terminate = true 64 | {% else %} 65 | leave_on_terminate = false 66 | {% endif %} 67 | {% if nomad_enable_syslog %} 68 | enable_syslog = true 69 | {% else %} 70 | enable_syslog = false 71 | {% endif %} 72 | {% if nomad_syslog_facility and nomad_enable_syslog %} 73 | syslog_facility = "{{ nomad_syslog_facility }}" 74 | {% endif %} 75 | {% if nomad_disable_update_check %} 76 | disable_update_check = true 77 | {% else %} 78 | disable_update_check = false 79 | {% endif %} 80 | {% if nomad_disable_anonymous_signature %} 81 | disable_anonymous_signature = true 82 | {% else %} 83 | disable_anonymous_signature = false 84 | {% endif %} 85 | -------------------------------------------------------------------------------- /templates/nomad.systemd.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | [Unit] 3 | Description=Service for nomad 4 | After=network-online.target local-fs.target 5 | Requires=network-online.target 6 | Conflicts=shutdown.target 7 | 8 | [Service] 9 | User={{ nomad_user }} 10 | Group={{ nomad_group }} 11 | PIDFile={{ nomad_pid_file }} 12 | PermissionsStartOnly=true 13 | Type=forking 14 | ExecStartPre=/bin/sh -c 'touch {{ nomad_log_file }} && chown {{ nomad_user }}:{{ nomad_user }} {{ nomad_log_file }}' 15 | ExecStartPre=/bin/sh -c 'touch {{ nomad_pid_file }} && chown {{ nomad_user }}:{{ nomad_user }} {{ nomad_pid_file }}' 16 | ExecStart=/bin/sh -c '{{ nomad_install_dir }}/nomad agent -{% if nomad_server %}server{% else %}client{% endif %} -config={{ nomad_config_dir }} > {{ nomad_log_file }} 2>&1 & echo $! > {{ nomad_pid_file }}' 17 | ExecStopPost=/bin/rm -f {{ nomad_pid_file }} 18 | KillMode=process 19 | KillSignal=SIGTERM 20 | TimeoutStopSec=10 21 | ExecReload=/bin/kill -HUP $MAINPID 22 | Restart=on-failure 23 | RestartSec=10 24 | 25 | [Install] 26 | WantedBy=multi-user.target 27 | -------------------------------------------------------------------------------- /templates/server.hcl.j2: -------------------------------------------------------------------------------- 1 | # {{ ansible_managed }} 2 | 3 | server { 4 | {% if nomad_server %} 5 | enabled = true 6 | {% else %} 7 | enabled = false 8 | {% endif %} 9 | {% if nomad_server_bootstrap_expect and nomad_server %} 10 | bootstrap_expect = {{ nomad_server_bootstrap_expect }} 11 | {% endif %} 12 | {% if nomad_server_data_dir and nomad_server %} 13 | data_dir = "{{ nomad_server_data_dir }}" 14 | {% endif %} 15 | {% if nomad_server_protocol_version and nomad_server %} 16 | protocol_version = {{ nomad_server_protocol_version }} 17 | {% endif %} 18 | {% if nomad_server_num_schedulers and nomad_server %} 19 | num_schedulers = {{ nomad_server_num_schedulers }} 20 | {% endif %} 21 | {% if nomad_server_enabled_schedulers and nomad_server %} 22 | enabled_schedulers = [ 23 | {% for scheduler in nomad_server_enabled_schedulers %} 24 | {% if not loop.last %} 25 | "{{ scheduler }}", 26 | {% else %} 27 | "{{ scheduler }}" 28 | {% endif %} 29 | {% endfor %} 30 | ] 31 | {% endif %} 32 | {% if nomad_server_node_gc_threshold and nomad_server %} 33 | node_gc_threshold = "{{ nomad_server_node_gc_threshold }}" 34 | {% endif %} 35 | {% if nomad_server_rejoin_after_leave and nomad_server %} 36 | rejoin_after_leave = "{{ nomad_server_rejoin_after_leave }}" 37 | {% endif %} 38 | {% if nomad_server_retry_join and nomad_server %} 39 | retry_join = [ 40 | {% for node_address in nomad_server_retry_join %} 41 | {% if not loop.last %} 42 | "{{ node_address }}", 43 | {% else %} 44 | "{{ node_address }}" 45 | {% endif %} 46 | {% endfor %} 47 | ] 48 | {% endif %} 49 | {% if nomad_server_retry_interval and nomad_server %} 50 | retry_interval = "{{ nomad_server_retry_interval }}" 51 | {% endif %} 52 | {% if nomad_server_retry_max and nomad_server %} 53 | retry_max = "{{ nomad_server_retry_max }}" 54 | {% endif %} 55 | {% if nomad_server_start_join and nomad_server %} 56 | start_join = [ 57 | {% for node_address in nomad_server_start_join %} 58 | {% if not loop.last %} 59 | "{{ node_address }}", 60 | {% else %} 61 | "{{ node_address }}" 62 | {% endif %} 63 | {% endfor %} 64 | ] 65 | {% endif %} 66 | } 67 | -------------------------------------------------------------------------------- /tests/Dockerfile.centos-6: -------------------------------------------------------------------------------- 1 | FROM centos:6 2 | 3 | RUN yum -y update; yum clean all 4 | 5 | # Install EPEL 6 | RUN yum -y install wget; \ 7 | wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm; \ 8 | yum -y --nogpgcheck localinstall epel-release-6-8.noarch.rpm; \ 9 | yum clean all 10 | 11 | # Install Ansible 12 | RUN yum -y install ansible 13 | 14 | # Create Ansible configuration file 15 | RUN echo -e "[defaults]\nroles_path = /etc/ansible/roles\nretry_files_enabled = False" > /etc/ansible/ansible.cfg 16 | 17 | # Create Ansible inventory file 18 | RUN echo -e "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts 19 | 20 | # Install role dependencies 21 | RUN ansible-galaxy install kbrebanov.unzip 22 | 23 | CMD ["/usr/sbin/init"] 24 | -------------------------------------------------------------------------------- /tests/Dockerfile.centos-7: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | # Install systemd -- See https://hub.docker.com/_/centos/ 4 | RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs 5 | RUN yum -y update; yum clean all; \ 6 | (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ 7 | rm -f /lib/systemd/system/multi-user.target.wants/*; \ 8 | rm -f /etc/systemd/system/*.wants/*; \ 9 | rm -f /lib/systemd/system/local-fs.target.wants/*; \ 10 | rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ 11 | rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ 12 | rm -f /lib/systemd/system/basic.target.wants/*; \ 13 | rm -f /lib/systemd/system/anaconda.target.wants/*; 14 | 15 | RUN yum -y update; yum clean all 16 | 17 | # Install EPEL 18 | RUN yum -y install wget; \ 19 | wget http://download.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-8.noarch.rpm; \ 20 | yum -y --nogpgcheck localinstall epel-release-7-8.noarch.rpm; \ 21 | yum clean all 22 | 23 | # Install Ansible 24 | RUN yum -y install ansible 25 | 26 | # Create Ansible configuration file 27 | RUN echo -e "[defaults]\nroles_path = /etc/ansible/roles\nretry_files_enabled = False" > /etc/ansible/ansible.cfg 28 | 29 | # Create Ansible inventory file 30 | RUN echo -e "[local]\nlocalhost ansible_connection=local" > /etc/ansible/hosts 31 | 32 | # Install role dependencies 33 | RUN ansible-galaxy install kbrebanov.unzip 34 | 35 | VOLUME ["/sys/fs/cgroup"] 36 | CMD ["/usr/sbin/init"] 37 | -------------------------------------------------------------------------------- /tests/Dockerfile.ubuntu-14.04: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | 3 | RUN apt-get -qq update 4 | 5 | # Install Ansible 6 | RUN apt-get -y install software-properties-common apt-transport-https; \ 7 | apt-add-repository ppa:ansible/ansible; \ 8 | apt-get -qq update; \ 9 | apt-get -y install ansible 10 | 11 | # Create Ansible configuration file 12 | RUN printf "[defaults]\nroles_path = /etc/ansible/roles\nretry_files_enabled = False" > /etc/ansible/ansible.cfg 13 | 14 | # Create Ansible inventory file 15 | RUN printf "[local]\nlocalhost ansible_connection=local\n" > /etc/ansible/hosts 16 | 17 | # Install role dependencies 18 | RUN ansible-galaxy install kbrebanov.unzip 19 | -------------------------------------------------------------------------------- /tests/Dockerfile.ubuntu-16.04: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | RUN apt-get -qq update 4 | 5 | # Install Ansible 6 | RUN apt-get -y install software-properties-common apt-transport-https; \ 7 | apt-add-repository ppa:ansible/ansible; \ 8 | apt-get -qq update; \ 9 | apt-get -y install ansible 10 | 11 | # Create Ansible configuration file 12 | RUN printf "[defaults]\nroles_path = /etc/ansible/roles\nretry_files_enabled = False" > /etc/ansible/ansible.cfg 13 | 14 | # Create Ansible inventory file 15 | RUN printf "[local]\nlocalhost ansible_connection=local\n" > /etc/ansible/hosts 16 | 17 | # Install role dependencies 18 | RUN ansible-galaxy install kbrebanov.unzip 19 | -------------------------------------------------------------------------------- /tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - name: ansible-nomad 6 | -------------------------------------------------------------------------------- /vars/CentOS.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for nomad (CentOS specific) 3 | -------------------------------------------------------------------------------- /vars/Ubuntu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for nomad (Ubuntu specific) 3 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for nomad 3 | 4 | nomad_url: https://releases.hashicorp.com/nomad/{{ nomad_version }}/nomad_{{ nomad_version }}_linux_amd64.zip 5 | nomad_download_dir: /root 6 | nomad_install_dir: /usr/local/bin 7 | nomad_data_dir: /var/lib/nomad 8 | nomad_config_dir: /etc/nomad.d 9 | nomad_pid_file: /var/run/nomad.pid 10 | nomad_log_file: /var/log/nomad.log 11 | nomad_user: "{% if nomad_server %}nomad{% else %}root{% endif %}" 12 | nomad_group: "{% if nomad_server %}nomad{% else %}root{% endif %}" 13 | nomad_service_name: nomad 14 | --------------------------------------------------------------------------------