aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Damani <me@kumardamani.net>2026-09-15 15:34:40 +0000
committerKumar Damani <me@kumardamani.net>2026-09-15 15:34:40 +0000
commit2a841c704b17d5f8edf864a3ee5245d07e6ec5c7 (patch)
tree788e8c2e5ead0a92220a09afb69332fabc33d988
parent34a9231e704ff4f6f2676dfaaccbb3bfb03a933d (diff)
s3 config
-rw-r--r--nix/.sops.yaml8
-rw-r--r--nix/README.md16
-rw-r--r--nix/flake.nix9
-rw-r--r--nix/per-host/s3/configuration.nix67
-rw-r--r--nix/secrets/s3.yaml37
-rwxr-xr-xterraform/main.tf35
6 files changed, 172 insertions, 0 deletions
diff --git a/nix/.sops.yaml b/nix/.sops.yaml
index c0f2315..b657a25 100644
--- a/nix/.sops.yaml
+++ b/nix/.sops.yaml
@@ -6,6 +6,7 @@ keys:
- &server_git age152as4m0ytaq0dd78lhs7yla2twgkucun9ew02q5xhgffehgsmczqdl4trg
- &server_photos age1zdy4saxtcs6y90mrjlmz6hnknk67w0cd3n79g2y6fvtzzfsq6f6shwamzj
- &server_caldav age1mhugjsg0pz45p56p5vc6hz05zrnk630j6p5xu4n2nsskvtxg8cqsndqr90
+ - &server_s3 age1nlkl8h7x33ssq3m5ka9syxurxz37y2duzhkvx3mmv23fxhetkuksqap73n
creation_rules:
- path_regex: 'secrets/torrents.*\.yaml$'
@@ -42,3 +43,10 @@ creation_rules:
- *admin_me
- *admin_me_2
- *server_caldav
+
+ - path_regex: 'secrets/s3.*\.yaml$'
+ key_groups:
+ - age:
+ - *admin_me
+ - *admin_me_2
+ - *server_s3
diff --git a/nix/README.md b/nix/README.md
index b7a00df..020bc36 100644
--- a/nix/README.md
+++ b/nix/README.md
@@ -101,3 +101,19 @@ git remote set-url --add --push origin git@git.kumardamani.net:<name>.git
git remote set-url --add --push origin git@gitlab.com:kdam0/<name>.git
git remote -v
```
+
+## s3
+
+Bootstrap:
+```sh
+sudo garage status
+sudo garage layout assign -z dc1 -c 10G <NODE_ID>
+sudo garage layout apply --version 1
+
+sudo garage bucket create <BUCKET_NAME>
+
+# to enable static sites
+sudo garage bucket website --allow <BUCKET_NAME>
+
+sudo garage key create site-uploader
+```
diff --git a/nix/flake.nix b/nix/flake.nix
index 3e4be37..50d9f5f 100644
--- a/nix/flake.nix
+++ b/nix/flake.nix
@@ -27,6 +27,15 @@
];
};
+ "s3" = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ modules = [
+ ./per-host/base/configuration.nix
+ ./per-host/s3/configuration.nix
+ sops-nix.nixosModules.sops
+ ];
+ };
+
"git" = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
diff --git a/nix/per-host/s3/configuration.nix b/nix/per-host/s3/configuration.nix
new file mode 100644
index 0000000..7af6d9d
--- /dev/null
+++ b/nix/per-host/s3/configuration.nix
@@ -0,0 +1,67 @@
+{ config, pkgs, modulesPath, lib, system, ... }:
+
+{
+ config = {
+ sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
+ sops.defaultSopsFile = ../../secrets/s3.yaml;
+ sops.secrets."garage/rpc-secret" = {
+ owner = "garage";
+ mode = "0400";
+ };
+ sops.secrets."garage/admin-token" = {
+ owner = "garage";
+ mode = "0400";
+ };
+ sops.secrets."garage/env" = { };
+
+ networking.hostName = "s3";
+ networking.firewall.allowedTCPPorts = [ 3900 3902 ];
+
+ users.users.garage = {
+ isSystemUser = true;
+ group = "garage";
+ };
+ users.groups.garage = { };
+
+ systemd.services.garage = {
+ serviceConfig = {
+ DynamicUser = false;
+ User = "garage";
+ Group = "garage";
+ };
+ unitConfig.RequiresMountsFor = "/mnt/data";
+ };
+
+ services.garage = {
+ enable = true;
+ package = pkgs.garage;
+ environmentFile = config.sops.secrets."garage/env".path;
+ settings = {
+ data_dir = "/mnt/data";
+ replication_factor = 1;
+ rpc_bind_addr = "[::]:3901";
+ rpc_secret_file = config.sops.secrets."garage/rpc-secret".path;
+ s3_api = {
+ s3_region = "garage";
+ api_bind_addr = "[::]:3900";
+ };
+ s3_web = {
+ bind_addr = "[::]:3902";
+ root_domain = ".s3web.kumardamani.net";
+ index = "index.html";
+ };
+ admin = {
+ api_bind_addr = "127.0.0.1:3901";
+ admin_token_file = config.sops.secrets."garage/admin-token".path;
+ };
+ };
+ };
+
+ fileSystems = {
+ "/mnt/data" = {
+ device = "nas.bacala:/mnt/tank/customers/lab/s3";
+ fsType = "nfs";
+ };
+ };
+ };
+}
diff --git a/nix/secrets/s3.yaml b/nix/secrets/s3.yaml
new file mode 100644
index 0000000..e1b9d57
--- /dev/null
+++ b/nix/secrets/s3.yaml
@@ -0,0 +1,37 @@
+garage:
+ rpc-secret: ENC[AES256_GCM,data:VHPayq/sgNgJLnmvvz/JMas7ibQKdlcRcaRbu3QGZDWUrLlsFtGC6PkucvKQGpM1AMivYkWIJNdsaaHZkIeSSg==,iv:wcE3+8AvGwKCMyGZ5CM5dP3CT93FwtioAvZAoiCpigY=,tag:XWW991rq/xIbFDzVN45+mQ==,type:str]
+ admin-token: ENC[AES256_GCM,data:5xZaWk0Rmc9DMX7QKkT/XV9NHjg1TUMYBE2cEodmtxOFfHeSxRADzz2h7RczCZxstFkcY7Fv4czH9QQSpYbCPw==,iv:AKU9XSdWqxbQxc+d5p2Xq80yj8XKXL79o5hx2k1aS7Y=,tag:UovKSyQo45FY1ndTBerFhQ==,type:str]
+ env: ENC[AES256_GCM,data:JlDaLvOUJIbw1pepmD6lCDNkF3PVAr600dNxjMquoTFE4pEtyMq+3nlF4yNS9Z2zkhISHRhAMfFdTY6ofcza+wVd9O7+xUvBOmy4+CjBDu/agR3n,iv:GLpgj8x78Ynhvf4EyzPTQunjG0875na9MaNgyMYItg8=,tag:i58gkH/zR/6bh6pg8rmt4Q==,type:str]
+sops:
+ age:
+ - enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmN0VpV0M3dzhSeDQvREJY
+ ZzVURmdVUzUvVSt3aXM0K20wOTVnZHJYT2dFCkR2NzlIenVmODhrdjNUNEFiSW0y
+ ZXIralFxUG5JWnJCaG9KeHJ0S05ZZGMKLS0tIE9QVkFqSkM2cUFxdXFLVU4zck1y
+ SnhpcThpREhFaHJ4VG00QjZwVkYyZE0KcYefioPZg1VTX7DDrYVQBjqlw5GFfDBa
+ qcBuoxvc7btCIHPz6CkzGtYq2U6XrsIaYrT02hURmsz84cVz7hx5kg==
+ -----END AGE ENCRYPTED FILE-----
+ recipient: age12teny70e5cm3992z7atx9g9606d4a60dsl8nskzkpp234uelnctq82mqaa
+ - enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBSTBNWEhWb25SN0E1ekpu
+ eC9pVTFQUitjd2tLTldZWWxLMi9PSmRGMlFzCllWZks3RUFpRnJYUmMzUlJtNmV3
+ NmZtcks1eW90OTE1ME51RnNTL1hJaGsKLS0tIHowNVB4Mk9QdktsSGJ5RzBVa0ZN
+ OXk2K1c4MWgzcmwxc01jeFRtTXFnTkUK5Wd9to4jBHs4jbCq2/4mPoN3WYGRJwGh
+ wZfTC/E3AWHHqB9I3OdsoTu0n8EeBfDUVOVP1TRmDGfdw6JuZIfTTA==
+ -----END AGE ENCRYPTED FILE-----
+ recipient: age183q00vnssxx9ksdktsave78js2yggtcaahkf3qqh9j3yj88w54xq722xhy
+ - enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqeENWRGIxdzV6WkZKWjdk
+ aHRBcDEybGs1dEZ0ak1sZjc5Mm9zMUFRcW1JCjF5dDVhTFp4dnIveE5vM2ZQWGJn
+ RGNqdzFQemNGWjBncmQ1T1lLb3BZZWsKLS0tIFRNd003TFhIWWZkV1NQNDVoa0JI
+ QlVCbmJJd1R5eVh4MExQeE4xM0VCSjAKCXnP6FPvzz/ouAxfi9e1LmS1/XQgkhoj
+ RDrqkDaJgzoK75r1pd1PbbE5/ZUvH3PvRNIgpDqORE6Uae0HkI3wLQ==
+ -----END AGE ENCRYPTED FILE-----
+ recipient: age1nlkl8h7x33ssq3m5ka9syxurxz37y2duzhkvx3mmv23fxhetkuksqap73n
+ lastmodified: "2026-09-14T21:18:18Z"
+ mac: ENC[AES256_GCM,data:uAMlG74zT0jAfZGlUxHjRi3+PQl/0f2qynWaRAOI2NySamRRnalmdAibFXqTj89FZiNPV+8bPbEaZyRuq2RmDCkZGhDfwL/iY0QEgMQSFzuaF5PdvVvIUFixNctlIgk1K/qcDCm3XU8C1muywcMxhx+vlsyuWsDC96Q+hfjE6gM=,iv:OxFmzYX/8qDe4TzVsXtPlG6gW58N57Rt666HNY9SUl4=,tag:KglVvOj+7bQCLtcg3Euczg==,type:str]
+ unencrypted_suffix: _unencrypted
+ version: 3.13.3
diff --git a/terraform/main.tf b/terraform/main.tf
index 6d5c3e6..c4a041c 100755
--- a/terraform/main.tf
+++ b/terraform/main.tf
@@ -474,6 +474,41 @@ resource "proxmox_vm_qemu" "caldav" {
}
}
+resource "proxmox_vm_qemu" "s3" {
+ target_node = "hesh"
+ name = "s3"
+ memory = 1024
+ start_at_node_boot = true
+ boot = "order=virtio0;net0"
+ clone_id = 104
+ full_clone = true
+ scsihw = "virtio-scsi-single"
+
+ startup_shutdown {
+ order = 4
+ }
+
+ cpu {
+ cores = 1
+ }
+
+ disk {
+ type = "disk"
+ slot = "virtio0"
+ size = "10G"
+ storage = "local-lvm"
+ format = "raw"
+ }
+
+ network {
+ id = 0
+ model = "virtio"
+ bridge = "vmbr1"
+ tag = 30
+ mtu = 1420
+ }
+}
+
moved {
from = proxmox_lxc.nckumar
to = proxmox_lxc.nc_kumar