mirror of
https://git.sr.ht/~magic_rb/dotfiles
synced 2024-12-11 09:22:02 +01:00
257 lines
7.4 KiB
Nix
257 lines
7.4 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";
|
||
|
};
|
||
|
}));
|
||
|
|
||
|
}
|