mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-12-12 09:51:59 +01:00
4a29b6d8d3
Signed-off-by: magic_rb <magic_rb@redalder.org>
262 lines
7.7 KiB
Nix
262 lines
7.7 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
tflib,
|
|
...
|
|
}: let
|
|
cfg = config.prefab.nomadServer;
|
|
inherit
|
|
(lib)
|
|
mapAttrsToList
|
|
foldAttrs
|
|
mergeAttrs
|
|
fix
|
|
flip
|
|
mkOption
|
|
types
|
|
optionalString
|
|
optionalAttrs
|
|
mkMerge
|
|
;
|
|
|
|
inherit
|
|
((a: builtins.break a) tflib)
|
|
tf
|
|
;
|
|
|
|
submoduleOptions = {
|
|
datacenters = mkOption {
|
|
description = ''
|
|
'';
|
|
type = with types; listOf str;
|
|
};
|
|
|
|
encryptionKey = mkOption {
|
|
description = ''
|
|
DO NOT hardcode the secret in Nix, generate it with Terraform
|
|
and let Terraform substitute it.
|
|
'';
|
|
type = types.str;
|
|
};
|
|
|
|
paths = {
|
|
encryptionKey = mkOption {
|
|
description = ''
|
|
'';
|
|
type = types.str;
|
|
};
|
|
replicationToken = mkOption {
|
|
description = ''
|
|
'';
|
|
type = with types; nullOr str;
|
|
default = null;
|
|
};
|
|
vaultToken = mkOption {
|
|
description = ''
|
|
'';
|
|
type = types.str;
|
|
};
|
|
consulToken = mkOption {
|
|
description = ''
|
|
'';
|
|
type = types.str;
|
|
};
|
|
};
|
|
|
|
vaultKvMount = mkOption {
|
|
description = ''
|
|
'';
|
|
type = types.str;
|
|
};
|
|
};
|
|
in {
|
|
options.prefab.nomadServer = mkOption {
|
|
description = ''
|
|
'';
|
|
type = with types; attrsOf (submodule {options = submoduleOptions;});
|
|
default = {};
|
|
};
|
|
|
|
config.resource =
|
|
mkMerge
|
|
(flip mapAttrsToList cfg (hostname: value:
|
|
fix (self: {
|
|
"vault_policy"."${hostname}_nomad" = {
|
|
name = "${hostname}-nomad-server-agent";
|
|
|
|
policy = ''
|
|
path "${value.vaultKvMount}/data/${value.paths.encryptionKey}" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "${value.vaultKvMount}/data/${value.paths.vaultToken}" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "${value.vaultKvMount}/data/${value.paths.consulToken}" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
${optionalString (value.paths.replicationToken != null) ''
|
|
path "${value.vaultKvMount}/data/${value.paths.replicationToken}" {
|
|
capabilities = ["read"]
|
|
}
|
|
''}
|
|
'';
|
|
};
|
|
|
|
"vault_kv_secret_v2"."${hostname}_nomad_encryption_key" = {
|
|
mount = value.vaultKvMount;
|
|
name = value.paths.encryptionKey;
|
|
delete_all_versions = true;
|
|
data_json = builtins.toJSON {
|
|
key = value.encryptionKey;
|
|
};
|
|
};
|
|
|
|
"consul_acl_policy"."${hostname}_nomad_server" = {
|
|
name = "${hostname}_nomad_server";
|
|
rules = ''
|
|
agent_prefix "" {
|
|
policy = "read"
|
|
}
|
|
|
|
node_prefix "" {
|
|
policy = "read"
|
|
}
|
|
|
|
service_prefix "" {
|
|
policy = "write"
|
|
}
|
|
|
|
acl = "write"
|
|
'';
|
|
};
|
|
|
|
"consul_acl_token"."${hostname}_nomad_server" = {
|
|
description = "Consul token for nomad_server on ${hostname}";
|
|
policies = [
|
|
(tf "consul_acl_policy.${hostname}_nomad_server.name")
|
|
];
|
|
local = false;
|
|
};
|
|
|
|
"vault_kv_secret_v2"."${hostname}_nomad_server_consul" = {
|
|
mount = value.vaultKvMount;
|
|
name = value.paths.consulToken;
|
|
delete_all_versions = true;
|
|
data_json = builtins.toJSON {
|
|
secret = tf "data.consul_acl_token_secret_id.${hostname}_nomad_server.secret_id";
|
|
accessor = tf "consul_acl_token.${hostname}_nomad_server.accessor_id";
|
|
};
|
|
};
|
|
|
|
"vault_policy"."${hostname}_nomad_server" = {
|
|
name = "${hostname}-nomad-server";
|
|
|
|
policy = ''
|
|
# Allow creating tokens under "nomad-cluster" token role. The token role name
|
|
# should be updated if "nomad-cluster" is not used.
|
|
path "auth/token/create/nomad-cluster" {
|
|
capabilities = ["update"]
|
|
}
|
|
|
|
# Allow looking up "nomad-cluster" token role. The token role name should be
|
|
# updated if "nomad-cluster" is not used.
|
|
path "auth/token/roles/nomad-cluster" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
# Allow looking up the token passed to Nomad to validate the token has the
|
|
# proper capabilities. This is provided by the "default" policy.
|
|
path "auth/token/lookup-self" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
# Allow looking up incoming tokens to validate they have permissions to access
|
|
# the tokens they are requesting. This is only required if
|
|
# `allow_unauthenticated` is set to false.
|
|
path "auth/token/lookup" {
|
|
capabilities = ["update"]
|
|
}
|
|
|
|
# Allow revoking tokens that should no longer exist. This allows revoking
|
|
# tokens for dead tasks.
|
|
path "auth/token/revoke-accessor" {
|
|
capabilities = ["update"]
|
|
}
|
|
|
|
# Allow checking the capabilities of our own token. This is used to validate the
|
|
# token upon startup. Note this requires update permissions because the Vault API
|
|
# is a POST
|
|
path "sys/capabilities-self" {
|
|
capabilities = ["update"]
|
|
}
|
|
|
|
# Allow our own token to be renewed.
|
|
path "auth/token/renew-self" {
|
|
capabilities = ["update"]
|
|
}
|
|
'';
|
|
};
|
|
|
|
"vault_token_auth_backend_role"."${hostname}_nomad_server" = {
|
|
role_name = "${hostname}_nomad_server";
|
|
allowed_policies = [
|
|
(tf "vault_policy.${hostname}_nomad_server.name")
|
|
];
|
|
orphan = true;
|
|
renewable = true;
|
|
};
|
|
|
|
"vault_token"."${hostname}_nomad_server" = {
|
|
policies = [
|
|
(tf "vault_policy.${hostname}_nomad_server.name")
|
|
];
|
|
renewable = true;
|
|
ttl = "24h";
|
|
explicit_max_ttl = 0;
|
|
role_name = tf "vault_token_auth_backend_role.${hostname}_nomad_server.role_name";
|
|
display_name = "${hostname}-nomad-server-Vault-token";
|
|
};
|
|
|
|
"vault_kv_secret_v2"."${hostname}_nomad_server_vault" = {
|
|
mount = value.vaultKvMount;
|
|
name = value.paths.vaultToken;
|
|
delete_all_versions = true;
|
|
data_json = builtins.toJSON {
|
|
secret = tf "vault_token.${hostname}_nomad_server.client_token";
|
|
};
|
|
};
|
|
}))
|
|
++ (flip mapAttrsToList cfg (
|
|
hostname: value: (
|
|
optionalAttrs (value.paths.replicationToken != null)
|
|
{
|
|
"nomad_acl_token"."${hostname}_replication" = {
|
|
name = "${hostname} replication token";
|
|
type = "management";
|
|
};
|
|
|
|
"vault_kv_secret_v2"."${hostname}_nomad_replication" = {
|
|
mount = value.vaultKvMount;
|
|
name = value.paths.replicationToken;
|
|
delete_all_versions = true;
|
|
data_json = builtins.toJSON {
|
|
secret = tf "nomad_acl_token.${hostname}_replication.secret_id";
|
|
accessor = tf "nomad_acl_token.${hostname}_replication.id";
|
|
};
|
|
};
|
|
}
|
|
)
|
|
)));
|
|
|
|
config.data =
|
|
mkMerge
|
|
(flip mapAttrsToList cfg (hostname: value: {
|
|
"consul_acl_token_secret_id"."${hostname}_nomad_server" = {
|
|
accessor_id = tf "consul_acl_token.${hostname}_nomad_server.id";
|
|
};
|
|
}));
|
|
}
|