| Tidy up TF scripts and first run of Ansible configuration. - infra - Terraform … | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 88aea3aa647f7a1b1e7c69ae731b6e846ba9cf3e | |
| parent 1689e2eba4bdb38eac00a4dc51d5f98335431252 | |
| Author: Jay Scott <[email protected]> | |
| Date: Sat, 28 Jan 2023 20:50:36 +0000 | |
| Tidy up TF scripts and first run of Ansible configuration. | |
| Diffstat: | |
| M README | 44 ++++++++++++++++++++++++++++-… | |
| A ansible/group_vars/all.yml | 3 +++ | |
| A ansible/group_vars/git.yml | 4 ++++ | |
| A ansible/group_vars/gopher.yml | 12 ++++++++++++ | |
| A ansible/inventory.yml | 13 +++++++++++++ | |
| A ansible/main.yml | 28 ++++++++++++++++++++++++++++ | |
| A ansible/roles/common/files/sshd_co… | 6 ++++++ | |
| A ansible/roles/common/handlers/main… | 4 ++++ | |
| A ansible/roles/common/tasks/main.yml | 42 +++++++++++++++++++++++++++++… | |
| A ansible/roles/common/tasks/setup-D… | 5 +++++ | |
| A ansible/roles/common/vars/Debian.y… | 5 +++++ | |
| A ansible/roles/finger/files/list | 4 ++++ | |
| A ansible/roles/finger/files/log | 1 + | |
| A ansible/roles/finger/files/logo.txt | 7 +++++++ | |
| A ansible/roles/finger/files/luser | 17 +++++++++++++++++ | |
| A ansible/roles/finger/files/nouser | 11 +++++++++++ | |
| A ansible/roles/finger/tasks/main.yml | 34 +++++++++++++++++++++++++++++… | |
| A ansible/roles/finger/vars/Debian.y… | 3 +++ | |
| A ansible/roles/git/handlers/main.yml | 6 ++++++ | |
| A ansible/roles/git/tasks/main.yml | 31 +++++++++++++++++++++++++++++… | |
| A ansible/roles/git/templates/git-da… | 18 ++++++++++++++++++ | |
| A ansible/roles/git/vars/Debian.yml | 2 ++ | |
| A ansible/roles/gopher/handlers/main… | 11 +++++++++++ | |
| A ansible/roles/gopher/tasks/main.yml | 58 ++++++++++++++++++++++++++++++ | |
| A ansible/roles/gopher/templates/geo… | 16 ++++++++++++++++ | |
| A ansible/roles/gopher/vars/Debian.y… | 4 ++++ | |
| A ansible/roles/gopher/vars/main.yml | 5 +++++ | |
| A ansible/roles/stagit/handlers/main… | 5 +++++ | |
| A ansible/roles/stagit/tasks/main.yml | 46 +++++++++++++++++++++++++++++… | |
| A ansible/roles/stagit/templates/sta… | 32 +++++++++++++++++++++++++++… | |
| A ansible/roles/stagit/vars/Debian.y… | 4 ++++ | |
| A ansible/roles/stagit/vars/main.yml | 5 +++++ | |
| D main.tf | 54 -----------------------------… | |
| D terraform.tfvars | 41 -----------------------------… | |
| R .terraform.lock.hcl -> terraform/.… | 0 | |
| A terraform/main.tf | 67 +++++++++++++++++++++++++++++… | |
| A terraform/outputs.tf | 3 +++ | |
| A terraform/terraform.tfvars | 45 +++++++++++++++++++++++++++++… | |
| A terraform/user_data/boot.yml | 16 ++++++++++++++++ | |
| A terraform/variables.tf | 21 +++++++++++++++++++++ | |
| D user_data.yml | 58 ------------------------------ | |
| D variables.tf | 25 ------------------------- | |
| 42 files changed, 635 insertions(+), 181 deletions(-) | |
| --- | |
| diff --git a/README b/README | |
| @@ -1,4 +1,42 @@ | |
| -bootstrap my cloud servers. | |
| - terraform plan -var="hcloud_token=$HCLOUD_TOKEN" | |
| - terraform apply -var="hcloud_token=$HCLOUD_TOKEN" | |
| +Terraform | |
| +========= | |
| + | |
| + | |
| +Bootstrap my hetzner cloud servers. If you actually want to use this for | |
| +yourself then you might need to do the following depending on your | |
| +requirements. | |
| + | |
| + | |
| + : Change the location of you backend in terraform.tf | |
| + : Update terraform.tfvars to suit. | |
| + : Export you personal API token to $HCLOUD_TOKEN | |
| + | |
| + | |
| + export HCLOUD_TOKEN='thisismylongasstoken' | |
| + | |
| + | |
| +The user_data script is a standard cloud-init yaml config that creates | |
| +an ansible user for configuring the instances. | |
| + | |
| + terraform plan | |
| + terraform apply | |
| + | |
| + | |
| +Ansible | |
| +======= | |
| + | |
| +Playbook to install the following: | |
| + | |
| + gopher | |
| + git and git daemon | |
| + stagit-gopher | |
| + efingerd | |
| + | |
| +Apply all: | |
| + | |
| + ansible-playbook -i inventory.yml main.yml | |
| + | |
| +Run tags | |
| + | |
| + ansible-playbook -i inventory.yml main.yml --tags <git/gopher/common> | |
| diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml | |
| @@ -0,0 +1,3 @@ | |
| +default: | |
| + username: jay | |
| + comment: Jay Scott | |
| diff --git a/ansible/group_vars/git.yml b/ansible/group_vars/git.yml | |
| @@ -0,0 +1,4 @@ | |
| +git: | |
| + user: git | |
| + group: users | |
| + base_path: /srv/git | |
| diff --git a/ansible/group_vars/gopher.yml b/ansible/group_vars/gopher.yml | |
| @@ -0,0 +1,12 @@ | |
| +geomyidae: | |
| + user: jay | |
| + group: users | |
| + root_path: /srv/gopher | |
| + git_branch: v0.69 | |
| + | |
| +stagit_gopher: | |
| + git_branch: 1.2 | |
| + cron_user: jay | |
| + cron_group: users | |
| + output_path: /srv/gopher | |
| + repo_path: /srv/git | |
| diff --git a/ansible/inventory.yml b/ansible/inventory.yml | |
| @@ -0,0 +1,13 @@ | |
| +all: | |
| + vars: | |
| + ansible_user: ansible | |
| + children: | |
| + finger: | |
| + hosts: | |
| + jay.scot | |
| + gopher: | |
| + hosts: | |
| + jay.scot | |
| + git: | |
| + hosts: | |
| + jay.scot | |
| diff --git a/ansible/main.yml b/ansible/main.yml | |
| @@ -0,0 +1,28 @@ | |
| +- hosts: all | |
| + become: true | |
| + roles: | |
| + - role: common | |
| + tags: | |
| + - common | |
| + | |
| +- hosts: git | |
| + become: true | |
| + roles: | |
| + - role: git | |
| + tags: | |
| + - git | |
| + | |
| +- hosts: gopher | |
| + become: true | |
| + roles: | |
| + - role: gopher | |
| + - role: stagit | |
| + tags: | |
| + - gopher | |
| + | |
| +- hosts: finger | |
| + become: true | |
| + roles: | |
| + - role: finger | |
| + tags: | |
| + - finger | |
| diff --git a/ansible/roles/common/files/sshd_config b/ansible/roles/common/file… | |
| @@ -0,0 +1,6 @@ | |
| +PasswordAuthentication no | |
| +ChallengeResponseAuthentication no | |
| +UsePAM yes | |
| +X11Forwarding no | |
| +Subsystem sftp /usr/lib/openssh/sftp-server | |
| +PermitRootLogin no | |
| diff --git a/ansible/roles/common/handlers/main.yml b/ansible/roles/common/hand… | |
| @@ -0,0 +1,4 @@ | |
| +- name: Restart sshd | |
| + ansible.builtin.service: | |
| + name: sshd | |
| + state: restart | |
| diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/m… | |
| @@ -0,0 +1,42 @@ | |
| +--- | |
| + | |
| +- name: Include OS-specific variables | |
| + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" | |
| + | |
| +- name: Include OS-specfic tasks | |
| + ansible.builtin.include_tasks: "setup-{{ ansible_os_family }}.yml" | |
| + | |
| +- name: Install Common Packages | |
| + ansible.builtin.package: | |
| + name: "{{ common_packages }}" | |
| + state: present | |
| + | |
| +- name: Add hardened SSH config | |
| + ansible.builtin.copy: | |
| + dest: /etc/ssh/sshd_config | |
| + src: sshd_config | |
| + owner: root | |
| + group: root | |
| + mode: 0600 | |
| + notify: Restart sshd | |
| + | |
| +- name: Add default user | |
| + ansible.builtin.user: | |
| + name: "{{ default.username }}" | |
| + comment: "{{ default.comment }}" | |
| + shell: /bin/bash | |
| + group: users | |
| + | |
| +- name: Set authorized key | |
| + ansible.posix.authorized_key: | |
| + user: "{{ default.username }}" | |
| + state: present | |
| + key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" | |
| + | |
| +- name: Add default user to sudo | |
| + community.general.sudoers: | |
| + name: "local-{{ default.username }}" | |
| + user: "{{ default.username }}" | |
| + state: present | |
| + nopassword: true | |
| + commands: ALL | |
| diff --git a/ansible/roles/common/tasks/setup-Debian.yml b/ansible/roles/common… | |
| @@ -0,0 +1,5 @@ | |
| +- name: Update apt cache. | |
| + ansible.builtin.apt: | |
| + update_cache: true | |
| + upgrade: true | |
| + cache_valid_time: 3600 | |
| diff --git a/ansible/roles/common/vars/Debian.yml b/ansible/roles/common/vars/D… | |
| @@ -0,0 +1,5 @@ | |
| +common_packages: | |
| + - htop | |
| + - vim | |
| + - finger | |
| + - lynx | |
| diff --git a/ansible/roles/finger/files/list b/ansible/roles/finger/files/list | |
| @@ -0,0 +1,4 @@ | |
| +#!/bin/sh | |
| + | |
| +cat "/etc/efingerd/logo.txt" | |
| +printf "\nusers:\n\t%s\n" "$(who -uw | cut -d " " -f 1 | sort | uniq)" | |
| diff --git a/ansible/roles/finger/files/log b/ansible/roles/finger/files/log | |
| @@ -0,0 +1 @@ | |
| +# nope, no logs | |
| diff --git a/ansible/roles/finger/files/logo.txt b/ansible/roles/finger/files/l… | |
| @@ -0,0 +1,7 @@ | |
| + ___ _______ __ __ _______ _______ _______ _______ | |
| + | || _ || | | | | || || || | | |
| + | || |_| || |_| | | _____|| || _ ||_ _| | |
| + | || || | | |_____ | || | | | | | | |
| + ___| || ||_ _| ___ |_____ || _|| |_| | | | | |
| +| || _ | | | | | _____| || |_ | | | | | |
| +|_______||__| |__| |___| |___| |_______||_______||_______| |___| | |
| diff --git a/ansible/roles/finger/files/luser b/ansible/roles/finger/files/luser | |
| @@ -0,0 +1,17 @@ | |
| +#!/bin/sh | |
| + | |
| +if [ "$3" = "root" ]; then | |
| + printf "Yeah, not going to happen." | |
| +elif [ "$3" = "git" ]; then | |
| + printf "I am not a git, you are!" | |
| +else | |
| + user_folder="/home/${3}" | |
| + | |
| + if [ -f "${user_folder}/finger.txt" ]; then | |
| + printf "\n" | |
| + cat "${user_folder}/finger.txt" | |
| + printf "\n" | |
| + fi | |
| +fi | |
| + | |
| +exit 0 | |
| diff --git a/ansible/roles/finger/files/nouser b/ansible/roles/finger/files/nou… | |
| @@ -0,0 +1,11 @@ | |
| +#!/bin/sh | |
| + | |
| +cat <<EOM | |
| + | |
| +You tried to finger non-existent user!!! | |
| +Your attempt is logged and sent to Scotland Yard, MI5 and the DLVA.. | |
| + | |
| +Expect a visit soon. | |
| + | |
| +Just joking, it went to /dev/null | |
| +EOM | |
| diff --git a/ansible/roles/finger/tasks/main.yml b/ansible/roles/finger/tasks/m… | |
| @@ -0,0 +1,34 @@ | |
| +--- | |
| +- name: Include OS-specific variables | |
| + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" | |
| + | |
| +- name: Install required packages | |
| + ansible.builtin.package: | |
| + name: "{{ common_packages }}" | |
| + state: present | |
| + | |
| +- name: Create efingerd config directory | |
| + ansible.builtin.file: | |
| + path: /etc/efingerd | |
| + state: directory | |
| + mode: '0755' | |
| + | |
| +- name: Copy efingerd scripts | |
| + ansible.builtin.copy: | |
| + src: "{{ item }}" | |
| + dest: "/etc/efingerd/{{ item }}" | |
| + owner: root | |
| + group: root | |
| + mode: '0755' | |
| + loop: | |
| + - list | |
| + - logo.txt | |
| + - log | |
| + - luser | |
| + - nouser | |
| + | |
| +- name: Enable inetd | |
| + ansible.builtin.systemd: | |
| + name: inetd | |
| + state: started | |
| + daemon_reload: true | |
| diff --git a/ansible/roles/finger/vars/Debian.yml b/ansible/roles/finger/vars/D… | |
| @@ -0,0 +1,3 @@ | |
| +common_packages: | |
| + - openbsd-inetd | |
| + - efingerd | |
| diff --git a/ansible/roles/git/handlers/main.yml b/ansible/roles/git/handlers/m… | |
| @@ -0,0 +1,6 @@ | |
| +--- | |
| +- name: Restart git-daemon | |
| + ansible.builtin.systemd: | |
| + name: git-daemon | |
| + state: started | |
| + daemon_reload: true | |
| diff --git a/ansible/roles/git/tasks/main.yml b/ansible/roles/git/tasks/main.yml | |
| @@ -0,0 +1,31 @@ | |
| +--- | |
| +- name: Include OS-specific variables | |
| + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" | |
| + | |
| +- name: Install required packages | |
| + ansible.builtin.package: | |
| + name: "{{ common_packages }}" | |
| + state: present | |
| + | |
| +- name: Added git service account | |
| + ansible.builtin.user: | |
| + name: "{{ git.user }}" | |
| + comment: "Git Service Account" | |
| + home: "{{ git.base_path }}" | |
| + shell: /usr/bin/git-shell | |
| + group: "{{ git.group }}" | |
| + | |
| +- name: Set initial authorized key | |
| + ansible.posix.authorized_key: | |
| + user: git | |
| + state: present | |
| + key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}" | |
| + | |
| +- name: Create systemd service file | |
| + ansible.builtin.template: | |
| + src: templates/git-daemon.service.j2 | |
| + dest: /lib/systemd/system/git-daemon.service | |
| + owner: root | |
| + group: root | |
| + mode: "0644" | |
| + notify: Restart git-daemon | |
| diff --git a/ansible/roles/git/templates/git-daemon.service.j2 b/ansible/roles/… | |
| @@ -0,0 +1,18 @@ | |
| +[Unit] | |
| +Description=Start Git Daemon | |
| + | |
| +[Service] | |
| +ExecStart=/usr/bin/git daemon --reuseaddr --base-path={{ git.base_path }} {{ g… | |
| + | |
| +Restart=always | |
| +RestartSec=500ms | |
| + | |
| +StandardOutput=syslog | |
| +StandardError=syslog | |
| +SyslogIdentifier=git-daemon | |
| + | |
| +User={{ git.user }} | |
| +Group={{ git.group }} | |
| + | |
| +[Install] | |
| +WantedBy=multi-user.target | |
| diff --git a/ansible/roles/git/vars/Debian.yml b/ansible/roles/git/vars/Debian.… | |
| @@ -0,0 +1,2 @@ | |
| +common_packages: | |
| + - git | |
| diff --git a/ansible/roles/gopher/handlers/main.yml b/ansible/roles/gopher/hand… | |
| @@ -0,0 +1,11 @@ | |
| +--- | |
| +- name: Restart geomyidae | |
| + ansible.builtin.systemd: | |
| + name: geomyidae | |
| + state: started | |
| + daemon_reload: true | |
| + | |
| +- name: Install geomyidae | |
| + community.general.system.make: | |
| + chdir: "{{ build_path }}" | |
| + target: install | |
| diff --git a/ansible/roles/gopher/tasks/main.yml b/ansible/roles/gopher/tasks/m… | |
| @@ -0,0 +1,58 @@ | |
| +--- | |
| +- name: Include OS-specific variables. | |
| + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" | |
| + | |
| +- name: Install required packages | |
| + ansible.builtin.package: | |
| + name: "{{ common_packages }}" | |
| + state: present | |
| + | |
| +- name: Git checkout | |
| + ansible.builtin.git: | |
| + repo: "{{ source_repo }}" | |
| + dest: "{{ build_path }}" | |
| + force: false | |
| + version: "{{ geomyidae.git_branch }}" | |
| + register: repo_clone | |
| + failed_when: | |
| + - repo_clone.failed | |
| + - not 'Local modifications exist in the destination' in repo_clone.msg | |
| + | |
| +- name: Disable TLS options | |
| + ansible.builtin.replace: | |
| + path: "{{ build_path }}/Makefile" | |
| + regexp: '^TLS_CFLAGS = -DENABLE_TLS' | |
| + replace: '#TLS_CFLAGS = -DENABLE_TLS' | |
| + when: disable_tls | |
| + | |
| +- name: Disable TLS flags | |
| + ansible.builtin.replace: | |
| + path: "{{ build_path }}/Makefile" | |
| + regexp: '^TLS_LDFLAGS = -ltls' | |
| + replace: '#TLS_LDFLAGS = -ltls' | |
| + when: disable_tls | |
| + | |
| +- name: Build geomyidae | |
| + community.general.system.make: | |
| + chdir: "{{ build_path }}" | |
| + notify: Install geomyidae | |
| + | |
| +- name: Flush handlers | |
| + ansible.builtin.meta: flush_handlers | |
| + | |
| +- name: Create root directory | |
| + ansible.builtin.file: | |
| + path: "{{ geomyidae.root_path }}" | |
| + owner: "{{ geomyidae.user }}" | |
| + group: "{{ geomyidae.group }}" | |
| + mode: 0755 | |
| + state: directory | |
| + | |
| +- name: Create systemd service file | |
| + ansible.builtin.template: | |
| + src: templates/geomyidae.service.j2 | |
| + dest: /lib/systemd/system/geomyidae.service | |
| + owner: root | |
| + group: root | |
| + mode: '0644' | |
| + notify: Restart geomyidae | |
| diff --git a/ansible/roles/gopher/templates/geomyidae.service.j2 b/ansible/role… | |
| @@ -0,0 +1,16 @@ | |
| +[Unit] | |
| +Description=Geomyidae Gopher Server | |
| +After=network.target | |
| +Wants=network.target | |
| +StartLimitBurst=5 | |
| +StartLimitIntervalSec=1 | |
| + | |
| +[Service] | |
| +Type=forking | |
| +Restart=on-abnormal | |
| +RestartSec=1 | |
| +User=root | |
| +ExecStart=/usr/local/bin/geomyidae -v 0 -b {{ geomyidae.root_path }} -p 70 -e … | |
| + | |
| +[Install] | |
| +WantedBy=multi-user.target | |
| diff --git a/ansible/roles/gopher/vars/Debian.yml b/ansible/roles/gopher/vars/D… | |
| @@ -0,0 +1,4 @@ | |
| +common_packages: | |
| + - git | |
| + - build-essential | |
| + - libssl-dev | |
| diff --git a/ansible/roles/gopher/vars/main.yml b/ansible/roles/gopher/vars/mai… | |
| @@ -0,0 +1,5 @@ | |
| +--- | |
| + | |
| +build_path: /tmp/src/geomyidae | |
| +source_repo: git://r-36.net/geomyidae | |
| +disable_tls: true | |
| diff --git a/ansible/roles/stagit/handlers/main.yml b/ansible/roles/stagit/hand… | |
| @@ -0,0 +1,5 @@ | |
| +--- | |
| +- name: Install stagit | |
| + community.general.system.make: | |
| + chdir: "{{ build_path }}" | |
| + target: install | |
| diff --git a/ansible/roles/stagit/tasks/main.yml b/ansible/roles/stagit/tasks/m… | |
| @@ -0,0 +1,46 @@ | |
| +--- | |
| +- name: Include OS-specific variables. | |
| + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" | |
| + | |
| +- name: Install required packages | |
| + ansible.builtin.package: | |
| + name: "{{ common_packages }}" | |
| + state: present | |
| + | |
| +- name: Git checkout | |
| + ansible.builtin.git: | |
| + repo: "{{ source_repo }}" | |
| + dest: "{{ build_path }}" | |
| + force: false | |
| + version: "{{ stagit_gopher.git_branch }}" | |
| + register: repo_clone | |
| + failed_when: | |
| + - repo_clone.failed | |
| + - not 'Local modifications exist in the destination' in repo_clone.msg | |
| + | |
| +- name: Enable old libgit2 workaround | |
| + ansible.builtin.replace: | |
| + path: "{{ build_path }}/Makefile" | |
| + regexp: '^#STAGIT_CFLAGS' | |
| + replace: 'STAGIT_CFLAGS' | |
| + when: enable_old_libgit2 | |
| + | |
| +- name: Build from source | |
| + community.general.system.make: | |
| + chdir: "{{ build_path }}" | |
| + notify: Install stagit | |
| + | |
| +- name: Create stagit run script | |
| + ansible.builtin.template: | |
| + src: templates/stagit_create.sh.j2 | |
| + dest: "/home/{{ stagit_gopher.cron_user }}/stagit_create.sh" | |
| + owner: "{{ stagit_gopher.cron_user }}" | |
| + group: "{{ stagit_gopher.cron_group }}" | |
| + mode: "755" | |
| + | |
| +- name: Adding script to cron | |
| + ansible.builtin.cron: | |
| + name: "run stagit script" | |
| + user: "{{ stagit_gopher.cron_user }}" | |
| + minute: "0" | |
| + job: "/home/{{ stagit_gopher.cron_user }}/stagit_create.sh" | |
| diff --git a/ansible/roles/stagit/templates/stagit_create.sh.j2 b/ansible/roles… | |
| @@ -0,0 +1,32 @@ | |
| +#!/bin/sh | |
| + | |
| +reposdir="{{ stagit_gopher.repo_path }}" | |
| +gopherdir="{{ stagit_gopher.output_path }}" | |
| +stagitdir="git/" | |
| +destdir="${gopherdir}/${stagitdir}" | |
| + | |
| +# remove /'s at the end. | |
| +stagitdir=$(printf "%s" "${stagitdir}" | sed 's@[/]*$@@g') | |
| + | |
| +rm -rf "{{ stagit_gopher.output_path }}/git/*" | |
| + | |
| +# make index. | |
| +/usr/local/bin/stagit-gopher-index -b "${stagitdir}" "${reposdir}/"*/ >"${dest… | |
| + | |
| +# make files per repo. | |
| +for dir in "${reposdir}/"*/; do | |
| + # strip .git suffix. | |
| + r=$(basename "${dir}") | |
| + d=$(basename "${dir}" ".git") | |
| + printf "%s... " "${d}" | |
| + | |
| + mkdir -p "${destdir}/${d}" | |
| + cd "${destdir}/${d}" || continue | |
| + /usr/local/bin/stagit-gopher -b "${stagitdir}/${d}" -c ".cache" \ | |
| + -u "gopher://jay.scot/1/git/$d/" "${reposdir}/${r}" | |
| + | |
| + # symlinks | |
| + ln -sf log.gph index.gph | |
| + | |
| + echo "done" | |
| +done | |
| diff --git a/ansible/roles/stagit/vars/Debian.yml b/ansible/roles/stagit/vars/D… | |
| @@ -0,0 +1,4 @@ | |
| +common_packages: | |
| + - git | |
| + - build-essential | |
| + - libgit2-dev | |
| diff --git a/ansible/roles/stagit/vars/main.yml b/ansible/roles/stagit/vars/mai… | |
| @@ -0,0 +1,5 @@ | |
| +--- | |
| + | |
| +build_path: /tmp/src/stagit-gopher | |
| +source_repo: git://git.codemadness.org/stagit-gopher | |
| +enable_old_libgit2: true | |
| diff --git a/main.tf b/main.tf | |
| @@ -1,54 +0,0 @@ | |
| -terraform { | |
| - required_providers { | |
| - hcloud = { | |
| - source = "hetznercloud/hcloud" | |
| - version = "1.36.2" | |
| - } | |
| - } | |
| -} | |
| - | |
| -provider "hcloud" { | |
| - token = var.hcloud_token | |
| -} | |
| - | |
| - | |
| -resource "hcloud_ssh_key" "this" { | |
| - name = "main_key" | |
| - public_key = file("~/.ssh/id_rsa.pub") | |
| -} | |
| - | |
| - | |
| -resource "hcloud_firewall" "this" { | |
| - name = "firewallrules" | |
| - | |
| - dynamic "rule" { | |
| - for_each = var.firewall_rules | |
| - | |
| - content { | |
| - description = rule.key | |
| - direction = rule.value.direction | |
| - protocol = rule.value.protocol | |
| - source_ips = rule.value.source_ips | |
| - port = rule.value.port | |
| - } | |
| - } | |
| -} | |
| - | |
| - | |
| -resource "hcloud_server" "nodes" { | |
| - for_each = var.nodes | |
| - | |
| - name = each.key | |
| - image = each.value.image | |
| - server_type = each.value.server_type | |
| - location = each.value.location | |
| - labels = each.value.labels | |
| - ssh_keys = [hcloud_ssh_key.this.id] | |
| - user_data = file("user_data.yml") | |
| - firewall_ids = [hcloud_firewall.this.id] | |
| - | |
| - public_net { | |
| - ipv4_enabled = each.value.ipv4 | |
| - ipv6_enabled = each.value.ipv6 | |
| - } | |
| -} | |
| diff --git a/terraform.tfvars b/terraform.tfvars | |
| @@ -1,41 +0,0 @@ | |
| -nodes = { | |
| - node1 = { | |
| - image = "debian-11" | |
| - location = "hel1", | |
| - server_type = "cx11", | |
| - ipv4 = true | |
| - ipv6 = true | |
| - labels = { | |
| - services = "git" | |
| - } | |
| - } | |
| -} | |
| - | |
| -firewall_rules = { | |
| - gopher = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "70" | |
| - } | |
| - ssh = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "22" | |
| - } | |
| - git = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "9418" | |
| - } | |
| - fingerd = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "79" | |
| - } | |
| - | |
| - | |
| -} | |
| diff --git a/.terraform.lock.hcl b/terraform/.terraform.lock.hcl | |
| diff --git a/terraform/main.tf b/terraform/main.tf | |
| @@ -0,0 +1,67 @@ | |
| +terraform { | |
| + required_providers { | |
| + hcloud = { | |
| + source = "hetznercloud/hcloud" | |
| + version = "1.36.2" | |
| + } | |
| + } | |
| + | |
| + backend "local" { | |
| + path = "/home/jay/.config/infra/terraform.tfstate" | |
| + } | |
| + | |
| +} | |
| + | |
| +resource "hcloud_ssh_key" "this" { | |
| + for_each = var.public_ssh_keys | |
| + | |
| + name = each.key | |
| + public_key = file(each.value) | |
| +} | |
| + | |
| + | |
| +resource "hcloud_firewall" "this" { | |
| + for_each = var.nodes | |
| + | |
| + name = each.key | |
| + | |
| + dynamic "rule" { | |
| + for_each = each.value.firewall_rules | |
| + | |
| + content { | |
| + description = rule.key | |
| + direction = rule.value.direction | |
| + protocol = rule.value.protocol | |
| + source_ips = rule.value.source_ips | |
| + port = rule.value.port | |
| + } | |
| + } | |
| +} | |
| + | |
| + | |
| +resource "hcloud_server" "this" { | |
| + for_each = var.nodes | |
| + | |
| + name = each.key | |
| + image = each.value.image | |
| + server_type = each.value.server_type | |
| + location = each.value.location | |
| + labels = each.value.labels | |
| + ssh_keys = [hcloud_ssh_key.this[each.value.public_key].id] | |
| + user_data = file(each.value.user_data) | |
| + firewall_ids = [hcloud_firewall.this[each.key].id] | |
| + | |
| + public_net { | |
| + ipv4_enabled = each.value.ipv4 | |
| + ipv6_enabled = each.value.ipv6 | |
| + } | |
| +} | |
| + | |
| +resource "hcloud_rdns" "this" { | |
| + for_each = hcloud_server.this | |
| + | |
| + server_id = each.value.id | |
| + ip_address = each.value.ipv4_address | |
| + dns_ptr = var.nodes[each.key].reverse_dns | |
| +} | |
| + | |
| diff --git a/terraform/outputs.tf b/terraform/outputs.tf | |
| @@ -0,0 +1,3 @@ | |
| +output "public_ip_address" { | |
| + value = {for name, server in hcloud_server.this: name => server.ipv4_address} | |
| +} | |
| diff --git a/terraform/terraform.tfvars b/terraform/terraform.tfvars | |
| @@ -0,0 +1,45 @@ | |
| +public_ssh_keys = { | |
| + main_key = "~/.ssh/id_rsa.pub" | |
| +} | |
| + | |
| +nodes = { | |
| + "jay.scot" = { | |
| + image = "debian-11" | |
| + location = "hel1", | |
| + server_type = "cx11", | |
| + reverse_dns = "jay.scot" | |
| + user_data = "user_data/boot.yml" | |
| + public_key = "main_key" | |
| + firewall_rules = { | |
| + gopher = { | |
| + direction = "in" | |
| + protocol = "tcp" | |
| + source_ips = ["0.0.0.0/0", "::/0"] | |
| + port = "70" | |
| + } | |
| + ssh = { | |
| + direction = "in" | |
| + protocol = "tcp" | |
| + source_ips = ["0.0.0.0/0", "::/0"] | |
| + port = "22" | |
| + } | |
| + git = { | |
| + direction = "in" | |
| + protocol = "tcp" | |
| + source_ips = ["0.0.0.0/0", "::/0"] | |
| + port = "9418" | |
| + } | |
| + fingerd = { | |
| + direction = "in" | |
| + protocol = "tcp" | |
| + source_ips = ["0.0.0.0/0", "::/0"] | |
| + port = "79" | |
| + } | |
| + } | |
| + ipv4 = true | |
| + ipv6 = true | |
| + labels = { | |
| + git = "true" | |
| + } | |
| + } | |
| +} | |
| diff --git a/terraform/user_data/boot.yml b/terraform/user_data/boot.yml | |
| @@ -0,0 +1,16 @@ | |
| +#cloud-config | |
| + | |
| +# disable ssh password authentication | |
| +ssh_pwauth: false | |
| + | |
| +# TODO: add in a ansible pull on boot at somepoint. | |
| +# add an ansible user | |
| +users: | |
| + - name: ansible | |
| + gecos: Ansible User | |
| + groups: users,wheel | |
| + sudo: ALL=(ALL) NOPASSWD:ALL | |
| + shell: /bin/bash | |
| + lock_passwd: true | |
| + ssh_authorized_keys: | |
| + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCRWnkYAChsjuT/T/IoENtm8OT18tPerea… | |
| diff --git a/terraform/variables.tf b/terraform/variables.tf | |
| @@ -0,0 +1,21 @@ | |
| + | |
| +variable "public_ssh_keys" { | |
| + description = "Public SSH key location to attach to instance." | |
| + type = map(any) | |
| +} | |
| + | |
| +variable "nodes" { | |
| + description = "Configuration settings for each required node." | |
| + type = map(object({ | |
| + image = string | |
| + location = string | |
| + server_type = string | |
| + reverse_dns = string | |
| + user_data = string | |
| + public_key = string | |
| + labels = map(any) | |
| + firewall_rules = map(any) | |
| + ipv4 = bool | |
| + ipv6 = bool | |
| + })) | |
| +} | |
| diff --git a/user_data.yml b/user_data.yml | |
| @@ -1,58 +0,0 @@ | |
| -#cloud-config | |
| -users: | |
| - - name: jay | |
| - groups: users | |
| - sudo: ALL=(ALL) NOPASSWD:ALL | |
| - shell: /bin/bash | |
| - ssh_authorized_keys: | |
| - - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCRWnkYAChsjuT/T/IoENtm8OT18tPer… | |
| - | |
| -package_update: true | |
| -package_upgrade: true | |
| - | |
| -packages: | |
| - - openbsd-inetd | |
| - - efingerd | |
| - - libgit2-dev | |
| - - vim | |
| - - htop | |
| - - git | |
| - | |
| -runcmd: | |
| - # SSH config | |
| - - sed -ie '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config | |
| - - sed -ie '/^PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/… | |
| - - sed -ie '/^X11Forwarding/s/^.*$/X11Forwarding no/' /etc/ssh/sshd_config | |
| - - sed -ie '/^#MaxAuthTries/s/^.*$/MaxAuthTries 2/' /etc/ssh/sshd_config | |
| - - sed -ie '/^#AllowTcpForwarding/s/^.*$/AllowTcpForwarding no/' /etc/ssh/ssh… | |
| - - sed -ie '/^#AllowAgentForwarding/s/^.*$/AllowAgentForwarding no/' /etc/ssh… | |
| - - sed -ie '/^#AuthorizedKeysFile/s/^.*$/AuthorizedKeysFile .ssh/authorized_k… | |
| - - systemctl restart ssh | |
| - # Git setup | |
| - - mkdir -p /srv/git | |
| - - chown -R git:git /srv/git | |
| - - systemctl enable git-daemon | |
| - - systemctl start git-daemon | |
| - | |
| -write_files: | |
| - - content: | | |
| - [Unit] | |
| - Description=Start Git Daemon | |
| - | |
| - [Service] | |
| - ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ | |
| - | |
| - Restart=always | |
| - RestartSec=500ms | |
| - | |
| - StandardOutput=syslog | |
| - StandardError=syslog | |
| - SyslogIdentifier=git-daemon | |
| - | |
| - User=git | |
| - Group=git | |
| - | |
| - [Install] | |
| - WantedBy=multi-user.target | |
| - path: /etc/systemd/system/git-daemon.service | |
| - permissions: '0644' | |
| diff --git a/variables.tf b/variables.tf | |
| @@ -1,25 +0,0 @@ | |
| -variable "hcloud_token" { | |
| - description = "Hetzner cloud personal API token." | |
| - type = string | |
| - sensitive = true | |
| -} | |
| - | |
| -variable "nodes" { | |
| - type = map(object({ | |
| - image = string | |
| - location = string | |
| - server_type = string | |
| - labels = map(any) | |
| - ipv4 = bool | |
| - ipv6 = bool | |
| - })) | |
| -} | |
| - | |
| -variable "firewall_rules" { | |
| - type = map(object({ | |
| - direction = string | |
| - protocol = string | |
| - source_ips = list(any) | |
| - port = string | |
| - })) | |
| -} |