summaryrefslogtreecommitdiff
path: root/tofu
diff options
context:
space:
mode:
Diffstat (limited to 'tofu')
-rw-r--r--tofu/cloud.nix7
-rw-r--r--tofu/cloudflare/default.nix26
-rw-r--r--tofu/cloudflare/dns.nix64
-rw-r--r--tofu/cloudflare/ruleset.nix64
-rw-r--r--tofu/cloudflare/tunnels.nix11
-rw-r--r--tofu/default.nix54
-rw-r--r--tofu/deploy.nix15
-rw-r--r--tofu/tailscale/acl.nix27
-rw-r--r--tofu/tailscale/default.nix12
-rw-r--r--tofu/tailscale/devices.nix17
-rw-r--r--tofu/tailscale/dns.nix5
-rw-r--r--tofu/tailscale/tags.nix15
-rw-r--r--tofu/vars.nix11
-rw-r--r--tofu/versions.nix13
14 files changed, 341 insertions, 0 deletions
diff --git a/tofu/cloud.nix b/tofu/cloud.nix
new file mode 100644
index 0000000..5ee0113
--- /dev/null
+++ b/tofu/cloud.nix
@@ -0,0 +1,7 @@
+{
+ terraform.cloud = {
+ hostname = "app.terraform.io";
+ organization = "getchoo";
+ workspaces.name = "flake";
+ };
+}
diff --git a/tofu/cloudflare/default.nix b/tofu/cloudflare/default.nix
new file mode 100644
index 0000000..c145cb0
--- /dev/null
+++ b/tofu/cloudflare/default.nix
@@ -0,0 +1,26 @@
+{lib, ...}: {
+ imports = [
+ ./dns.nix
+ ./ruleset.nix
+ ./tunnels.nix
+ ];
+
+ terraform.required_providers.cloudflare = {
+ source = "cloudflare/cloudflare";
+ version = "~> 4";
+ };
+
+ resource = {
+ cloudflare_url_normalization_settings.incoming = {
+ scope = "incoming";
+ type = "cloudflare";
+ zone_id = lib.tfRef "var.zone_id";
+ };
+
+ cloudflare_bot_management.bots = {
+ enable_js = false;
+ fight_mode = false;
+ zone_id = lib.tfRef "var.zone_id";
+ };
+ };
+}
diff --git a/tofu/cloudflare/dns.nix b/tofu/cloudflare/dns.nix
new file mode 100644
index 0000000..3371566
--- /dev/null
+++ b/tofu/cloudflare/dns.nix
@@ -0,0 +1,64 @@
+{lib, ...}: let
+ mkRecord = name: {
+ value,
+ type,
+ ...
+ } @ args:
+ {
+ name = args.name or name;
+ zone_id = "\${var.zone_id}";
+ inherit value type;
+ proxied = true;
+ }
+ // lib.optionalAttrs (type != "TXT") {proxied = true;};
+
+ atlas_tunnel = lib.tfRef "data.cloudflare_tunnel.atlas-nginx.id" + ".cfargotunnel.com";
+in {
+ resource.cloudflare_record = builtins.mapAttrs mkRecord {
+ website = {
+ name = "@";
+ value = "website-86j.pages.dev";
+ type = "CNAME";
+ };
+
+ www = {
+ value = "mydadleft.me";
+ type = "CNAME";
+ };
+
+ api = {
+ value = atlas_tunnel;
+ type = "CNAME";
+ };
+
+ miniflux = {
+ value = atlas_tunnel;
+ type = "CNAME";
+ };
+
+ msix = {
+ value = atlas_tunnel;
+ type = "CNAME";
+ };
+
+ # prevent email spoofing
+
+ dmarc = {
+ name = "_dmarc";
+ value = "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s;";
+ type = "TXT";
+ };
+
+ domainkey = {
+ name = "*._domainkey";
+ value = "v=DKIM1; p=";
+ type = "TXT";
+ };
+
+ email = {
+ name = "mydadleft.me";
+ value = "v=spf1 -all";
+ type = "TXT";
+ };
+ };
+}
diff --git a/tofu/cloudflare/ruleset.nix b/tofu/cloudflare/ruleset.nix
new file mode 100644
index 0000000..1be98aa
--- /dev/null
+++ b/tofu/cloudflare/ruleset.nix
@@ -0,0 +1,64 @@
+{lib, ...}: {
+ resource.cloudflare_ruleset = {
+ default = {
+ kind = "zone";
+ name = "default";
+ phase = "http_config_settings";
+ zone_id = lib.tfRef "var.zone_id";
+
+ rules = [
+ {
+ action = "set_config";
+ action_parameters = {
+ automatic_https_rewrites = true;
+ email_obfuscation = true;
+ opportunistic_encryption = false;
+ };
+ description = "base redirects";
+ enabled = true;
+ expression = "true";
+ }
+ ];
+ };
+
+ redirect = {
+ kind = "zone";
+ name = "default";
+ phase = "http_request_dynamic_redirect";
+ zone_id = lib.tfRef "var.zone_id";
+
+ rules = [
+ {
+ action = "redirect";
+ action_parameters = {
+ from_value = {
+ preserve_query_string = false;
+ status_code = 301;
+ target_url = {
+ value = "https://www.youtube.com/watch?v=RvVdFXOFcjw";
+ };
+ };
+ };
+ description = "funny";
+ enabled = true;
+ expression = "(http.request.uri.path eq \"/hacks\" and http.host eq \"mydadleft.me\")";
+ }
+ {
+ action = "redirect";
+ action_parameters = {
+ from_value = {
+ preserve_query_string = false;
+ status_code = 301;
+ target_url = {
+ value = "https://www.youtube.com/watch?v=RvVdFXOFcjw";
+ };
+ };
+ };
+ description = "onlyfriends";
+ enabled = true;
+ expression = "(http.request.uri.path eq \"/onlyfriends\" and http.host eq \"mydadleft.me\")";
+ }
+ ];
+ };
+ };
+}
diff --git a/tofu/cloudflare/tunnels.nix b/tofu/cloudflare/tunnels.nix
new file mode 100644
index 0000000..bea9811
--- /dev/null
+++ b/tofu/cloudflare/tunnels.nix
@@ -0,0 +1,11 @@
+{lib, ...}: {
+ data.cloudflare_tunnel =
+ lib.genAttrs
+ [
+ "atlas-nginx"
+ ]
+ (name: {
+ inherit name;
+ account_id = lib.tfRef "var.account_id";
+ });
+}
diff --git a/tofu/default.nix b/tofu/default.nix
new file mode 100644
index 0000000..4e6a425
--- /dev/null
+++ b/tofu/default.nix
@@ -0,0 +1,54 @@
+{inputs, ...}: {
+ perSystem = {
+ lib,
+ pkgs,
+ system,
+ ...
+ }: let
+ config = inputs.terranix.lib.terranixConfiguration {
+ inherit system;
+ modules = [
+ ./cloudflare
+ ./tailscale
+ ./cloud.nix
+ ./vars.nix
+ ./versions.nix
+ ];
+ };
+ in {
+ apps =
+ lib.genAttrs ["apply" "destroy" "plan"] (fn: {
+ type = "app";
+
+ program = pkgs.writeShellApplication {
+ name = fn;
+
+ runtimeInputs = [pkgs.opentofu];
+
+ text = ''
+ config_file="config.tf.json"
+ [ -e "$config_file" ] && rm -f "$config_file"
+ cp ${config} "$config_file"
+ tofu init && tofu ${fn}
+ '';
+ };
+ })
+ // {
+ tofu-config = {
+ type = "app";
+
+ program = pkgs.writeShellApplication {
+ name = "tofu-config";
+
+ runtimeInputs = [pkgs.opentofu];
+
+ text = ''
+ config_file="config.tf.json"
+ [ -e "$config_file" ] && rm -f "$config_file"
+ cp ${config} "$config_file"
+ '';
+ };
+ };
+ };
+ };
+}
diff --git a/tofu/deploy.nix b/tofu/deploy.nix
new file mode 100644
index 0000000..3f15713
--- /dev/null
+++ b/tofu/deploy.nix
@@ -0,0 +1,15 @@
+{
+ module.deploy_nixos = rec {
+ source = "github.com/nix-community/terraform-nixos//deploy_nixos?ref=646cacb12439ca477c05315a7bfd49e9832bc4e3";
+
+ build_on_target = "true";
+ flake = true;
+ hermetic = true;
+ ssh_agent = false;
+
+ nixos_config = "atlas";
+
+ target_user = "root";
+ target_host = nixos_config;
+ };
+}
diff --git a/tofu/tailscale/acl.nix b/tofu/tailscale/acl.nix
new file mode 100644
index 0000000..46503d8
--- /dev/null
+++ b/tofu/tailscale/acl.nix
@@ -0,0 +1,27 @@
+{lib, ...}: {
+ resource = {
+ tailscale_acl.main = {
+ acl = toString (builtins.toJSON {
+ tagOwners = let
+ me = ["getchoo@github"];
+ tags = map (name: "tag:${name}") ["server" "personal" "gha"];
+ in
+ lib.genAttrs tags (_: me);
+
+ acls = let
+ mkAcl = action: src: dst: {inherit action src dst;};
+ in [
+ (mkAcl "accept" ["tag:personal"] ["*:*"])
+ (mkAcl "accept" ["tag:server" "tag:gha"] ["tag:server:*"])
+ ];
+
+ ssh = let
+ mkSshAcl = action: src: dst: users: {inherit action src dst users;};
+ in [
+ (mkSshAcl "accept" ["tag:personal"] ["tag:server" "tag:personal"] ["autogroup:nonroot" "root"])
+ (mkSshAcl "accept" ["tag:gha"] ["tag:server"] ["root"])
+ ];
+ });
+ };
+ };
+}
diff --git a/tofu/tailscale/default.nix b/tofu/tailscale/default.nix
new file mode 100644
index 0000000..2225fd5
--- /dev/null
+++ b/tofu/tailscale/default.nix
@@ -0,0 +1,12 @@
+{lib, ...}: {
+ imports = [
+ ./acl.nix
+ ./devices.nix
+ ./dns.nix
+ ./tags.nix
+ ];
+
+ provider.tailscale = {
+ tailnet = lib.tfRef "var.tailnet";
+ };
+}
diff --git a/tofu/tailscale/devices.nix b/tofu/tailscale/devices.nix
new file mode 100644
index 0000000..44ee3f1
--- /dev/null
+++ b/tofu/tailscale/devices.nix
@@ -0,0 +1,17 @@
+{lib, ...}: {
+ data.tailscale_device = let
+ toDevices = devices:
+ lib.genAttrs devices (name: {
+ name = "${name}.tailc59d6.ts.net";
+ wait_for = "60s";
+ });
+ in
+ toDevices [
+ "atlas"
+ "caroline"
+ "glados"
+ "glados-wsl"
+ "glados-windows"
+ "iphone-14"
+ ];
+}
diff --git a/tofu/tailscale/dns.nix b/tofu/tailscale/dns.nix
new file mode 100644
index 0000000..320a24b
--- /dev/null
+++ b/tofu/tailscale/dns.nix
@@ -0,0 +1,5 @@
+{
+ resource.tailscale_dns_preferences.default = {
+ magic_dns = true;
+ };
+}
diff --git a/tofu/tailscale/tags.nix b/tofu/tailscale/tags.nix
new file mode 100644
index 0000000..c519a25
--- /dev/null
+++ b/tofu/tailscale/tags.nix
@@ -0,0 +1,15 @@
+{lib, ...}: {
+ resource.tailscale_device_tags = let
+ getDeviceID = device: lib.tfRef "data.tailscale_device.${device}.id";
+ toTags = n: v: {device_id = getDeviceID n;} // v;
+
+ tags = lib.genAttrs ["server" "personal" "gha"] (n: ["tag:${n}"]);
+ in
+ builtins.mapAttrs toTags {
+ atlas.tags = tags.server;
+ caroline.tags = tags.personal;
+ glados.tags = tags.personal;
+ glados-wsl.tags = tags.personal;
+ iphone-14.tags = tags.personal;
+ };
+}
diff --git a/tofu/vars.nix b/tofu/vars.nix
new file mode 100644
index 0000000..2f640c2
--- /dev/null
+++ b/tofu/vars.nix
@@ -0,0 +1,11 @@
+{
+ variable = {
+ # cloudflare
+ zone_id.default = "53286ae07c44ed39e4b1249a2adb6d4d";
+ account_id.default = "44c47ae2d55db34c1bf2f378ea8202f1";
+ cf_domain.default = "mydadleft.me";
+
+ # tailscale
+ tailnet.default = "getchoo.github";
+ };
+}
diff --git a/tofu/versions.nix b/tofu/versions.nix
new file mode 100644
index 0000000..b563ce1
--- /dev/null
+++ b/tofu/versions.nix
@@ -0,0 +1,13 @@
+{
+ terraform.required_providers = {
+ cloudflare = {
+ source = "cloudflare/cloudflare";
+ version = "~> 4";
+ };
+
+ tailscale = {
+ source = "tailscale/tailscale";
+ version = "0.13.13";
+ };
+ };
+}