diff --git a/ansible/devops.yaml b/ansible/devops.yaml
new file mode 100644
index 0000000..03fde7c
--- /dev/null
+++ b/ansible/devops.yaml
@@ -0,0 +1,12 @@
+---
+- name: Create server
+ hosts: localhost
+ roles:
+ - server-setup
+- name: Set up drone
+ hosts: servers
+ become: true
+ become_method: ansible.builtin.sudo
+ remote_user: "{{ ssh_user }}"
+ roles:
+ - drone
diff --git a/ansible/inventories/group_vars/servers/servers_vars.yaml.example b/ansible/inventories/group_vars/servers/servers_vars.yaml.example
new file mode 100644
index 0000000..5668722
--- /dev/null
+++ b/ansible/inventories/group_vars/servers/servers_vars.yaml.example
@@ -0,0 +1,5 @@
+---
+hcloud_api_token: someAPIToken
+ssh_user: remoteUser
+admin_mail: mail@example.com
+ci_domain: yourDomainForCi
\ No newline at end of file
diff --git a/ansible/inventories/hetzner.example b/ansible/inventories/hetzner.example
index 4af05bb..174fbc1 100644
--- a/ansible/inventories/hetzner.example
+++ b/ansible/inventories/hetzner.example
@@ -1 +1,4 @@
-localhost ansible_python_interpreter=/usr/bin/python3
+localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3
+
+[servers]
+alias ansible_host=IPorDomain ansible_python_interpreter=python3
\ No newline at end of file
diff --git a/ansible/roles/apache/handlers/main.yml b/ansible/roles/apache/handlers/main.yml
new file mode 100644
index 0000000..1092b0e
--- /dev/null
+++ b/ansible/roles/apache/handlers/main.yml
@@ -0,0 +1,9 @@
+---
+- name: Restart apache
+ ansible.builtin.service:
+ name: apache2
+ state: restarted
+- name: Reload apache
+ ansible.builtin.service:
+ name: apache2
+ state: reloaded
diff --git a/ansible/roles/apache/meta/main.yaml b/ansible/roles/apache/meta/main.yaml
new file mode 100644
index 0000000..950e3ed
--- /dev/null
+++ b/ansible/roles/apache/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - role: letsencrypt
diff --git a/ansible/roles/apache/tasks/main.yml b/ansible/roles/apache/tasks/main.yml
new file mode 100644
index 0000000..d86c643
--- /dev/null
+++ b/ansible/roles/apache/tasks/main.yml
@@ -0,0 +1,42 @@
+---
+- name: Install apache 2
+ ansible.builtin.apt:
+ name: apache2
+ update_cache: true
+ tags:
+ - apache
+- name: Allow apache through firewall
+ community.general.ufw:
+ name: Apache Full
+ rule: allow
+- name: Enable mods
+ block:
+ - name: Enable headers
+ community.general.apache2_module:
+ name: headers
+ state: present
+ - name: Enable proxy
+ community.general.apache2_module:
+ name: proxy
+ state: present
+ - name: Enable proxy_wstunnel
+ community.general.apache2_module:
+ name: proxy_wstunnel
+ state: present
+ - name: Enable proxy_http
+ community.general.apache2_module:
+ name: proxy_http
+ state: present
+ - name: Enable proxy_balancer
+ community.general.apache2_module:
+ name: proxy_balancer
+ state: present
+ - name: Enable lbmethod_byrequests
+ community.general.apache2_module:
+ name: lbmethod_byrequests
+ state: present
+ - name: Enable ssl
+ community.general.apache2_module:
+ name: ssl
+ state: present
+ notify: Restart apache
diff --git a/ansible/roles/common/tasks/main.yaml b/ansible/roles/common/tasks/main.yaml
new file mode 100644
index 0000000..5cd13ff
--- /dev/null
+++ b/ansible/roles/common/tasks/main.yaml
@@ -0,0 +1,9 @@
+---
+- name: Ensure all tool packages are installed
+ ansible.builtin.apt:
+ pkg: "{{ packages }}"
+ update_cache: true
+ cache_valid_time: 600
+ vars:
+ packages:
+ - python3-pip
diff --git a/ansible/roles/docker/handlers/main.yml b/ansible/roles/docker/handlers/main.yml
new file mode 100644
index 0000000..07aa0eb
--- /dev/null
+++ b/ansible/roles/docker/handlers/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Restart docker
+ ansible.builtin.service:
+ name: docker
+ state: restarted
diff --git a/ansible/roles/docker/meta/main.yaml b/ansible/roles/docker/meta/main.yaml
new file mode 100644
index 0000000..fdda41b
--- /dev/null
+++ b/ansible/roles/docker/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - role: common
diff --git a/ansible/roles/docker/tasks/main.yml b/ansible/roles/docker/tasks/main.yml
new file mode 100644
index 0000000..147f08a
--- /dev/null
+++ b/ansible/roles/docker/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+- name: Install docker-compose
+ ansible.builtin.apt:
+ name: docker-compose
+ update_cache: true
+ tags:
+ - docker
+- name: Enable docker service
+ ansible.builtin.service:
+ name: docker
+ enabled: true
+- name: Install ansible python dependencies on remote
+ ansible.builtin.pip:
+ name:
+ - docker
+ - docker-compose
+- name: Enable docker log rotation
+ ansible.builtin.template:
+ src: etc/docker/daemon.json.j2
+ dest: /etc/docker/daemon.json
+ owner: root
+ group: root
+ mode: "644"
+ notify: Restart docker
diff --git a/ansible/roles/docker/templates/etc/docker/daemon.json.j2 b/ansible/roles/docker/templates/etc/docker/daemon.json.j2
new file mode 100644
index 0000000..b8ab8c9
--- /dev/null
+++ b/ansible/roles/docker/templates/etc/docker/daemon.json.j2
@@ -0,0 +1,7 @@
+{
+ "log-driver": "json-file",
+ "log-opts": {
+ "max-size": "10m",
+ "max-file": "3"
+ }
+}
diff --git a/ansible/roles/drone/defaults/main.yaml b/ansible/roles/drone/defaults/main.yaml
new file mode 100644
index 0000000..50e0c30
--- /dev/null
+++ b/ansible/roles/drone/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+drone_max_procs: 1
diff --git a/ansible/roles/drone/meta/main.yml b/ansible/roles/drone/meta/main.yml
new file mode 100644
index 0000000..3821742
--- /dev/null
+++ b/ansible/roles/drone/meta/main.yml
@@ -0,0 +1,5 @@
+---
+dependencies:
+ - role: docker
+ - role: apache
+ - role: letsencrypt
diff --git a/ansible/roles/drone/tasks/apache.yml b/ansible/roles/drone/tasks/apache.yml
new file mode 100644
index 0000000..dc9daca
--- /dev/null
+++ b/ansible/roles/drone/tasks/apache.yml
@@ -0,0 +1,56 @@
+---
+- name: Add drone HTTP site
+ ansible.builtin.template:
+ src: etc/apache2/sites-available/ansible_domain.conf.j2
+ dest: /etc/apache2/sites-available/{{ ci_domain }}.conf
+ owner: root
+ group: root
+ mode: "644"
+ force: false
+ register: drone_http
+- name: Disable default site and enable drone site
+ block:
+ - name: Disable default site
+ ansible.builtin.command:
+ cmd: a2dissite 000-default.conf
+ removes: /etc/apache2/sites-enabled/000-default.conf
+ - name: Enable drone site
+ ansible.builtin.command:
+ cmd: a2ensite {{ ci_domain }}.conf
+ creates: /etc/apache2/sites-enabled/{{ ci_domain }}.conf
+- name: Check certificate existence
+ ansible.builtin.stat:
+ path: "/etc/letsencrypt/live/{{ ci_domain }}/cert.pem"
+ register: certificate
+- name: Generate certificates
+ ansible.builtin.command:
+ cmd: >
+ certbot --apache --non-interactive --keep-until-expiring
+ --no-eff-email
+ --email {{ admin_mail }}
+ --redirect
+ --renew-with-new-domains --agree-tos -d {{ ci_domain }}
+ creates: "/etc/letsencrypt/live/{{ ci_domain }}/cert.pem"
+ register: certbot_certificate_created
+ failed_when:
+ - "'Successfully received certificate.' not in certbot_certificate_created.stdout"
+ when:
+ - not certificate.stat.exists
+- name: Add drone HTTPS site
+ ansible.builtin.template:
+ src: etc/apache2/sites-available/ansible_domain-le-ssl.conf.j2
+ dest: /etc/apache2/sites-available/{{ ci_domain }}-le-ssl.conf
+ owner: root
+ group: root
+ mode: "644"
+- name: Check certificate existence after certbot run
+ ansible.builtin.stat:
+ path: "/etc/letsencrypt/live/{{ ci_domain }}/cert.pem"
+ register: certificate_after_certbot
+- name: Enable drone HTTPS site
+ ansible.builtin.command:
+ cmd: a2ensite {{ ci_domain }}-le-ssl.conf
+ creates: /etc/apache2/sites-enabled/{{ ci_domain }}-le-ssl.conf
+ notify: Restart apache
+ when:
+ - certificate_after_certbot.stat.exists
diff --git a/ansible/roles/drone/tasks/drone.yml b/ansible/roles/drone/tasks/drone.yml
new file mode 100644
index 0000000..7160a8c
--- /dev/null
+++ b/ansible/roles/drone/tasks/drone.yml
@@ -0,0 +1,42 @@
+---
+- name: Create drone directory
+ ansible.builtin.file:
+ state: directory
+ path: /etc/drone
+ owner: root
+ group: root
+ mode: "644"
+- name: Create shared secret
+ ansible.builtin.command:
+ cmd: openssl rand -hex 16
+ register: drone_rpc_secret
+ changed_when: true
+- name: Copy docker compose file for drone
+ ansible.builtin.template:
+ src: etc/drone/docker-compose.yml.j2
+ dest: /etc/drone/docker-compose.yml
+ owner: root
+ group: root
+ mode: "644"
+- name: Start drone docker container
+ community.docker.docker_compose:
+ project_src: /etc/drone
+- name: Install drone cli
+ block:
+ - name: Download drone cli
+ ansible.builtin.get_url:
+ url: https://github.com/drone/drone-cli/releases/latest/download/drone_linux_amd64.tar.gz
+ dest: /home/{{ ssh_user }}/drone_linux_amd64.tar.gz
+ owner: "{{ ssh_user }}"
+ group: "{{ ssh_user }}"
+ mode: "644"
+ - name: Unpack the cli archive
+ ansible.builtin.unarchive:
+ dest: /home/{{ ssh_user }}
+ src: /home/{{ ssh_user }}/drone_linux_amd64.tar.gz
+ remote_src: true
+ register: drone_unpack
+ - name: Install drone cli
+ ansible.builtin.command:
+ cmd: install -t /usr/local/bin /home/{{ ssh_user }}/drone
+ changed_when: true
diff --git a/ansible/roles/drone/tasks/main.yml b/ansible/roles/drone/tasks/main.yml
new file mode 100644
index 0000000..29a7177
--- /dev/null
+++ b/ansible/roles/drone/tasks/main.yml
@@ -0,0 +1,5 @@
+---
+- name: Set up apache for drone
+ ansible.builtin.import_tasks: apache.yml
+- name: Set up drone
+ ansible.builtin.import_tasks: drone.yml
diff --git a/ansible/roles/drone/templates/etc/apache2/sites-available/ansible_domain-le-ssl.conf.j2 b/ansible/roles/drone/templates/etc/apache2/sites-available/ansible_domain-le-ssl.conf.j2
new file mode 100644
index 0000000..2f355e2
--- /dev/null
+++ b/ansible/roles/drone/templates/etc/apache2/sites-available/ansible_domain-le-ssl.conf.j2
@@ -0,0 +1,23 @@
+
+
+ ServerName {{ ci_domain }}
+ ServerAdmin {{ admin_mail }}
+ ErrorLog ${APACHE_LOG_DIR}/error.log
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+ SSLCertificateFile /etc/letsencrypt/live/{{ ci_domain }}/fullchain.pem
+ SSLCertificateKeyFile /etc/letsencrypt/live/{{ ci_domain }}/privkey.pem
+ Include /etc/letsencrypt/options-ssl-apache.conf
+
+ # Encoded slashes need to be allowed
+ AllowEncodedSlashes NoDecode
+
+ # keep the host
+ ProxyPreserveHost On
+ RequestHeader set X-Forwarded-Proto "https"
+ RequestHeader set X-Forwarded-Host "{{ ci_domain }}"
+ ProxyPass / http://127.0.0.1:8000/
+ ProxyPassReverse / http://127.0.0.1:8000/
+
+
+
diff --git a/ansible/roles/drone/templates/etc/apache2/sites-available/ansible_domain.conf.j2 b/ansible/roles/drone/templates/etc/apache2/sites-available/ansible_domain.conf.j2
new file mode 100644
index 0000000..dfd6bb4
--- /dev/null
+++ b/ansible/roles/drone/templates/etc/apache2/sites-available/ansible_domain.conf.j2
@@ -0,0 +1,6 @@
+
+ ServerName {{ ci_domain }}
+ ServerAdmin {{ admin_mail }}
+ ErrorLog ${APACHE_LOG_DIR}/error.log
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+
diff --git a/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2 b/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2
new file mode 100644
index 0000000..2742d5e
--- /dev/null
+++ b/ansible/roles/drone/templates/etc/drone/docker-compose.yml.j2
@@ -0,0 +1,41 @@
+version: '2'
+
+services:
+ drone-server:
+ image: drone/drone:latest
+
+ ports:
+ - "8000:80"
+ - "8001:443"
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /var/lib/drone:/data
+ restart: always
+ environment:
+ - DRONE_SERVER_HOST={{ ci_domain }}
+ - DRONE_SERVER_PROTO=https
+ - DRONE_AGENTS_ENABLED=true
+ - DRONE_RPC_SECRET={{ drone_rpc_secret.stdout }}
+ - DRONE_USER_CREATE=username:{{ gitea_user }},admin:true
+ - DRONE_GITEA_SERVER={{ gitea_url }}
+ - DRONE_GITEA_CLIENT_ID={{ gitea_client_id }}
+ - DRONE_GITEA_CLIENT_SECRET={{ gitea_client_secret }}
+ - DOCKER_MAX_PROCS={{ drone_max_procs }}
+ - LC_ALL=C.UTF-8
+ - LANG=C.UTF-8
+ drone-runner:
+ image: drone/drone-runner-docker:latest
+
+ ports:
+ - "3000:3000"
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ restart: always
+ depends_on:
+ - drone-server
+ environment:
+ - DRONE_RPC_PROTO=http
+ - DRONE_RPC_HOST=drone-server
+ - DRONE_RPC_SECRET={{ drone_rpc_secret.stdout }}
+ - DRONE_RUNNER_CAPACITY=2
+ - DRONE_RUNNER_NAME={{ ansible_hostname }}
diff --git a/ansible/roles/letsencrypt/tasks/main.yml b/ansible/roles/letsencrypt/tasks/main.yml
new file mode 100644
index 0000000..4bf8f28
--- /dev/null
+++ b/ansible/roles/letsencrypt/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+- name: Install certbot
+ ansible.builtin.apt:
+ name: certbot
+ update_cache: true
+- name: Install python3-certbot-apache
+ ansible.builtin.apt:
+ name: python3-certbot-apache
+ update_cache: true
diff --git a/ansible/roles/server-setup/defaults/main.yaml b/ansible/roles/server-setup/defaults/main.yaml
index 7023c5a..ff9f62d 100644
--- a/ansible/roles/server-setup/defaults/main.yaml
+++ b/ansible/roles/server-setup/defaults/main.yaml
@@ -3,4 +3,4 @@ basic_firewall: basic-firewall
server_image: ubuntu-22.04
server_location: fsn1
server_placement_group: default
-server_type: cax11
\ No newline at end of file
+server_type: cax11
diff --git a/ansible/roles/server-setup/tasks/create-server.yaml b/ansible/roles/server-setup/tasks/create-server.yaml
index f22ad0b..f1e50e3 100644
--- a/ansible/roles/server-setup/tasks/create-server.yaml
+++ b/ansible/roles/server-setup/tasks/create-server.yaml
@@ -1,11 +1,11 @@
---
-- name: create SSH key
+- name: Create SSH key
hetzner.hcloud.hcloud_ssh_key:
api_token: "{{ hcloud_api_token }}"
public_key: "{{ ssh_key_admin_user }}"
name: "{{ ssh_key_admin_user_name }}"
state: present
-- name: create server via HCloud
+- name: Create server via HCloud
hetzner.hcloud.hcloud_server:
api_token: "{{ hcloud_api_token }}"
firewalls:
@@ -19,4 +19,4 @@
- "{{ ssh_key_admin_user_name }}"
user_data: "{{ lookup('ansible.builtin.template', 'basic-ssh-hardening.yaml.j2', convert_data=false) }}"
state: present
- register: server
\ No newline at end of file
+ register: server
diff --git a/ansible/roles/server-setup/tasks/main.yaml b/ansible/roles/server-setup/tasks/main.yaml
index 476b218..07e9c10 100644
--- a/ansible/roles/server-setup/tasks/main.yaml
+++ b/ansible/roles/server-setup/tasks/main.yaml
@@ -1,2 +1,3 @@
---
-- import_tasks: create-server.yaml
\ No newline at end of file
+- name: Create server
+ ansible.builtin.import_tasks: create-server.yaml
diff --git a/ansible/setup.yaml b/ansible/setup.yaml
deleted file mode 100644
index 5ab8d79..0000000
--- a/ansible/setup.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-- name: Create server
- hosts: localhost
- connection: local
- roles:
- - server-setup
diff --git a/ansible/site.yaml b/ansible/site.yaml
index e78e4eb..5c62693 100644
--- a/ansible/site.yaml
+++ b/ansible/site.yaml
@@ -1,2 +1,2 @@
---
-- include: setup.yaml
\ No newline at end of file
+- include: devops.yaml
\ No newline at end of file