dotfiles/terranix/modules/consul_agent.nix

238 lines
6.3 KiB
Nix
Raw Normal View History

{
config,
pkgs,
lib,
tflib,
...
}: let
cfg = config.prefab.consulAgent;
inherit
(lib)
mkOption
types
mapAttrsToList
fix
optionalString
optionalAttrs
singleton
mkMerge
flip
;
inherit
(tflib)
tf
;
submoduleOptions = {
datacenter = mkOption {
description = ''
'';
type = types.str;
};
replicationDatacenters = 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;
};
anonymousToken = mkOption {
description = ''
DO NOT hardcode the secret in Nix, generate it with Terraform
and let Terraform substitute it.
'';
type = types.submodule {
options.secret = mkOption {
description = '''';
type = types.str;
};
options.accessor = mkOption {
description = '''';
type = types.str;
};
};
};
paths = {
encryptionKey = mkOption {
description = ''
'';
type = types.str;
};
agentToken = mkOption {
description = ''
'';
type = types.str;
};
replicationToken = mkOption {
description = ''
'';
type = with types; nullOr str;
default = null;
};
anonymousToken = mkOption {
description = ''
'';
type = types.str;
};
};
vaultKvMount = mkOption {
description = ''
'';
type = types.str;
};
};
in {
options.prefab.consulAgent = mkOption {
description = ''
'';
type = with types; attrsOf (submodule {options = submoduleOptions;});
default = {};
};
config.resource =
mkMerge
(flip mapAttrsToList cfg (hostname: value:
fix (self: {
"consul_acl_policy"."${hostname}_agent" = {
name = "${hostname}-consul-agent";
rules = ''
node "${hostname}" {
policy = "write"
}
agent "${hostname}" {
policy = "write"
}
service_prefix "" {
policy = "write"
}
'';
};
"consul_acl_token"."${hostname}_consul_agent" = {
description = "Consul agent token on ${hostname}";
node_identities = singleton {
node_name = hostname;
datacenter = value.datacenter;
};
local = false;
};
"vault_kv_secret_v2"."${hostname}_consul_encryption_key" = {
mount = value.vaultKvMount;
name = value.paths.encryptionKey;
delete_all_versions = true;
data_json = builtins.toJSON {
key = value.encryptionKey;
};
};
"vault_kv_secret_v2"."${hostname}_consul_anonymous_token" = {
mount = value.vaultKvMount;
name = value.paths.anonymousToken;
delete_all_versions = true;
data_json = builtins.toJSON {
secret = value.anonymousToken.secret;
accessor = value.anonymousToken.accessor;
};
};
"vault_kv_secret_v2"."${hostname}_consul_agent" = {
mount = value.vaultKvMount;
name = value.paths.agentToken;
delete_all_versions = true;
data_json = builtins.toJSON {
secret = tf "data.consul_acl_token_secret_id.${hostname}_consul_agent.secret_id";
accessor = tf "consul_acl_token.${hostname}_consul_agent.id";
};
};
"vault_policy"."${hostname}_consul" = {
name = "${hostname}_consul_agent";
policy = ''
path "${value.vaultKvMount}/data/${value.paths.encryptionKey}" {
capabilities = ["read"]
}
path "${value.vaultKvMount}/data/${value.paths.agentToken}" {
capabilities = ["read"]
}
${optionalString (value.paths.replicationToken != null) ''
path "${value.vaultKvMount}/data/${value.paths.replicationToken}" {
capabilities = ["read"]
}
''}
path "${value.vaultKvMount}/data/${value.paths.anonymousToken}" {
capabilities = ["read"]
}
'';
};
}))
++ (flip mapAttrsToList cfg (
hostname: value: (optionalAttrs (value.paths.replicationToken != null) {
"consul_acl_policy"."${hostname}_replication" = {
name = "${hostname}_consul_replication";
datacenters = value.replicationDatacenters;
rules = ''
acl = "write"
operator = "write"
service_prefix "" {
policy = "read"
intentions = "read"
}
'';
};
"consul_acl_token"."${hostname}_consul_replication" = {
description = "Consul replication token on ${hostname}";
policies = [
(tf "consul_acl_policy.${hostname}_replication.name")
];
local = false;
};
"vault_kv_secret_v2"."${hostname}_consul_replication" = {
mount = value.vaultKvMount;
name = value.paths.replicationToken;
delete_all_versions = true;
data_json = builtins.toJSON {
secret = tf "data.consul_acl_token_secret_id.${hostname}_consul_replication.secret_id";
accessor = tf "consul_acl_token.${hostname}_consul_replication.id";
};
};
})
)));
config.data =
mkMerge
(flip mapAttrsToList cfg (
hostname: value: {
"consul_acl_token_secret_id"."${hostname}_consul_agent" = {
accessor_id = tf "consul_acl_token.${hostname}_consul_agent.id";
};
}
)
++ flip mapAttrsToList cfg (
hostname: value: (optionalAttrs (value.paths.replicationToken != null) {
"consul_acl_token_secret_id"."${hostname}_consul_replication" = {
accessor_id = tf "consul_acl_token.${hostname}_consul_replication.id";
};
})
));
}