diff --git a/README.md b/README.md index 5472757..dac56e6 100644 --- a/README.md +++ b/README.md @@ -22,32 +22,42 @@ Below is the directory map for this repo. ├── host_vars │ ├── goldenrod.yaml │ └── new-bark.yaml +├── infrastructure.code-workspace ├── inventory.yaml ├── README.md ├── roles +│ ├── backup +│ │ ├── files +│ │ ├── handlers +│ │ ├── tasks +│ │ └── templates │ ├── common │ │ └── tasks -│ │ └── main.yaml │ ├── dns_server │ │ ├── handlers -│ │ │ └── main.yaml │ │ ├── tasks -│ │ │ └── main.yaml │ │ └── templates -│ │ └── adguard_quadlet.j2 │ └── gitea_server │ ├── handlers -│ │ └── main.yaml │ ├── tasks -│ │ └── main.yaml │ └── templates -│ ├── act_runner_quadlet.j2 -│ └── gitea_quadlet.j2 └── site.yaml ```` +## Roles +Below is a list of all roles in this project. +Each role has a separate `README.md` that goes in depth about that role and any required variables for that role. + +| Role Name | README file | Tags | +|-----------|-------------|------| +| Backup |[README.md](roles/backup/README.md)| common, backup| +| Common |[README.md](roles/common/README.md)| common| +| DNS Server |[README.md](roles/dns_server/README.md)| dns, core| +| Gitea Server |[README.md](roles/gitea_server/README.md)| gitea, core| + ## Prerequisites +### Install Tools To run this project locally the following tools are required. All install commands assume you are running Ubuntu/Debian. @@ -61,6 +71,24 @@ All install commands assume you are running Ubuntu/Debian. ``` - SSH access to target nodes +### Global Connection Variables +This playbook relies globally on `ansible_user` and `ansible_become_pass` for host authentication and privilege escalation. While configured per-host within `host_vars` for this deployment, they can also be defined globally in `group_vars/all.yaml` if your environment uses shared credentials. + +> [!WARNING] +> Any variable marked `# !SENSITIVE` **should not** be stored in plain text under any circumstance. + +```yaml +# (required) The SSH user Ansible utilizes to connect to target nodes. +# Must have sudo privileges. DO NOT set as root. +# format: string +ansible_user: + +# (required) The sudo password for the user defined above. +# format: string +# !SENSITIVE +ansible_become_pass: +``` + ## How to Run The ultimate goal of this project is a fully automated gitops workflow. However, until that is fully running below are the instructions to run this project locally. @@ -95,5 +123,6 @@ Below is a list of all services currently deployed by this project. This list wi Unless otherwise stated all services are run via rootless podman quadlets. -- Internal DNS (dns_server) - AdguardHome for network wide adblocking and local DNS resoultion +- Internal DNS (dns_server) - AdguardHome for network wide ad-blocking and local DNS resolution - Git Server and CI/CD runner (gitea_server) - Gitea alongside act runner for local git with repo mirroring and local private ci/cd runners +- Automated Backup (rclone and restic) - Restic using rclone backend to handle automated backups for key directories diff --git a/roles/backup/README.md b/roles/backup/README.md new file mode 100644 index 0000000..0743b5a --- /dev/null +++ b/roles/backup/README.md @@ -0,0 +1,105 @@ +# Role: Backup +Installs and configures rclone and restic to handle daily backups +Creates systemd services for both daily restic backups and weekly restic prune jobs, and creates systemd timers to automatically run them + +## Tags +- backup +- common + +## Required Variables +Below is an annotated break down of the required variables and their structure for this role + +These blocks should be defined in the `host_vars` file for each host as all variables are unique to the specific host. + +> [!WARNING] +> Any variable marked `# !SENSITIVE` **should not** be stored in plain text under any circumstance + +### Rclone Remote Info +This info is used to create the rclone.conf file. + +All variables listed below are required for this role to run correctly +```yaml +# (required) This is a list of all rclone remotes to define in the rclone.conf +# At least one remote is required, but you may have as many as you want +rclone_remotes: + # (required) Name of the remote to add. Must be unique to the host + # format: string + - remote_name: server-gdrive + + # (required) Client ID of google cloud project OAuth Client + # format: string + # !SENSITIVE + client_id: + + # (required) Client secret of google cloud project OAuth Client + # format: string + # !SENSITIVE + client_secret: + + # (required) Client auth token. This must be generated one time for each host + # format: json string + # !SENSITIVE + client_auth_token: + + # (required) ID for google drive shared drive. Found in the URL of the shared drive + # https://drive.google.com/drive/u/0/folders/ + # format: string + # !SENSITIVE + team_drive_id: +``` + +### Restic Repo Info +This info is used to create the restic service files, and defines what directories will be backed up. + +All variables listed below are required for this role to run correctly + +```yaml + +# (required) password to restic repo +# This is required for any operations done to the restic repo. Keep this password saved somewhere secure that you can access +# format: string +# !SENSITIVE +restic_password: + +# (required) name of the restic repo +# This name can be anything you want, however it must be unique per rclone remote +# This will also be the name of the folder in google drive +# format: snake_case +backup_name: + +# (required) unique identifier for the repo. It is used by restic to differentiate each repo +# format: rclone::{{ backup_name }} +restic_repo_url: + +# (required) path to password file. +# format: /path/to/file +restic_password_file: + +# (required) path to rclone.conf file +# format: /path/to/rclone.conf +rclone_config_path: + +# (required) list of paths to backup +# recommended paths to backup are listed in this example +# format: /path/to/dir +backup_paths: + - /home + - /etc + - /var/log + +# (required) number of daily backups to keep +# recommend value listed +# format: int +keep_daily: 7 + +# (required) number of weekly backups to keep +# recommended value listed +# format: int +keep_weekly: 4 +``` + +## Execution +To run this role without running the entire playbook, use the following command: +```bash +ansible-playbook site.yaml --tags "backup" +``` \ No newline at end of file diff --git a/roles/common/README.md b/roles/common/README.md new file mode 100644 index 0000000..2dd5a7f --- /dev/null +++ b/roles/common/README.md @@ -0,0 +1,39 @@ +# Role: Common +Installs basic tools and configures base settings for all servers +This role should always be able to target all hosts. + +## Tags +- common + + +## Required Variables +Below is an annotated break down of the required variables and their structure for this role +These variables can be defined either in `host_vars` or `group_vars` as they are generic enough that all hosts can have the same path. However it is recommended to define them per host if possible + +> [!WARNING] +> Any variable marked `# !SENSITIVE` **should not** be stored in plain text under any circumstance + +### Podman Variables +This information is used to setup base podman directories + +All variables listed below are required for this role to run correctly + +```yaml +# (required) path to directory where podman volume mounts will be placed +# format: /path/to/dir +podman_config_base_dir: + +# (required) path to where quadlet files will be saved +# Recommended value listed below. Without changes, this is the only path the container generator will look for container files on systemd daemon-reload +# format: /path/to/dir +podman_quadlet_base_dir: "/home/{{ ansible_user }}/.config/containers/systemd" +``` + +## Execution +> [!NOTE] +> This role cannot be ran by itself as other required roles are marked with the common tag. This is by design + +To run all common roles, use the following command +```bash +ansible-playbook site.yaml --tags "common" +``` diff --git a/roles/dns_server/README.md b/roles/dns_server/README.md new file mode 100644 index 0000000..1caf261 --- /dev/null +++ b/roles/dns_server/README.md @@ -0,0 +1,63 @@ +# Role: DNS Server +Sets up and deploys DNS server. +Current setup deploys Adguard Home as the default DNS server, but any can be used + +## Tags +- core +- dns + +## Required Variables +Below is an annotated breakdown of the required variables and their structure for this role + +These blocks should be defined in the `host_vars` file for each host as all variables are unique to the specific host. + +> [!WARNING] +> Any variable marked `# !SENSITIVE` **should not** be stored in plain text under any circumstance + +### DNS Info +Defines settings for dns server quadlet to be deployed + +```yaml +# (required) List of all DNS containers to be deployed +# in theory you can run multiple containers, however it is highly recommend to only run one +# at least one service is required +dns_services: + + # (required) name of the container in podman, and service name in systemd + # This is unique to both podman and systemd + # format: snake_case + - name: + + # (required) URL of container image + # can be from any container registry + # format: url + image: + + # (optional) category of the container + # this changes the folder the quadlet is saved to. + # default: "services" + # format: string + category: services + + # (optional) list of volume mounts to be used by the container + # it is highly recommended to use volume mounts for DNS containers to persist configs + # format example is listed below + # default: [] + # format: /local/path/:/container/path + volumes: + - /local/path:/container/path +``` + +## Templates + +### adguard_quadlet.j2 +This template is used to generate .container files for DNS services. Currently it is set up to expect the use of Adguard Home container images. + +## Execution +> [!CAUTION] +> This role targets and can potentially restart core services. As such it is recommended to only run this role when 100% necessary + +To run this command without running all roles in the playbook, use the following command +```bash +ansible-playbook site.yaml --tags "dns" +``` diff --git a/roles/gitea_server/README.md b/roles/gitea_server/README.md new file mode 100644 index 0000000..99b3e77 --- /dev/null +++ b/roles/gitea_server/README.md @@ -0,0 +1,124 @@ +# Role: Gitea Server +Sets up and deploys Gitea server and Act Runner. +It is recommended that only one server have this role. This prevents issues with multiple sources of truth. + +## Tags +- core +- gitea + +## Required Variables +Below is an annotated breakdown of the required variables and their structure for this role + +These blocks should be defined in the `host_vars` file for the host you wish to be the designated gitea server + +> [!WARNING] +> Any variable marked `# !SENSITIVE` **should not** be stored in plain text under any circumstance + +### Gitea Info +Defines settings for the Gitea container to be deployed + +```yaml +# (required) List of all Gitea containers to be deployed +# in theory you can run multiple containers, however it is highly recommend to only run one +# at least one service is required +gitea_services: + + # (required) name of the container in podman, and service name in systemd + # This is unique to both podman and systemd + # format: snake_case + - name: + + # (required) URL of container image + # can be from any container registry + # format: url + image: + + # (optional) name of container owner + # best practice is to use the name of the user running this container + # default: "jdelpilar" + # format: string + container_owner: + + # --- Traefik Labels --- # + # (optional) subdomain for the WebUI of the container + # This is used to build the FQDN that traefik will use + # default: name value defined above + # format: snake_case + subdomain: + + # (optional) domain used in FQDN + # default: "delpilar.net" + # format: URL (domain only) + domain: + + # (optional) Port of the WebUI as defined by the container + # Please check the documentation of the specific container used to find this value + # default: 80 + # format: int + port: 3000 + + # (optional) list of volume mounts to be used by the container + # it is highly recommended to use volume mounts for Gitea containers to persist configs + # format example is listed below + # default: [] + # format: /local/path/:/container/path + volumes: + - /local/path:/container/path +``` +### Act Runner Info +Defines settings for the Act Runner container to be deployed + +```yaml + +# (required) List of all Act Runner containers to be deployed +# defining multiple runners may result in better concurrency +# however for most users, one runner will be enough +# at least one service is required +runner_services: + + # (required) name of the container in podman, and service name in systemd + # This is unique to both podman and systemd + # format: snake_case + - name: + + # (required) URL of container image + # can be from any container registry + # format: url + image: + + + # (optional) name of container owner + # best practice is to use the name of the user running this container + # default: "jdelpilar" + # format: string + container_owner: + + # (required) URL of the gitea instance + # should match the URL generated by the subdomain and domain variables for the gitea service + # format: URL + gitea_url: + + # (required) Unique token for the runner. Authenticates the runner to gitea + # Must be generated via the gitea instance. Any value can be used to allow this role to set up gitea + # format: string + # !SENSITIVE + runner_token: +``` + + +## Templates + +### gitea_quadlet.j2 +This template is used to generate .container files for Gitea services. This template includes a section for traefik labels. + +### act_runner_quadlet.j2 +This template is used to generate .container files for act_runner services. + +## Execution +> [!CAUTION] +> This role targets and can potentially restart core services. As such it is recommended to only run this role when 100% necessary + +To run this command without running all roles in the playbook, use the following command +```bash +ansible-playbook site.yaml --tags "gitea" +```