diff options
-rw-r--r-- | .travis.yml | 29 | ||||
-rw-r--r-- | README.md | 61 | ||||
-rw-r--r-- | defaults/main.yml | 15 | ||||
-rw-r--r-- | files/clever-set-domain.sh | 11 | ||||
-rw-r--r-- | files/clever-set-drain.sh | 11 | ||||
-rw-r--r-- | files/clever-wait-deploy.sh | 50 | ||||
-rw-r--r-- | handlers/main.yml | 2 | ||||
-rw-r--r-- | meta/main.yml | 60 | ||||
-rw-r--r-- | tasks/addon.yml | 9 | ||||
-rw-r--r-- | tasks/deploy.yml | 30 | ||||
-rw-r--r-- | tasks/environment.yml | 11 | ||||
-rw-r--r-- | tasks/login.yml | 15 | ||||
-rw-r--r-- | tasks/main.yml | 32 | ||||
-rw-r--r-- | tasks/setup.yml | 28 | ||||
-rw-r--r-- | templates/cleverlogin.j2 | 4 | ||||
-rw-r--r-- | templates/env.j2 | 3 | ||||
-rw-r--r-- | tests/inventory | 2 | ||||
-rw-r--r-- | tests/test.yml | 5 | ||||
-rw-r--r-- | vars/main.yml | 2 |
19 files changed, 380 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..49e7e1c --- /dev/null +++ b/.travis.yml | |||
@@ -0,0 +1,29 @@ | |||
1 | --- | ||
2 | language: python | ||
3 | python: "2.7" | ||
4 | |||
5 | # Use the new container infrastructure | ||
6 | sudo: false | ||
7 | |||
8 | # Install ansible | ||
9 | addons: | ||
10 | apt: | ||
11 | packages: | ||
12 | - python-pip | ||
13 | |||
14 | install: | ||
15 | # Install ansible | ||
16 | - pip install ansible | ||
17 | |||
18 | # Check ansible version | ||
19 | - ansible --version | ||
20 | |||
21 | # Create ansible.cfg with correct roles_path | ||
22 | - printf '[defaults]\nroles_path=../' >ansible.cfg | ||
23 | |||
24 | script: | ||
25 | # Basic role syntax check | ||
26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check | ||
27 | |||
28 | notifications: | ||
29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ | ||
@@ -1,2 +1,63 @@ | |||
1 | # ansible-clever | 1 | # ansible-clever |
2 | Ansible role for clever cloud deployment | 2 | Ansible role for clever cloud deployment |
3 | ======= | ||
4 | Clever deploy | ||
5 | ========= | ||
6 | |||
7 | This roles deploy an haskell app on clever cloud (https://www.clever-cloud.com). | ||
8 | |||
9 | Requirements | ||
10 | ------------ | ||
11 | |||
12 | |||
13 | Role Variables | ||
14 | -------------- | ||
15 | |||
16 | Variables for the application | ||
17 | - `clever_token`: clever_cloud token, mandatory. | ||
18 | - `clever_secret`: clever_cloud secret, mandatory. | ||
19 | - `clever_app`: the id of the app to link, mandatory. | ||
20 | - `clever_env`: a dict of environment variables for the application (without add_ons one already available), optional. | ||
21 | - `clever_addons`: a list of dict describing addons enabled for the application from which we would use information during deploy, optional.<br/> | ||
22 | Example: `{ name: pg, env_prefix: POSTGRESQL_ADDON }` | ||
23 | - `clever_app_tasks`: tasks file to be executed after environment and addons variables where gathered. Specific to an app, should be use to run migrations. Optional. | ||
24 | - `domain`: the domain from which the application should be reachable, optional | ||
25 | - `syslog_server`: UDP Syslog server to be used as UDPSyslog drain for the application, optional. Example: `udp://198.51.100.51:12345`. | ||
26 | |||
27 | Variables specific to deployment, default should be fine: | ||
28 | - `clever_cli_version`: Version of clever cli tools, default to `0.9.3`. | ||
29 | - `clever_user_path`: Path relative to ansible_user home dir where cli tools and helpers are installed default to `.local/bin`. | ||
30 | - `clever_app_root`: Path of the application to deploy, default to `"{{ playbook_dir }}/.."`, ie ansible directory in the root of the application. | ||
31 | - `clever_app_confdir`: Path where to store clever cloud data specific to this application, default to `"{{ clever_app_root }}/.clever_cloud"` | ||
32 | - `clever_login_file`: Path to store login information. Default to `"{{ clever_app_confdir }}/login"`. | ||
33 | |||
34 | |||
35 | Dependencies | ||
36 | ------------ | ||
37 | |||
38 | None | ||
39 | |||
40 | Example Playbook | ||
41 | ---------------- | ||
42 | |||
43 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: | ||
44 | |||
45 | - hosts: servers | ||
46 | roles: | ||
47 | - { role: fretlink.clever, clever_app: 42, clever_token: "{{ vault_clever_token }}", clever_secret: "{{ vault_clever_secret}}" } | ||
48 | |||
49 | |||
50 | TODO | ||
51 | ---- | ||
52 | |||
53 | Add some tests and Travis integration | ||
54 | |||
55 | License | ||
56 | ------- | ||
57 | |||
58 | BSD | ||
59 | |||
60 | Author Information | ||
61 | ------------------ | ||
62 | |||
63 | Developped at Fretlink (https://www.fretlink.com) for our | ||
diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..eaf3173 --- /dev/null +++ b/defaults/main.yml | |||
@@ -0,0 +1,15 @@ | |||
1 | --- | ||
2 | # defaults file for clever | ||
3 | clever_cli_version: 0.9.3 | ||
4 | clever_user_path: .local/bin | ||
5 | clever_app_root: "{{ playbook_dir }}/.." | ||
6 | clever_app_confdir: "{{ clever_app_root }}/.clever_cloud" | ||
7 | clever_login_file: "{{ clever_app_confdir }}/login" | ||
8 | |||
9 | clever_env: {} | ||
10 | |||
11 | clever_addons: [] | ||
12 | # example | ||
13 | # clever_addons: | ||
14 | # - name: pg | ||
15 | # - env_prefix: POSTGRESQL_ADDON | ||
diff --git a/files/clever-set-domain.sh b/files/clever-set-domain.sh new file mode 100644 index 0000000..bf63be0 --- /dev/null +++ b/files/clever-set-domain.sh | |||
@@ -0,0 +1,11 @@ | |||
1 | #!/bin/bash -e | ||
2 | |||
3 | function checkDomain { | ||
4 | clever domain | grep "${DOMAIN}" | ||
5 | } | ||
6 | |||
7 | function setDomain { | ||
8 | clever domain add "${DOMAIN}" | ||
9 | } | ||
10 | |||
11 | checkDomain || setDomain | ||
diff --git a/files/clever-set-drain.sh b/files/clever-set-drain.sh new file mode 100644 index 0000000..405cb28 --- /dev/null +++ b/files/clever-set-drain.sh | |||
@@ -0,0 +1,11 @@ | |||
1 | #!/bin/bash -e | ||
2 | |||
3 | function checkDrain { | ||
4 | clever drain | grep "${SYSLOG_UDP_SERVER}" | ||
5 | } | ||
6 | |||
7 | function setDrain { | ||
8 | clever drain create UDPSyslog "udp://${SYSLOG_UDP_SERVER}" | ||
9 | } | ||
10 | |||
11 | checkDrain || setDrain | ||
diff --git a/files/clever-wait-deploy.sh b/files/clever-wait-deploy.sh new file mode 100644 index 0000000..99088cc --- /dev/null +++ b/files/clever-wait-deploy.sh | |||
@@ -0,0 +1,50 @@ | |||
1 | #!/bin/bash -e | ||
2 | |||
3 | function deploying { | ||
4 | checkStatus "$1" "IN PROGRESS" | ||
5 | } | ||
6 | |||
7 | function deployed { | ||
8 | checkStatus "$1" "OK" | ||
9 | } | ||
10 | |||
11 | function inactive { | ||
12 | local commit="$1" | ||
13 | [[ "$(clever activity | grep "$commit" | grep "DEPLOY" | wc -l)" == "0" ]] | ||
14 | } | ||
15 | |||
16 | function checkStatus { | ||
17 | local commit="$1" | ||
18 | local status="$2" | ||
19 | [[ "$(clever activity | grep "$commit" | grep "${status}\s\+DEPLOY" | wc -l)" == "1" ]] | ||
20 | } | ||
21 | |||
22 | function check { | ||
23 | local timeout=600 # 10 minutes | ||
24 | local commit="$1" | ||
25 | local samplingTime=5 | ||
26 | |||
27 | echo "Waiting for deployment start..." | ||
28 | while inactive "$commit" -a $timeout -gt 0 | ||
29 | do | ||
30 | sleep $samplingTime | ||
31 | let "timeout-=$samplingTime" | ||
32 | done | ||
33 | |||
34 | # Wait for completion | ||
35 | echo "Deployement in progress..." | ||
36 | while deploying "$commit" -a $timeout -gt 0 | ||
37 | do | ||
38 | sleep $samplingTime | ||
39 | let "timeout-=$samplingTime" | ||
40 | done | ||
41 | |||
42 | if [ $samplingTime -eq 0 ] | ||
43 | then | ||
44 | echo "Timeout" | ||
45 | fi | ||
46 | |||
47 | deployed "$commit" | ||
48 | } | ||
49 | |||
50 | check "$(git rev-parse HEAD)" | ||
diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..9b6333b --- /dev/null +++ b/handlers/main.yml | |||
@@ -0,0 +1,2 @@ | |||
1 | --- | ||
2 | # handlers file for clever \ No newline at end of file | ||
diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..eabd765 --- /dev/null +++ b/meta/main.yml | |||
@@ -0,0 +1,60 @@ | |||
1 | galaxy_info: | ||
2 | author: Fretlink | ||
3 | description: Love and trucks | ||
4 | company: Fretlink | ||
5 | |||
6 | # If the issue tracker for your role is not on github, uncomment the | ||
7 | # next line and provide a value | ||
8 | # issue_tracker_url: http://example.com/issue/tracker | ||
9 | |||
10 | # Some suggested licenses: | ||
11 | # - BSD (default) | ||
12 | # - MIT | ||
13 | # - GPLv2 | ||
14 | # - GPLv3 | ||
15 | # - Apache | ||
16 | # - CC-BY | ||
17 | license: BSD | ||
18 | |||
19 | min_ansible_version: 2.4 | ||
20 | |||
21 | # If this a Container Enabled role, provide the minimum Ansible Container version. | ||
22 | # min_ansible_container_version: | ||
23 | |||
24 | # Optionally specify the branch Galaxy will use when accessing the GitHub | ||
25 | # repo for this role. During role install, if no tags are available, | ||
26 | # Galaxy will use this branch. During import Galaxy will access files on | ||
27 | # this branch. If Travis integration is configured, only notifications for this | ||
28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch | ||
29 | # (usually master) will be used. | ||
30 | github_branch: master | ||
31 | |||
32 | # | ||
33 | # platforms is a list of platforms, and each platform has a name and a list of versions. | ||
34 | # | ||
35 | # platforms: | ||
36 | # - name: Fedora | ||
37 | # versions: | ||
38 | # - all | ||
39 | # - 25 | ||
40 | # - name: SomePlatform | ||
41 | # versions: | ||
42 | # - all | ||
43 | # - 1.0 | ||
44 | # - 7 | ||
45 | # - 99.99 | ||
46 | |||
47 | galaxy_tags: | ||
48 | - clevercloud | ||
49 | - deployment | ||
50 | - cd | ||
51 | # List tags for your role here, one per line. A tag is a keyword that describes | ||
52 | # and categorizes the role. Users find roles by searching for tags. Be sure to | ||
53 | # remove the '[]' above, if you add tags to this list. | ||
54 | # | ||
55 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. | ||
56 | # Maximum 20 tags per role. | ||
57 | |||
58 | dependencies: [] | ||
59 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, | ||
60 | # if you add dependencies to this list. | ||
diff --git a/tasks/addon.yml b/tasks/addon.yml new file mode 100644 index 0000000..f6a4d14 --- /dev/null +++ b/tasks/addon.yml | |||
@@ -0,0 +1,9 @@ | |||
1 | - name: Gather addon information for {{ addon.name }} | ||
2 | shell: "clever env | grep {{ addon.env_prefix }} | sed -e 's/{{ addon.env_prefix }}_//' -e 's/=/: \"/' -e 's/$/\"/' > {{ clever_app_confdir }}/{{ addon.name }}_env.yml" | ||
3 | environment: | ||
4 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
5 | |||
6 | - name: Include addon var for {{ addon.name }} | ||
7 | include_vars: | ||
8 | file: "{{ clever_app_confdir }}/{{ addon.name }}_env.yml" | ||
9 | name: "{{ addon.name }}" | ||
diff --git a/tasks/deploy.yml b/tasks/deploy.yml new file mode 100644 index 0000000..8b98d8c --- /dev/null +++ b/tasks/deploy.yml | |||
@@ -0,0 +1,30 @@ | |||
1 | - name: Configure Drain | ||
2 | when: syslog_server is defined | ||
3 | command: clever-set-drain.sh | ||
4 | environment: | ||
5 | SYSLOG_UDP_SERVER: "{{ syslog_server }}" | ||
6 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
7 | |||
8 | - name: Configure Domain | ||
9 | when: domain is defined | ||
10 | command: clever-set-domain.sh | ||
11 | environment: | ||
12 | DOMAIN: "{{ domain }}" | ||
13 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
14 | |||
15 | - name: Push Environment | ||
16 | shell: "clever env import < {{ clever_app_confdir }}/env" | ||
17 | environment: | ||
18 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
19 | |||
20 | #TODO: Improve ssh-key validation | ||
21 | - name: Accept Clever-Cloud servers | ||
22 | shell: "ssh-keyscan -H push-par-clevercloud-customers.services.clever-cloud.com >> ~/.ssh/known_hosts" | ||
23 | |||
24 | - name: Push to Clever-Cloud to trigger deployment | ||
25 | command: "git push --force git+ssh://git@push-par-clevercloud-customers.services.clever-cloud.com/{{ clever_app }}.git HEAD:refs/heads/master" | ||
26 | |||
27 | - name: Wait until deployment completion | ||
28 | command: clever-wait-deploy.sh | ||
29 | environment: | ||
30 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
diff --git a/tasks/environment.yml b/tasks/environment.yml new file mode 100644 index 0000000..1508ad4 --- /dev/null +++ b/tasks/environment.yml | |||
@@ -0,0 +1,11 @@ | |||
1 | - name: Create environment file | ||
2 | template: | ||
3 | src: env.j2 | ||
4 | dest: "{{ clever_app_confdir }}/env" | ||
5 | no_log: true | ||
6 | |||
7 | - name: Create addons variable file | ||
8 | include_tasks: addon.yml | ||
9 | vars: | ||
10 | addon: "{{ item }}" | ||
11 | with_items: "{{ clever_addons }}" | ||
diff --git a/tasks/login.yml b/tasks/login.yml new file mode 100644 index 0000000..0eb310f --- /dev/null +++ b/tasks/login.yml | |||
@@ -0,0 +1,15 @@ | |||
1 | - name: Create .clever-cloud directory | ||
2 | file: | ||
3 | path: "{{ clever_app_confdir }}" | ||
4 | state: directory | ||
5 | |||
6 | - name: Fill the login file | ||
7 | template: | ||
8 | src: cleverlogin.j2 | ||
9 | dest: "{{ clever_login_file }}" | ||
10 | no_log: true | ||
11 | |||
12 | - name: Link app | ||
13 | shell: clever link {{ clever_app }} | ||
14 | environment: | ||
15 | CONFIGURATION_FILE: "{{ clever_login_file }}" | ||
diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..fa23f6c --- /dev/null +++ b/tasks/main.yml | |||
@@ -0,0 +1,32 @@ | |||
1 | --- | ||
2 | # tasks file for clever | ||
3 | - name: Setup environment for clever | ||
4 | include_tasks: setup.yml | ||
5 | tags: | ||
6 | - clever | ||
7 | - clever-setup | ||
8 | |||
9 | - name: Login to clever | ||
10 | include_tasks: login.yml | ||
11 | tags: | ||
12 | - clever | ||
13 | - clever-login | ||
14 | |||
15 | - name: Manage environment | ||
16 | include_tasks: environment.yml | ||
17 | tags: | ||
18 | - clever | ||
19 | - clever-env | ||
20 | |||
21 | - name: Include specific tasks | ||
22 | include_tasks: "{{ clever_app_tasks }}" | ||
23 | when: clever_app_tasks is defined | ||
24 | tags: | ||
25 | - clever | ||
26 | - clever-specific-role | ||
27 | |||
28 | - name: Deploy app | ||
29 | include_tasks: deploy.yml | ||
30 | tags: | ||
31 | - clever | ||
32 | - clever-deploy | ||
diff --git a/tasks/setup.yml b/tasks/setup.yml new file mode 100644 index 0000000..ac9fdcb --- /dev/null +++ b/tasks/setup.yml | |||
@@ -0,0 +1,28 @@ | |||
1 | - name: Check if clever command is available in path and version | ||
2 | command: clever --version | ||
3 | register: clever_returned_version | ||
4 | ignore_errors: true | ||
5 | |||
6 | - name: Ensure user path exists | ||
7 | file: | ||
8 | path: "{{ ansible_env.HOME }}/{{ clever_user_path }}" | ||
9 | state: directory | ||
10 | |||
11 | - name: Download and install clever cli tools if necessary | ||
12 | unarchive: | ||
13 | remote_src: yes | ||
14 | extra_opts: | ||
15 | - "--strip-components=1" | ||
16 | src: https://clever-tools.cellar.services.clever-cloud.com/releases/{{ clever_cli_version }}/clever-tools-{{ clever_cli_version }}_linux.tar.gz | ||
17 | dest: "{{ ansible_env.HOME }}/{{ clever_user_path }}" | ||
18 | when: clever_returned_version|failed or clever_returned_version.stdout != clever_cli_version | ||
19 | |||
20 | - name: Install helper scripts | ||
21 | copy: | ||
22 | src: "{{ item }}" | ||
23 | dest: "{{ ansible_env.HOME }}/{{ clever_user_path }}/{{ item }}" | ||
24 | mode: 0755 | ||
25 | with_items: | ||
26 | - clever-set-domain.sh | ||
27 | - clever-set-drain.sh | ||
28 | - clever-wait-deploy.sh | ||
diff --git a/templates/cleverlogin.j2 b/templates/cleverlogin.j2 new file mode 100644 index 0000000..46b0612 --- /dev/null +++ b/templates/cleverlogin.j2 | |||
@@ -0,0 +1,4 @@ | |||
1 | { | ||
2 | "token": "{{ clever_token }}", | ||
3 | "secret": "{{ clever_secret }}" | ||
4 | } | ||
diff --git a/templates/env.j2 b/templates/env.j2 new file mode 100644 index 0000000..6010f07 --- /dev/null +++ b/templates/env.j2 | |||
@@ -0,0 +1,3 @@ | |||
1 | {% for key, value in clever_env.iteritems() %} | ||
2 | {{ key }}={{ value }} | ||
3 | {% endfor %} | ||
diff --git a/tests/inventory b/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/tests/inventory | |||
@@ -0,0 +1,2 @@ | |||
1 | localhost | ||
2 | |||
diff --git a/tests/test.yml b/tests/test.yml new file mode 100644 index 0000000..3e3c57f --- /dev/null +++ b/tests/test.yml | |||
@@ -0,0 +1,5 @@ | |||
1 | --- | ||
2 | - hosts: localhost | ||
3 | remote_user: root | ||
4 | roles: | ||
5 | - clever \ No newline at end of file | ||
diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..19478fd --- /dev/null +++ b/vars/main.yml | |||
@@ -0,0 +1,2 @@ | |||
1 | --- | ||
2 | # vars file for clever \ No newline at end of file | ||