Support multiple dns zones per host
This commit is contained in:
parent
46375018e0
commit
d842025c81
12 changed files with 301 additions and 88 deletions
|
@ -160,7 +160,6 @@ in
|
|||
enable = true;
|
||||
dns = {
|
||||
enable = true;
|
||||
zone_name = tldFromFqdn fqdn;
|
||||
aRecords = lib.lists.map (d: {
|
||||
fqdn = d;
|
||||
content = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
||||
|
|
|
@ -103,6 +103,18 @@ in
|
|||
default = false;
|
||||
};
|
||||
};
|
||||
network = {
|
||||
router = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "monitoring.kaareskovgaard.net";
|
||||
description = "Set to null to create new router. Will make routing to monitoring instance unroutable over ipv6 (which is the only one that has ipv6 record)";
|
||||
};
|
||||
ipv4Cidr = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "172.24.0.0/24";
|
||||
description = "Set to unique cidr for non monitoring instances";
|
||||
};
|
||||
};
|
||||
extraFirewallRules = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
description = "Extra firewall rules added to the instance";
|
||||
|
@ -136,6 +148,8 @@ in
|
|||
ssh_public_key = cfg.ssh_key;
|
||||
firewall_rules = firewallRules;
|
||||
user_data = builtins.toJSON provisioningUserData;
|
||||
ip4_cidr = cfg.network.ipv4Cidr;
|
||||
router = cfg.network.router;
|
||||
};
|
||||
khscodes.unifi.enable = true;
|
||||
khscodes.unifi.static_route.compute = {
|
||||
|
@ -148,7 +162,6 @@ in
|
|||
enable = true;
|
||||
dns = {
|
||||
enable = true;
|
||||
zone_name = tldFromFqdn fqdn;
|
||||
aRecords = lib.mkIf cfg.dns.mapIpv4Address (
|
||||
lib.lists.map (d: {
|
||||
fqdn = d;
|
||||
|
|
|
@ -105,11 +105,22 @@ let
|
|||
description = "Extra configuration to inject into the generated nginx config";
|
||||
default = '''';
|
||||
};
|
||||
rateLimit.enable = lib.mkOption {
|
||||
rateLimit = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Enable rate limiting";
|
||||
};
|
||||
burst = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 20;
|
||||
};
|
||||
};
|
||||
fail2ban.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Enable fail2ban rate limiting";
|
||||
};
|
||||
locations = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.khscodes.mkSubmodule {
|
||||
|
@ -211,6 +222,10 @@ in
|
|||
};
|
||||
groups.${config.services.prometheus.exporters.nginxlog.user} = { };
|
||||
};
|
||||
systemd.services.fail2ban = {
|
||||
# fail2ban fails starting if the nginx log files don't exist
|
||||
after = [ "nginx.service" ];
|
||||
};
|
||||
services.fail2ban.jails = {
|
||||
nginx-botsearch = {
|
||||
settings = {
|
||||
|
@ -271,14 +286,9 @@ in
|
|||
commonHttpConfig = ''
|
||||
${logfmt}
|
||||
access_log /var/log/nginx/access.logfmt.log logfmt;
|
||||
|
||||
log_format fail2ban '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
log_format nginx_exporter '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" $upstream_response_time';
|
||||
access_log /var/log/nginx/access.fail2ban.log fail2ban;
|
||||
'';
|
||||
appendHttpConfig = ''
|
||||
limit_req_zone $binary_remote_addr zone=nobots:10m rate=20r/s;
|
||||
|
@ -314,12 +324,11 @@ in
|
|||
else
|
||||
'''';
|
||||
reqLimit = lib.strings.optionalString value.rateLimit.enable ''
|
||||
limit_req zone=nobots burst=20 nodelay;
|
||||
limit_req zone=nobots burst=${toString value.rateLimit.burst} nodelay;
|
||||
'';
|
||||
extraConfig = ''
|
||||
${mtls}
|
||||
${reqLimit}
|
||||
access_log /var/log/nginx/access.fail2ban.log fail2ban;
|
||||
access_log /var/log/nginx/access.logfmt.log logfmt;
|
||||
access_log /var/log/nginx/access.${name}.log nginx_exporter;
|
||||
${value.extraConfig}
|
||||
|
|
|
@ -12,6 +12,15 @@ let
|
|||
"@"
|
||||
else
|
||||
fqdn;
|
||||
tldFromFqdn =
|
||||
fqdn:
|
||||
let
|
||||
split = lib.strings.splitString "." fqdn;
|
||||
in
|
||||
if lib.lists.length split < 3 then
|
||||
fqdn
|
||||
else
|
||||
lib.strings.removePrefix "${builtins.head split}." fqdn;
|
||||
dnsARecordModule = lib.khscodes.mkSubmodule {
|
||||
description = "Module for defining dns A/AAAA record";
|
||||
options = {
|
||||
|
@ -77,14 +86,11 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
imports = [ ./dns_zone.nix ];
|
||||
options.khscodes.cloudflare = {
|
||||
enable = lib.mkEnableOption "Enables khscodes cloudflare terranix integration";
|
||||
dns = {
|
||||
enable = lib.mkEnableOption "Enables setting up DNS records";
|
||||
zone_name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The dns zone name (TLD)";
|
||||
};
|
||||
aRecords = lib.mkOption {
|
||||
type = lib.types.listOf dnsARecordModule;
|
||||
default = [ ];
|
||||
|
@ -119,51 +125,77 @@ in
|
|||
version = "~> 4.0";
|
||||
};
|
||||
|
||||
data.cloudflare_zone.dns_zone = lib.attrsets.optionalAttrs cfg.dns.enable {
|
||||
name = cfg.dns.zone_name;
|
||||
};
|
||||
khscodes.cloudflare.data.dns_zones = lib.lists.unique (
|
||||
lib.lists.map (a: tldFromFqdn (a.fqdn)) (
|
||||
cfg.dns.aRecords ++ cfg.dns.aaaaRecords ++ cfg.dns.txtRecords ++ cfg.dns.mxRecords
|
||||
)
|
||||
);
|
||||
resource.cloudflare_record = lib.attrsets.optionalAttrs cfg.dns.enable (
|
||||
lib.listToAttrs (
|
||||
(lib.lists.map (record: {
|
||||
(lib.lists.map (
|
||||
record:
|
||||
let
|
||||
zoneName = tldFromFqdn record.fqdn;
|
||||
in
|
||||
{
|
||||
name = "${lib.khscodes.sanitize-terraform-name record.fqdn}_a";
|
||||
value = {
|
||||
inherit (record) content ttl proxied;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
name = nameFromFQDNAndZone record.fqdn zoneName;
|
||||
type = "A";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
comment = "app=${cfg.dns.zone_name}";
|
||||
zone_id = "\${ data.cloudflare_zone.${lib.khscodes.sanitize-terraform-name zoneName}.id }";
|
||||
comment = "app=${zoneName}";
|
||||
};
|
||||
}) cfg.dns.aRecords)
|
||||
++ (lib.lists.map (record: {
|
||||
}
|
||||
) cfg.dns.aRecords)
|
||||
++ (lib.lists.map (
|
||||
record:
|
||||
let
|
||||
zoneName = tldFromFqdn record.fqdn;
|
||||
in
|
||||
{
|
||||
name = "${lib.khscodes.sanitize-terraform-name record.fqdn}_aaaa";
|
||||
value = {
|
||||
inherit (record) content ttl proxied;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
name = nameFromFQDNAndZone record.fqdn zoneName;
|
||||
type = "AAAA";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
comment = "app=${cfg.dns.zone_name}";
|
||||
zone_id = "\${ data.cloudflare_zone.${lib.khscodes.sanitize-terraform-name zoneName}.id }";
|
||||
comment = "app=${zoneName}";
|
||||
};
|
||||
}) cfg.dns.aaaaRecords)
|
||||
++ (lib.lists.map (record: {
|
||||
}
|
||||
) cfg.dns.aaaaRecords)
|
||||
++ (lib.lists.map (
|
||||
record:
|
||||
let
|
||||
zoneName = tldFromFqdn record.fqdn;
|
||||
in
|
||||
{
|
||||
name = "${lib.khscodes.sanitize-terraform-name record.fqdn}_txt";
|
||||
value = {
|
||||
inherit (record) content ttl;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
name = nameFromFQDNAndZone record.fqdn zoneName;
|
||||
type = "TXT";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
comment = "app=${cfg.dns.zone_name}";
|
||||
zone_id = "\${ data.cloudflare_zone.${lib.khscodes.sanitize-terraform-name zoneName}.id }";
|
||||
comment = "app=${zoneName}";
|
||||
};
|
||||
}) cfg.dns.txtRecords)
|
||||
++ (lib.lists.map (record: {
|
||||
}
|
||||
) cfg.dns.txtRecords)
|
||||
++ (lib.lists.map (
|
||||
record:
|
||||
let
|
||||
zoneName = tldFromFqdn record.fqdn;
|
||||
in
|
||||
{
|
||||
name = "${lib.khscodes.sanitize-terraform-name record.fqdn}_mx";
|
||||
value = {
|
||||
inherit (record) content priority;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
name = nameFromFQDNAndZone record.fqdn zoneName;
|
||||
type = "MX";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
comment = "app=${cfg.dns.zone_name}";
|
||||
zone_id = "\${ data.cloudflare_zone.${lib.khscodes.sanitize-terraform-name zoneName}.id }";
|
||||
comment = "app=${zoneName}";
|
||||
};
|
||||
}) cfg.dns.mxRecords)
|
||||
}
|
||||
) cfg.dns.mxRecords)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
22
nix/modules/terranix/cloudflare/dns_zone.nix
Normal file
22
nix/modules/terranix/cloudflare/dns_zone.nix
Normal file
|
@ -0,0 +1,22 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.khscodes.cloudflare;
|
||||
in
|
||||
{
|
||||
options.khscodes.cloudflare = {
|
||||
data.dns_zones = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable {
|
||||
data.cloudflare_zone = lib.listToAttrs (
|
||||
lib.lists.map (zone: {
|
||||
name = lib.khscodes.sanitize-terraform-name zone;
|
||||
value = {
|
||||
name = zone;
|
||||
};
|
||||
}) (lib.lists.unique cfg.data.dns_zones)
|
||||
);
|
||||
};
|
||||
}
|
|
@ -74,7 +74,7 @@ let
|
|||
};
|
||||
ip4_cidr = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "IPv4 cidr of the private virtual network";
|
||||
description = "IPv4 cidr of the private virtual network. Must override when using a named router";
|
||||
default = "172.24.0.0/24";
|
||||
};
|
||||
ip4_dns_nameservers = lib.mkOption {
|
||||
|
@ -111,6 +111,11 @@ let
|
|||
"2606:4700:4700::1001"
|
||||
];
|
||||
};
|
||||
router = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "monitoring.kaareskovgaard.net";
|
||||
description = "Name of the router to attach to. If null will create a new router";
|
||||
};
|
||||
tags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
};
|
||||
|
@ -226,20 +231,45 @@ in
|
|||
) cfg.compute_instance;
|
||||
|
||||
# router
|
||||
resource.openstack_networking_router_v2 = lib.mapAttrs' (
|
||||
resource.openstack_networking_router_v2 = lib.filterAttrs (name: value: value != null) (
|
||||
lib.mapAttrs' (
|
||||
name: value:
|
||||
let
|
||||
sanitizedName = lib.khscodes.sanitize-terraform-name name;
|
||||
in
|
||||
{
|
||||
name = sanitizedName;
|
||||
value = {
|
||||
value =
|
||||
if value.router == null then
|
||||
{
|
||||
name = value.name;
|
||||
external_network_id = "\${ data.openstack_networking_network_v2.provider.id }";
|
||||
tags = value.tags;
|
||||
};
|
||||
}
|
||||
) cfg.compute_instance;
|
||||
else
|
||||
null;
|
||||
}
|
||||
) cfg.compute_instance
|
||||
);
|
||||
|
||||
data.openstack_networking_router_v2 = lib.filterAttrs (name: value: value != null) (
|
||||
lib.mapAttrs' (
|
||||
name: value:
|
||||
let
|
||||
sanitizedName = lib.khscodes.sanitize-terraform-name name;
|
||||
in
|
||||
{
|
||||
name = sanitizedName;
|
||||
value =
|
||||
if value.router != null then
|
||||
{
|
||||
name = value.router;
|
||||
}
|
||||
else
|
||||
null;
|
||||
}
|
||||
) cfg.compute_instance
|
||||
);
|
||||
|
||||
# network
|
||||
resource.openstack_networking_network_v2 = lib.mapAttrs' (
|
||||
|
@ -305,7 +335,9 @@ in
|
|||
{
|
||||
name = "${sanitizedName}_ip4";
|
||||
value = {
|
||||
router_id = "\${ openstack_networking_router_v2.${sanitizedName}.id }";
|
||||
router_id = "\${ ${
|
||||
lib.strings.optionalString (value.router != null) "data."
|
||||
} openstack_networking_router_v2.${sanitizedName}.id }";
|
||||
subnet_id = "\${ openstack_networking_subnet_v2.${sanitizedName}_ip4.id }";
|
||||
};
|
||||
}
|
||||
|
@ -318,7 +350,9 @@ in
|
|||
{
|
||||
name = "${sanitizedName}_ip6";
|
||||
value = {
|
||||
router_id = "\${ openstack_networking_router_v2.${sanitizedName}.id }";
|
||||
router_id = "\${ ${
|
||||
lib.strings.optionalString (value.router != null) "data."
|
||||
}openstack_networking_router_v2.${sanitizedName}.id }";
|
||||
subnet_id = "\${ openstack_networking_subnet_v2.${sanitizedName}_ip6.id }";
|
||||
};
|
||||
}
|
||||
|
|
|
@ -45,8 +45,10 @@ in
|
|||
{
|
||||
id = "\${ openstack_compute_instance_v2.${sanitizedName}.id }";
|
||||
ipv4_address = "\${ openstack_networking_floatingip_v2.${sanitizedName}.address }";
|
||||
ipv6_address = "\${ data.openstack_networking_port_v2.${sanitizedName}.all_fixed_ips[1] }";
|
||||
ipv6_external_gateway = "\${ [for ip in openstack_networking_router_v2.${sanitizedName}.external_fixed_ip : ip.ip_address if replace(ip.ip_address, \":\", \"\") != ip.ip_address][0] }";
|
||||
ipv6_address = "\${ [for ip in data.openstack_networking_port_v2.${sanitizedName}.all_fixed_ips : ip if replace(ip, \":\", \"\") != ip][0] }";
|
||||
ipv6_external_gateway = "\${ [for ip in ${
|
||||
lib.strings.optionalString (value.router != null) "data."
|
||||
}openstack_networking_router_v2.${sanitizedName}.external_fixed_ip : ip.ip_address if replace(ip.ip_address, \":\", \"\") != ip.ip_address][0] }";
|
||||
ipv6_cidr = "\${ openstack_networking_subnet_v2.${sanitizedName}_ip6.cidr }";
|
||||
}
|
||||
)
|
||||
|
|
|
@ -77,7 +77,7 @@ in
|
|||
|
||||
resource.cloudflare_record.dkim_rsa = {
|
||||
name = "snm_rsa._domainkey";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
zone_id = "\${ data.cloudflare_zone.kas_codes.id }";
|
||||
type = "TXT";
|
||||
content = ''"v=DKIM1;k=rsa;p=${dkimPublicKey "tls_private_key.dkim_rsa"}"'';
|
||||
comment = "app=kas.codes";
|
||||
|
@ -86,7 +86,7 @@ in
|
|||
|
||||
resource.cloudflare_record.dkim_ed25519 = {
|
||||
name = "snm_ed25519._domainkey";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
zone_id = "\${ data.cloudflare_zone.kas_codes.id }";
|
||||
type = "TXT";
|
||||
content = ''"v=DKIM1;k=ed25519;p=${dkimPublicKey "tls_private_key.dkim_ed25519"}"'';
|
||||
comment = "app=kas.codes";
|
||||
|
@ -95,7 +95,7 @@ in
|
|||
|
||||
resource.cloudflare_record.spf = {
|
||||
name = "@";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
zone_id = "\${ data.cloudflare_zone.kas_codes.id }";
|
||||
type = "TXT";
|
||||
content = ''"v=spf1 ip4:${config.khscodes.hcloud.output.server.compute.ipv4_address} ip6:${config.khscodes.hcloud.output.server.compute.ipv6_address} -all"'';
|
||||
comment = "app=kas.codes";
|
||||
|
@ -103,7 +103,7 @@ in
|
|||
};
|
||||
resource.cloudflare_record.dmarc = {
|
||||
name = "_dmarc";
|
||||
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||
zone_id = "\${ data.cloudflare_zone.kas_codes.id }";
|
||||
type = "TXT";
|
||||
content = ''"v=DMARC1; p=reject; adkim=s; aspf=s;"'';
|
||||
comment = "app=kas.codes";
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
"${inputs.self}/nix/profiles/nixos/hetzner-server.nix"
|
||||
];
|
||||
khscodes.infrastructure.hetzner-instance = {
|
||||
enable = true;
|
||||
mapRdns = true;
|
||||
server_type = "cax11";
|
||||
};
|
||||
khscodes.networking.fqdn = "mail.kaareskovgaard.net";
|
||||
system.stateVersion = "25.05";
|
||||
}
|
|
@ -7,10 +7,16 @@
|
|||
let
|
||||
domain = "login.kaareskovgaard.net";
|
||||
bootstrapping = config.khscodes."security.kaareskovgaard.net".bootstrap.enable;
|
||||
openbaoAppBasicSecretFile = "/var/lib/vault-agent/kanidm/openbao_basic_secret";
|
||||
openbaoCliAppBasicSecretFile = "/var/lib/vault-agent/kanidm/openbao_cli_basic_secret";
|
||||
monitoringAppBasicSecretFile = "/var/lib/vault-agent/kanidm/monitoring_basic_secret";
|
||||
forgejoAppBasicSecretFile = "/var/lib/vault-agent/kanidm/forgejo_basic_secret";
|
||||
openbaoAppBasicSecretFile = "/run/kanidm/openbao_basic_secret";
|
||||
openbaoCliAppBasicSecretFile = "/run/kanidm/openbao_cli_basic_secret";
|
||||
monitoringAppBasicSecretFile = "/run/kanidm/monitoring_basic_secret";
|
||||
forgejoAppBasicSecretFile = "/run/kanidm/forgejo_basic_secret";
|
||||
secretFiles = [
|
||||
openbaoAppBasicSecretFile
|
||||
openbaoCliAppBasicSecretFile
|
||||
monitoringAppBasicSecretFile
|
||||
forgejoAppBasicSecretFile
|
||||
];
|
||||
openbaoDomain = config.khscodes.infrastructure.openbao.domain;
|
||||
openbaoAllowedRedirectUrls = [
|
||||
"https://${openbaoDomain}/ui/vault/auth/kanidm/oidc/callback"
|
||||
|
@ -183,9 +189,7 @@ in
|
|||
# Don't add dependencies from bootstrapping when not bootstrapping.
|
||||
systemd.services.kanidm = lib.mkIf (!bootstrapping) {
|
||||
unitConfig = {
|
||||
ConditionPathExists = [
|
||||
openbaoAppBasicSecretFile
|
||||
];
|
||||
ConditionPathExists = secretFiles;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
79
nix/systems/x86_64-linux/chat.kaareskovgaard.net/default.nix
Normal file
79
nix/systems/x86_64-linux/chat.kaareskovgaard.net/default.nix
Normal file
|
@ -0,0 +1,79 @@
|
|||
{ inputs, config, ... }:
|
||||
let
|
||||
mattermost = config.services.mattermost;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
"${inputs.self}/nix/profiles/nixos/khs-openstack-server.nix"
|
||||
];
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "mattermost" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "mattermost";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
services.mattermost = {
|
||||
enable = true;
|
||||
siteName = "chat.kaareskovgaard.net";
|
||||
siteUrl = "https://chat.kaareskovgaard.net";
|
||||
database = {
|
||||
create = false;
|
||||
};
|
||||
telemetry = {
|
||||
enableSecurityAlerts = false;
|
||||
enableDiagnostics = false;
|
||||
};
|
||||
settings = {
|
||||
EmailSettings = {
|
||||
EnableSignUpWithEmail = false;
|
||||
EnableSignInWithEmail = true;
|
||||
EnableSignInWithUsername = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
khscodes = {
|
||||
infrastructure.khs-openstack-instance = {
|
||||
enable = true;
|
||||
flavor = "m.small";
|
||||
network = {
|
||||
ipv4Cidr = "172.24.1.0/24";
|
||||
};
|
||||
};
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts."chat.kaareskovgaard.net" = {
|
||||
rateLimit.burst = 100;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString mattermost.port}";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
services.vault-agent.templates = [
|
||||
{
|
||||
contents = ''
|
||||
{{- with secret "kanidm/data/apps/mattermost" -}}
|
||||
MM_OPENIDSETTINGS_SECRET={{ .Data.data.basic_secret }}
|
||||
{{- end -}}
|
||||
'';
|
||||
destination = "/run/mattermost/env";
|
||||
owner = "mattermost";
|
||||
group = "mattermost";
|
||||
perms = "0600";
|
||||
reloadOrRestartUnits = [ "mattermost.service" ];
|
||||
}
|
||||
];
|
||||
infrastructure.vault-server-approle.policy = {
|
||||
"kanidm/data/apps/mattermost" = {
|
||||
capabilities = [ "read" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
khscodes.networking.fqdn = "chat.kaareskovgaard.net";
|
||||
system.stateVersion = "25.05";
|
||||
}
|
|
@ -190,6 +190,9 @@ in
|
|||
infrastructure.khs-openstack-instance = {
|
||||
enable = true;
|
||||
flavor = "m.large";
|
||||
network = {
|
||||
router = null;
|
||||
};
|
||||
};
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue