From 519495426d0df262364e443ea1fcd69dcc419446 Mon Sep 17 00:00:00 2001 From: Joshua Lusk Date: Tue, 26 May 2026 10:41:49 -0400 Subject: add git playbook --- Makefile | 4 ++ README.md | 12 +++++ inventory.yaml | 4 ++ playbooks/bootstrap.yaml | 5 ++ playbooks/git.yaml | 97 +++++++++++++++++++++++++++++++++++ playbooks/templates/cgitrc.j2 | 14 +++++ playbooks/templates/nginx/git.conf.j2 | 44 ++++++++++++++++ vault.yaml | 38 +++++++------- 8 files changed, 200 insertions(+), 18 deletions(-) create mode 100644 playbooks/git.yaml create mode 100644 playbooks/templates/cgitrc.j2 create mode 100644 playbooks/templates/nginx/git.conf.j2 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` | DevOps setup | +| `git` | Git hosting | ### *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 +``` + #### 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 -- cgit v1.2.3