ops/vault/cfg: add acme-ca
This commit is contained in:
parent
fb7e18260a
commit
148e071c21
3 changed files with 139 additions and 0 deletions
48
ops/vault/cfg/acme-ca.nix
Normal file
48
ops/vault/cfg/acme-ca.nix
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{ ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./module-acme-ca.nix ];
|
||||||
|
|
||||||
|
my.acme.accounts = let
|
||||||
|
base = {
|
||||||
|
key_type = "EC256";
|
||||||
|
ignore_dns_propagation = true;
|
||||||
|
};
|
||||||
|
letsencrypt = base // {
|
||||||
|
contact = "letsencrypt@lukegb.com";
|
||||||
|
terms_of_service_agreed = true;
|
||||||
|
};
|
||||||
|
letsencrypt-staging = letsencrypt // {
|
||||||
|
server_url = "https://acme-staging-v02.api.letsencrypt.org/directory";
|
||||||
|
};
|
||||||
|
letsencrypt-prod = letsencrypt // {
|
||||||
|
server_url = "https://acme-v02.api.letsencrypt.org/directory";
|
||||||
|
};
|
||||||
|
|
||||||
|
cloudflare = t: t // {
|
||||||
|
provider = "cloudflare";
|
||||||
|
provider_configuration.CLOUDFLARE_DNS_API_TOKEN = "\${data.vault_generic_secret.misc.data[\"cloudflareToken\"]}";
|
||||||
|
};
|
||||||
|
gcloud-as205479 = t: t // {
|
||||||
|
provider = "gcloud";
|
||||||
|
provider_configuration.GCE_PROJECT = "as205479-177317";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
letsencrypt-cloudflare = cloudflare letsencrypt-prod;
|
||||||
|
letsencrypt-staging-cloudflare = cloudflare letsencrypt-staging;
|
||||||
|
|
||||||
|
letsencrypt-gcloud-as205479 = gcloud-as205479 letsencrypt-prod;
|
||||||
|
letsencrypt-staging-gcloud-as205479 = gcloud-as205479 letsencrypt-staging;
|
||||||
|
};
|
||||||
|
|
||||||
|
my.acme.roles = let
|
||||||
|
cloudflareDomains = [ "lukegb.com" "bfob.gg" "lukegb.dev" "lukegb.tech" "lukegb.xyz" "zxcvbnm.ninja" ];
|
||||||
|
gcloudDomains = [ "as205479.net" "event.lukegb.tech" "tech.lukegb.tech" ];
|
||||||
|
in {
|
||||||
|
letsencrypt-cloudflare.allowed_domains = cloudflareDomains;
|
||||||
|
letsencrypt-staging-cloudflare.allowed_domains = cloudflareDomains;
|
||||||
|
|
||||||
|
letsencrypt-gcloud-as205479.allowed_domains = gcloudDomains;
|
||||||
|
letsencrypt-staging-gcloud-as205479.allowed_domains = gcloudDomains;
|
||||||
|
};
|
||||||
|
}
|
|
@ -12,6 +12,8 @@
|
||||||
./ssh-ca-server.nix
|
./ssh-ca-server.nix
|
||||||
|
|
||||||
./servers.nix
|
./servers.nix
|
||||||
|
|
||||||
|
./acme-ca.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
terraform = {
|
terraform = {
|
||||||
|
|
89
ops/vault/cfg/module-acme-ca.nix
Normal file
89
ops/vault/cfg/module-acme-ca.nix
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (lib) mapAttrs' nameValuePair mkMerge mkOption mkIf any types;
|
||||||
|
|
||||||
|
hackterpolate = s: let
|
||||||
|
parts = builtins.split "(\\\$\\{[^}]+})" s;
|
||||||
|
unescape = s: builtins.fromJSON ''"${s}"'';
|
||||||
|
strParts = lib.imap1 (i: v: if lib.mod i 2 == 0 then unescape (builtins.elemAt v 0) else v) parts;
|
||||||
|
in lib.concatStrings strParts;
|
||||||
|
|
||||||
|
cfg = config.my.acme;
|
||||||
|
accountsEndpoints = mapAttrs' (name: value: nameValuePair "acme_account_${name}" {
|
||||||
|
depends_on = [ "vault_mount.acme" ];
|
||||||
|
path = "acme/accounts/${name}";
|
||||||
|
disable_read = true;
|
||||||
|
|
||||||
|
data_json = hackterpolate (builtins.toJSON value);
|
||||||
|
}) cfg.accounts;
|
||||||
|
rolesEndpoints = mapAttrs' (name: value: nameValuePair "acme_role_${name}" {
|
||||||
|
depends_on = [ "vault_mount.acme" ];
|
||||||
|
path = "acme/roles/${name}";
|
||||||
|
disable_read = true;
|
||||||
|
|
||||||
|
data_json = hackterpolate (builtins.toJSON value);
|
||||||
|
}) cfg.roles;
|
||||||
|
|
||||||
|
mkMergeIf = things: mkIf (any (t: t != { }) things) (mkMerge things);
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
my.acme.mountPoint = mkOption {
|
||||||
|
default = "acme";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
my.acme.accounts = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = (pkgs.formats.json { }).type;
|
||||||
|
};
|
||||||
|
|
||||||
|
my.acme.roles = mkOption {
|
||||||
|
default = {};
|
||||||
|
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||||
|
options = {
|
||||||
|
account = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
allow_bare_domains = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
allow_subdomains = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
allowed_domains = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
};
|
||||||
|
|
||||||
|
cache_for_ratio = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 20;
|
||||||
|
};
|
||||||
|
|
||||||
|
disable_cache = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
resource.vault_mount.acme = {
|
||||||
|
path = config.my.acme.mountPoint;
|
||||||
|
type = "acme";
|
||||||
|
};
|
||||||
|
|
||||||
|
resource.vault_generic_endpoint = mkMergeIf [
|
||||||
|
accountsEndpoints
|
||||||
|
rolesEndpoints
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue