Compare commits
No commits in common. "033d3d637136d3dc03804c6578308c8fb5546616" and "7b30a38166021b78fb39807bd13451cb8ff41d6a" have entirely different histories.
033d3d6371
...
7b30a38166
20 changed files with 290 additions and 60 deletions
8
.ageboxreg.yml
Normal file
8
.ageboxreg.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
file_ids:
|
||||||
|
- .env
|
||||||
|
- files/docker/fedi/.env
|
||||||
|
- files/docker/hoarder/.env
|
||||||
|
- files/docker/rss/.env
|
||||||
|
- roles/common/files/robo_key
|
||||||
|
- roles/docker/files/rclone.conf
|
||||||
|
version: "1"
|
||||||
0
.devfiles/hooks/.gitkeep
Normal file
0
.devfiles/hooks/.gitkeep
Normal file
5
.devfiles/hooks/commit-msg.sh
Normal file
5
.devfiles/hooks/commit-msg.sh
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
cog verify --file "$1"
|
||||||
16
.devfiles/hooks/pre-commit.sh
Normal file
16
.devfiles/hooks/pre-commit.sh
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
root="$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
cd "$root"
|
||||||
|
|
||||||
|
export PATH=$PATH:.devfiles/bin
|
||||||
|
|
||||||
|
gitleaks git
|
||||||
|
|
||||||
|
# Only validate encrypted files if we are tracking any
|
||||||
|
if [[ -e .ageboxreg.yml ]]; then
|
||||||
|
agebox validate --no-decrypt
|
||||||
|
fi
|
||||||
44
.devfiles/justfile
Normal file
44
.devfiles/justfile
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
set dotenv-load := true
|
||||||
|
|
||||||
|
export PATH := source_dir() + "/bin:" + source_dir() + "/scripts:" + env("PATH")
|
||||||
|
export AGEBOX_DEBUG := "0"
|
||||||
|
export AGEBOX_PUBLIC_KEYS := source_dir() + "/public_keys.txt"
|
||||||
|
|
||||||
|
# Install agebox from the latest github realse
|
||||||
|
install-agebox:
|
||||||
|
curl -sSL "https://github.com/slok/agebox/releases/latest/download/agebox-linux-amd64" -o .devfiles/bin/agebox
|
||||||
|
chmod + x .devfiles/bin/agebox
|
||||||
|
|
||||||
|
[no-cd]
|
||||||
|
install-hooks:
|
||||||
|
cog install-hook --all
|
||||||
|
|
||||||
|
# Easy and simple file repository encryption tool based on Age.
|
||||||
|
[working-directory('..')]
|
||||||
|
agebox +ARGS="--help":
|
||||||
|
@agebox {{ ARGS }}
|
||||||
|
|
||||||
|
# Encrypt the provided files, relative to project root.
|
||||||
|
encrypt +FILES: (agebox "encrypt " + FILES)
|
||||||
|
|
||||||
|
# Encrypt all the tracked files.
|
||||||
|
encrypt-all: (agebox "encrypt --all")
|
||||||
|
|
||||||
|
# Decrypt the provided files, relative to project root.
|
||||||
|
decrypt +FILES: (agebox "decrypt " + FILES)
|
||||||
|
|
||||||
|
# Decrypt all the tracked files.
|
||||||
|
decrypt-all: (agebox "decrypt --all --force")
|
||||||
|
|
||||||
|
# Reencrypt all the tracked files with the new public keys.
|
||||||
|
reencrypt: (agebox "reencrypt")
|
||||||
|
|
||||||
|
# Show the content of an encrypted file to stdout.
|
||||||
|
crypt-peek +FILES: (agebox "cat " + FILES)
|
||||||
|
|
||||||
|
# Validate that all tracked files are encrypted.
|
||||||
|
crypt-check:(agebox "validate --no-decrypt ")
|
||||||
|
|
||||||
|
# Validate no credentials are pushed to git
|
||||||
|
leaks:
|
||||||
|
@gitleaks git --verbose --redact
|
||||||
4
.devfiles/public_keys.txt
Normal file
4
.devfiles/public_keys.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# aleidk
|
||||||
|
age1h0wfmxcrfjjcmv3ju7zcm6gc8j8pz35gs08kkqsjej20ndsxq54qv48hgn
|
||||||
|
# anavarro
|
||||||
|
age1gj7hj894l0a0lvu3fsndlkdkyc0da7963kcqhpfe43reflx3gafqnm058u
|
||||||
0
.devfiles/scripts/.gitkeep
Normal file
0
.devfiles/scripts/.gitkeep
Normal file
30
.devfiles/scripts/dependecy-check.sh
Executable file
30
.devfiles/scripts/dependecy-check.sh
Executable file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
root="$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
export PATH=$root/.devfiles/bin:$root/.devfiles/scripts:$PATH
|
||||||
|
|
||||||
|
devtools=(
|
||||||
|
age
|
||||||
|
agebox
|
||||||
|
cog
|
||||||
|
gitleaks
|
||||||
|
)
|
||||||
|
|
||||||
|
missing_tools=()
|
||||||
|
|
||||||
|
for cmd in "${devtools[@]}"; do
|
||||||
|
if ! command -v "$cmd" &>/dev/null; then
|
||||||
|
missing_tools+=("$cmd")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${#missing_tools[@]} != 0 ]]; then
|
||||||
|
echo "The following tools where not found:"
|
||||||
|
printf "%s\n" "${missing_tools[@]}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo -e "All tools are installed!"
|
||||||
|
fi
|
||||||
16
.devfiles/scripts/fetch_gh_release.sh
Executable file
16
.devfiles/scripts/fetch_gh_release.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
basedir=".devfiles/bin"
|
||||||
|
|
||||||
|
repo="$1"
|
||||||
|
shift
|
||||||
|
release_filename="$1"
|
||||||
|
shift
|
||||||
|
out_filename="$basedir/$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
curl -sSL "https://github.com/$repo/releases/latest/download/$release_filename" -o "$out_filename"
|
||||||
|
|
||||||
|
chmod +x "$out_filename"
|
||||||
42
.devfiles/scripts/gitignore.sh
Executable file
42
.devfiles/scripts/gitignore.sh
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
root="$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
base_url="https://git.alecodes.page/api/v1/gitignore/templates"
|
||||||
|
|
||||||
|
query="$*"
|
||||||
|
|
||||||
|
list_available() {
|
||||||
|
curl -Ssl $base_url | jq -r '.[]'
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -z $query ]]; then
|
||||||
|
list_available
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp_file="$(mktemp)"
|
||||||
|
|
||||||
|
for template in $query; do
|
||||||
|
# Capitalize the string
|
||||||
|
template=${template,,}
|
||||||
|
template=${template^}
|
||||||
|
|
||||||
|
response="$(curl -Ssl "$base_url/$template")"
|
||||||
|
name="$(echo "$response" | jq -r '.name')"
|
||||||
|
content="$(echo "$response" | jq -r '.source')"
|
||||||
|
|
||||||
|
if [[ "$content" == "null" ]]; then
|
||||||
|
echo "Template not found, available options:"
|
||||||
|
list_available
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "\n### %s\n\n%s\n\n" "$name" "$content" >>"$tmp_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
sed -i -ne "/#### -- TEMPLATES BEGIN -- ####/ {p; r $tmp_file" -e ':a; n; /#### -- TEMPLATES END -- ####/ {p; b}; ba}; p' "$root/.gitignore"
|
||||||
|
|
||||||
|
rm "$tmp_file"
|
||||||
BIN
.env.agebox
Normal file
BIN
.env.agebox
Normal file
Binary file not shown.
|
|
@ -1,6 +1,10 @@
|
||||||
# Repo management tasks
|
# Repo management tasks
|
||||||
|
mod repo '.devfiles/justfile'
|
||||||
set dotenv-load := true
|
set dotenv-load := true
|
||||||
|
|
||||||
|
export ANSIBLE_VAULT_PASSWORD_FILE := justfile_directory() + "/.decrypt-pass.txt"
|
||||||
|
export ANSIBLE_BECOME_PASSWORD_FILE := justfile_directory() + "/.become-pass.txt"
|
||||||
|
|
||||||
# Debug output, disabled in CI
|
# Debug output, disabled in CI
|
||||||
|
|
||||||
export ANSIBLE_DISPLAY_ARGS_TO_STDOUT := if env('CI', '') == 'true' { 'false' } else { 'true' }
|
export ANSIBLE_DISPLAY_ARGS_TO_STDOUT := if env('CI', '') == 'true' { 'false' } else { 'true' }
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ inventory=/etc/ansible/hosts,./hosts/inventory.yaml
|
||||||
;log_path=
|
;log_path=
|
||||||
|
|
||||||
# (pathspec) Colon separated paths in which Ansible will search for Lookup Plugins.
|
# (pathspec) Colon separated paths in which Ansible will search for Lookup Plugins.
|
||||||
lookup_plugins=/home/aleidk/.ansible/plugins/lookup:/usr/share/ansible/plugins/lookup:./lookup_plugins/
|
;lookup_plugins=/home/aleidk/.ansible/plugins/lookup:/usr/share/ansible/plugins/lookup
|
||||||
|
|
||||||
# (string) Sets the macro for the 'ansible_managed' variable available for :ref:`ansible_collections.ansible.builtin.template_module` and :ref:`ansible_collections.ansible.windows.win_template_module`. This is only relevant for those two modules.
|
# (string) Sets the macro for the 'ansible_managed' variable available for :ref:`ansible_collections.ansible.builtin.template_module` and :ref:`ansible_collections.ansible.windows.win_template_module`. This is only relevant for those two modules.
|
||||||
;ansible_managed=Ansible managed
|
;ansible_managed=Ansible managed
|
||||||
|
|
@ -185,7 +185,7 @@ lookup_plugins=/home/aleidk/.ansible/plugins/lookup:/usr/share/ansible/plugins/l
|
||||||
;module_name=command
|
;module_name=command
|
||||||
|
|
||||||
# (pathspec) Colon separated paths in which Ansible will search for Modules.
|
# (pathspec) Colon separated paths in which Ansible will search for Modules.
|
||||||
# library=/home/aleidk/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:./modules
|
;library=/home/aleidk/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
|
||||||
|
|
||||||
# (pathspec) Colon separated paths in which Ansible will search for Module utils files, which are shared by modules.
|
# (pathspec) Colon separated paths in which Ansible will search for Module utils files, which are shared by modules.
|
||||||
;module_utils=/home/aleidk/.ansible/plugins/module_utils:/usr/share/ansible/plugins/module_utils
|
;module_utils=/home/aleidk/.ansible/plugins/module_utils:/usr/share/ansible/plugins/module_utils
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,50 +0,0 @@
|
||||||
# python 3 headers, required if submitting to Ansible
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import json
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleParserError
|
|
||||||
from ansible.plugins.lookup import LookupBase
|
|
||||||
from ansible.utils.display import Display
|
|
||||||
from jinja2 import Environment
|
|
||||||
|
|
||||||
DOCUMENTATION = r"""
|
|
||||||
name: rbw
|
|
||||||
short_description: get secrets using rbw
|
|
||||||
options:
|
|
||||||
_terms:
|
|
||||||
description: Name of the secret to get
|
|
||||||
required: True
|
|
||||||
"""
|
|
||||||
|
|
||||||
display = Display()
|
|
||||||
|
|
||||||
|
|
||||||
def rbw(name: str):
|
|
||||||
sub = subprocess.run(["rbw", "get", name, "--raw"], capture_output=True)
|
|
||||||
|
|
||||||
secret = json.loads(sub.stdout)
|
|
||||||
|
|
||||||
display.debug(f'Obtaining data for "{secret["name"]}"')
|
|
||||||
|
|
||||||
return secret
|
|
||||||
|
|
||||||
|
|
||||||
class LookupModule(LookupBase):
|
|
||||||
def run(self, terms, variables=None, **kwargs):
|
|
||||||
# First of all populate options,
|
|
||||||
# this will already take into account env vars and ini config
|
|
||||||
self.set_options(var_options=variables, direct=kwargs)
|
|
||||||
|
|
||||||
# lookups in general are expected to both take a list as input and output a list
|
|
||||||
# this is done so they work with the looping construct 'with_'.
|
|
||||||
ret = []
|
|
||||||
for term in terms:
|
|
||||||
secret = rbw(term)
|
|
||||||
|
|
||||||
ret.append(secret)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
24
opentofu/vms/.terraform.lock.hcl
generated
Normal file
24
opentofu/vms/.terraform.lock.hcl
generated
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# This file is maintained automatically by "tofu init".
|
||||||
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.opentofu.org/bpg/proxmox" {
|
||||||
|
version = "0.43.2"
|
||||||
|
constraints = "0.43.2"
|
||||||
|
hashes = [
|
||||||
|
"h1:5+YNvUbtMlus6GJJktc9/7o68tYgQIQxhjTqqt2WCpk=",
|
||||||
|
"zh:07c9357e80cc52c020bd3728e5a00e21b9c06b20ee91d13d0c8ea034c1de4b6f",
|
||||||
|
"zh:41208bfd4d69f04142a69e9eabd79d4cba99f4fcacd59318aad0265c7b4bfe9e",
|
||||||
|
"zh:420623a0ae35bee21c00da444c0fbc63d3d6008d71516d90e11512651f25210f",
|
||||||
|
"zh:4cf21c0245a4fcbfec9edc1c65a5a0f0d83180607d870229ce3761fa25652ac7",
|
||||||
|
"zh:6f07cab62a60d7adc7a2c3f6fb27057dd70883c02c8ee762aec683743aee16c0",
|
||||||
|
"zh:75c4c97b110373ee48ad87774d9becbb1e21d55e0a4324f594a3b3cc8d25d73e",
|
||||||
|
"zh:79b3ab36e5276a1172c661eb60574a330cb502f2de40410f2540a50061a777f7",
|
||||||
|
"zh:96a8cda572ac540aa6c616eabd2e8dc9399809e8558f6d53a883da2a9fbdede8",
|
||||||
|
"zh:99a78347944868062bac87e93372672aa0f12422cf82d5a7f13a00805f18d5bd",
|
||||||
|
"zh:a6d2ff27558114277a9e2db874f5c9c9ee65d0dc5e918f2d9994e3ec9ef0e2b5",
|
||||||
|
"zh:c220049b7b3890e8b882873f0a4320d5b6ca28cf4b3ff9128a130e86ffbc3209",
|
||||||
|
"zh:da586199b595f278d4ecfc64e60afa52b15b9183323edde00d74a7ede5abad27",
|
||||||
|
"zh:f2caa3eefc03dd03f05ce466e98ba6fb9f0b87ece3a7fc35eb73d63f816c13d4",
|
||||||
|
"zh:f99012369fff51af76557d5616a24ae48d12ef662c6d132aa74db7f6b9d4144b",
|
||||||
|
]
|
||||||
|
}
|
||||||
35
opentofu/vms/providers.tf
Normal file
35
opentofu/vms/providers.tf
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
# docs: https://registry.terraform.io/providers/bpg/proxmox/latest/docs
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "bpg/proxmox"
|
||||||
|
version = "0.43.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backend "s3" {
|
||||||
|
bucket = "opentofu-state"
|
||||||
|
region = "us-east-1"
|
||||||
|
key = "lxc/terraform.tfstate"
|
||||||
|
encrypt = false
|
||||||
|
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_region_validation = true
|
||||||
|
skip_requesting_account_id = true
|
||||||
|
skip_s3_checksum = true
|
||||||
|
|
||||||
|
endpoints = {
|
||||||
|
s3 = "https://a7638f5d66d44acc48d4b80b7c3c8a0c.r2.cloudflarestorage.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "proxmox" {
|
||||||
|
insecure = true
|
||||||
|
tmp_dir = "/var/tmp"
|
||||||
|
ssh {
|
||||||
|
agent = true
|
||||||
|
username = "robo"
|
||||||
|
}
|
||||||
|
}
|
||||||
56
opentofu/vms/s3.tf
Normal file
56
opentofu/vms/s3.tf
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# docs: https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_container
|
||||||
|
|
||||||
|
variable "vm_names" {
|
||||||
|
type = list(string)
|
||||||
|
default = ["donkey-kong"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "proxmox_virtual_environment_container" "vm" {
|
||||||
|
for_each = toset(var.vm_names)
|
||||||
|
vm_id = 160 + index(var.vm_names, each.key)
|
||||||
|
node_name = "pve"
|
||||||
|
description = "S3 data storage"
|
||||||
|
unprivileged = true
|
||||||
|
|
||||||
|
start_on_boot = "true"
|
||||||
|
|
||||||
|
disk {
|
||||||
|
datastore_id = "local-lvm"
|
||||||
|
size = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
initialization {
|
||||||
|
hostname = each.key
|
||||||
|
|
||||||
|
ip_config {
|
||||||
|
ipv4 {
|
||||||
|
address = "10.0.10.${160 + index(var.vm_names, each.key)}/24"
|
||||||
|
gateway = "10.0.0.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user_account {
|
||||||
|
password = var.root_password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
name = "eth0"
|
||||||
|
firewall = true
|
||||||
|
bridge = "vnet10"
|
||||||
|
}
|
||||||
|
|
||||||
|
operating_system {
|
||||||
|
template_file_id = "local:vztmpl/alpine-latest-base-2024-12-30.tar.gz"
|
||||||
|
type = "alpine"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags = [
|
||||||
|
"storage",
|
||||||
|
"s3",
|
||||||
|
]
|
||||||
|
|
||||||
|
features {
|
||||||
|
nesting = true
|
||||||
|
}
|
||||||
|
}
|
||||||
4
opentofu/vms/variables.tf
Normal file
4
opentofu/vms/variables.tf
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
variable "root_password" {
|
||||||
|
type = string
|
||||||
|
description = "Password used for the root user"
|
||||||
|
}
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
---
|
|
||||||
- hosts: localhost
|
|
||||||
vars:
|
|
||||||
secret: "{{ lookup('rbw', 'Work Laptop') }}"
|
|
||||||
tasks:
|
|
||||||
|
|
||||||
- debug:
|
|
||||||
msg: the value of the secret is {{ secret.data.public_key }}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue