summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Lusk <luskjh@gmail.com>2026-05-26 10:41:49 -0400
committerJoshua Lusk <luskjh@gmail.com>2026-05-26 10:41:49 -0400
commit519495426d0df262364e443ea1fcd69dcc419446 (patch)
tree27d9f300dd303963f2ac937c17256d8aada44d8d
parent2f117e8eb79fc361228e206024e802bee60b3d78 (diff)
add git playbook
-rw-r--r--Makefile4
-rw-r--r--README.md12
-rw-r--r--inventory.yaml4
-rw-r--r--playbooks/bootstrap.yaml5
-rw-r--r--playbooks/git.yaml97
-rw-r--r--playbooks/templates/cgitrc.j214
-rw-r--r--playbooks/templates/nginx/git.conf.j244
-rw-r--r--vault.yaml38
8 files changed, 200 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index 2e1c864..9c78459 100644
--- a/Makefile
+++ b/Makefile
@@ -45,3 +45,7 @@ https:
.PHONY: devops
devops:
$(BIN)/ansible-playbook -e @vault.yaml playbooks/devops.yaml
+
+.PHONY: git
+git:
+ $(BIN)/ansible-playbook -e @vault.yaml playbooks/git.yaml
diff --git a/README.md b/README.md
index 8ab85e5..0f7c7b4 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ _Listed in applicable order._
| `http` | Web server |
| `https` | SSL certificates |
| `devops`<sup>†</sup> | DevOps setup |
+| `git` | Git hosting |
### <sup>*</sup>Pre-bootstraped targets
@@ -51,6 +52,17 @@ $ make ping ANSIBLE_USER=root ANSIBLE_PORT=22
$ make bootstrap ANSIBLE_USER=root ANSIBLE_PORT=22
```
+#### Git Repository
+
+The `git` playbook publishes repositories via cgit at
+`https://git.sorantics.com` and creates
+`/home/git/sorantics/infra.git` as the first bare repository.
+
+```sh
+$ git remote add origin git@git.sorantics.com:sorantics/infra.git
+$ git push -u origin main
+```
+
#### <sup>†</sup>Hollyhock's mTLS Protection
The subdomain `hollyhock` is secured with mTLS - once the `devops`
diff --git a/inventory.yaml b/inventory.yaml
index b3aef2a..d1750fd 100644
--- a/inventory.yaml
+++ b/inventory.yaml
@@ -24,6 +24,10 @@ all:
nginx_group: www-data
nginx_log_group: adm
+ git_user: git
+ git_group: git
+ git_repo_root: "/home/{{ git_user }}"
+
sites:
- name: landing
domains: ["{{ domain }}", "www.{{ domain }}"]
diff --git a/playbooks/bootstrap.yaml b/playbooks/bootstrap.yaml
index 3f5f872..230dfde 100644
--- a/playbooks/bootstrap.yaml
+++ b/playbooks/bootstrap.yaml
@@ -27,6 +27,7 @@
- "{{ admin_group }}"
- "{{ automation_group }}"
- "{{ deploy_group }}"
+ - "{{ git_group }}"
- name: Create users
ansible.builtin.user:
@@ -46,6 +47,9 @@
- user: "{{ deploy_user }}"
password: "{{ deploy_password }}"
groups: "{{ deploy_group }}"
+ - user: "{{ git_user }}"
+ password: "{{ git_password }}"
+ groups: "{{ git_group }}"
no_log: true
- name: Add ssh keys
@@ -57,6 +61,7 @@
- "{{ admin_user }}"
- "{{ automation_user }}"
- "{{ deploy_user }}"
+ - "{{ git_user }}"
- name: Apply ssh changes
ansible.builtin.meta: flush_handlers
diff --git a/playbooks/git.yaml b/playbooks/git.yaml
new file mode 100644
index 0000000..d166c4a
--- /dev/null
+++ b/playbooks/git.yaml
@@ -0,0 +1,97 @@
+- name: Git browser
+ hosts: hollyhock
+ become: true
+ vars:
+ git_namespace: "{{ git_repo_root }}/sorantics"
+ tasks:
+ - name: Install dependencies
+ ansible.builtin.apt:
+ name:
+ - cgit
+ - fcgiwrap
+ - git
+ state: present
+ update_cache: true
+
+ - name: Enable fcgiwrap socket
+ ansible.builtin.systemd:
+ name: fcgiwrap.socket
+ state: started
+ enabled: true
+
+ - name: Create git repository directory
+ ansible.builtin.file:
+ path: "{{ git_repo_root }}"
+ state: directory
+ owner: "{{ git_user }}"
+ group: "{{ git_group }}"
+ mode: "0755"
+
+ - name: Create Sorantics git namespace
+ ansible.builtin.file:
+ path: "{{ git_namespace }}"
+ state: directory
+ owner: "{{ git_user }}"
+ group: "{{ git_group }}"
+ mode: "0755"
+
+ - name: Create infra repository # noqa: command-instead-of-module
+ ansible.builtin.command:
+ cmd: git init --bare infra.git
+ chdir: "{{ git_namespace }}"
+ creates: "{{ git_namespace }}/infra.git/HEAD"
+ become: true
+ become_user: "{{ git_user }}"
+
+ - name: Setup bare infra repository
+ ansible.builtin.file:
+ path: "{{ git_namespace }}/infra.git"
+ state: directory
+ owner: "{{ git_user }}"
+ group: "{{ git_group }}"
+ recurse: true
+
+ - name: Describe infra repository
+ ansible.builtin.copy:
+ content: "Remote infrastructure.\n"
+ dest: "{{ git_namespace }}/infra.git/description"
+ owner: "{{ git_user }}"
+ group: "{{ git_group }}"
+ mode: "0644"
+
+ - name: Configure cgit
+ ansible.builtin.template:
+ src: cgitrc.j2
+ dest: /etc/cgitrc
+ mode: "0644"
+
+ - name: Copy nginx config
+ ansible.builtin.template:
+ src: nginx/git.conf.j2
+ dest: /etc/nginx/sites-available/git
+ mode: "0644"
+ notify: Test and restart nginx
+
+ - name: Disable http and https nginx sites
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - /etc/nginx/sites-enabled/git-http
+ - /etc/nginx/sites-enabled/git-https
+ notify:
+ - Test and restart nginx
+
+ - name: Enable nginx config
+ ansible.builtin.file:
+ src: /etc/nginx/sites-available/git
+ dest: /etc/nginx/sites-enabled/git
+ state: link
+ owner: "{{ nginx_user }}"
+ group: "{{ nginx_group }}"
+ notify:
+ - Test and restart nginx
+
+ handlers:
+ - name: Test and restart nginx
+ ansible.builtin.include_tasks: tasks/test_and_restart_nginx.yaml
diff --git a/playbooks/templates/cgitrc.j2 b/playbooks/templates/cgitrc.j2
new file mode 100644
index 0000000..233e2c0
--- /dev/null
+++ b/playbooks/templates/cgitrc.j2
@@ -0,0 +1,14 @@
+css=/cgit.css
+logo=/cgit.png
+favicon=/favicon.ico
+
+root-title=git.{{ domain }}
+root-desc=Sorantics repositories
+
+clone-prefix=https://git.{{ domain }} git@git.{{ domain }}:
+enable-index-owner=0
+enable-log-filecount=1
+enable-log-linecount=1
+enable-tree-linenumbers=1
+remove-suffix=1
+scan-path={{ git_repo_root }}
diff --git a/playbooks/templates/nginx/git.conf.j2 b/playbooks/templates/nginx/git.conf.j2
new file mode 100644
index 0000000..d6a0f1c
--- /dev/null
+++ b/playbooks/templates/nginx/git.conf.j2
@@ -0,0 +1,44 @@
+server {
+ listen 80;
+ listen [::]:80;
+ server_name git.{{ domain }};
+
+ return 301 https://$host$request_uri;
+}
+
+server {
+ server_name git.{{ domain }};
+
+ listen 443 ssl;
+ listen [::]:443 ssl;
+
+ root /usr/share/cgit;
+
+ location /cgit.css {
+ alias /usr/share/cgit/cgit.css;
+ }
+
+ location /cgit.png {
+ alias /usr/share/cgit/cgit.png;
+ }
+
+ location /favicon.ico {
+ alias /usr/share/cgit/favicon.ico;
+ }
+
+ location / {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
+ fastcgi_param PATH_INFO $uri;
+ fastcgi_param QUERY_STRING $args;
+ fastcgi_pass unix:/run/fcgiwrap.socket;
+ }
+
+ ssl_certificate /etc/letsencrypt/live/git.{{ domain }}/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/git.{{ domain }}/privkey.pem;
+ include /etc/letsencrypt/options-ssl-nginx.conf;
+ ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
+
+ access_log /var/log/nginx/git/access.log;
+ error_log /var/log/nginx/git/error.log;
+}
diff --git a/vault.yaml b/vault.yaml
index b4ac7f8..ae53b26 100644
--- a/vault.yaml
+++ b/vault.yaml
@@ -1,19 +1,21 @@
$ANSIBLE_VAULT;1.1;AES256
-65306666313531353535326534363963303433383662353838666133356537616233343135366461
-3833356361373265333634333263313639383433316435350a623831623237633630663533363431
-37396234386462383939613061623563353135376233396337313737636164623530623033366261
-3535626461653137630a626334646463346363643633623566323038353266373331353765323539
-31373531663962336433383861393465396534376130333063393339336339653239383839393264
-61343730316665626338626430336432373033646636373062626134393361653932303030313235
-36666461363032333866343265646365316332313638306661636336646666306665306365643965
-38373330343233316565653233616566313931343734646562363035336366666566363133623561
-38343730373061363339653130373130646338653839643061383236336437636538613334363238
-31316336376330363033653863373734663863333333353563396161393666336165646230323139
-38333637303438303237643734383139623666363435363632366632666137333236323031306239
-64633039633061623165373833376132386633643562613931653833633138616536663238303230
-62343637303266666232353536373230363334633561633362613339326633323263613032636437
-35633438313261383539373065306536396233613830376339666661663534373636306630396437
-35373264623036313430366232643031373134326434623433663239366365343032396164626535
-61613435353665653261613663353065376234636364333863653261316231396330363835646638
-39363662616532343738666466336430656161376139313561326463383939333361646236333138
-3832663930616633313439386664336361646166643938323937
+66303635613461636431636332303163316137373464653766613931646235663765383236343734
+3132616536653337636464623962623033373030363865630a306262646634333262333437396532
+35646237656233653231313465376337353236383936316163356430343033383661643665343435
+3262326532316163320a343638343866373331653539366332373131313439363564666434353730
+63376335333737623163663364366661613362333663356632316164636131343164386162343163
+36306430613836306633393538663461663166346633653237633930666536343331316465623432
+33376262313838646633376631613239653633343231336236323134373938383266373363633635
+63336162363637323338303664646230316535633634346334353533363833616137363430656234
+33663730343830653332306462623734323737633733363365353439636435333035623966616636
+30366437633437376535386136353331616234383162393564653238646332323332386238653835
+62643938653636646232356531363134353030356630613837373234373435326333346330303739
+34376564303864663463313531393031363939313464366331353164653032643135626535656638
+62663937646637396266653730343730376263393133336662323064353761303430653461316635
+37656132376131656431333862623034363939343036353037643265643131306335326335366532
+64646431396464613434303736643136303965613463626433656238353561353438396339393464
+38336231663030373366343464396538313135386138663835346235373933313765343231326262
+37343365653430613731356231643736613664323132343639393561383239633132643963346465
+39656133366461656436646563373838663238333133626561316632363235636136346135306364
+37343138613332346238386162656135366531646335346536326536306137666531653061386637
+39663938666265653236