-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
nixos/vault: implement RFC0042 #328002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
nixos/vault: implement RFC0042 #328002
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,41 +6,31 @@ let | |
| cfg = config.services.vault; | ||
| opt = options.services.vault; | ||
|
|
||
| configFile = pkgs.writeText "vault.hcl" '' | ||
| # vault in dev mode will refuse to start if its configuration sets listener | ||
| ${lib.optionalString (!cfg.dev) '' | ||
| listener "tcp" { | ||
| address = "${cfg.address}" | ||
| ${if (cfg.tlsCertFile == null || cfg.tlsKeyFile == null) then '' | ||
| tls_disable = "true" | ||
| '' else '' | ||
| tls_cert_file = "${cfg.tlsCertFile}" | ||
| tls_key_file = "${cfg.tlsKeyFile}" | ||
| ''} | ||
| ${cfg.listenerExtraConfig} | ||
| } | ||
| ''} | ||
| storage "${cfg.storageBackend}" { | ||
| ${optionalString (cfg.storagePath != null) ''path = "${cfg.storagePath}"''} | ||
| ${optionalString (cfg.storageConfig != null) cfg.storageConfig} | ||
| } | ||
| ${optionalString (cfg.telemetryConfig != "") '' | ||
| telemetry { | ||
| ${cfg.telemetryConfig} | ||
| } | ||
| ''} | ||
| ${cfg.extraConfig} | ||
| ''; | ||
| format = pkgs.formats.json {}; | ||
| configFile = format.generate "vault.hcl.json" (filterAttrsRecursive (_: v: v != null) cfg.settings); | ||
|
|
||
| allConfigPaths = [configFile] ++ cfg.extraSettingsPaths; | ||
| configOptions = escapeShellArgs | ||
| (lib.optional cfg.dev "-dev" ++ | ||
| lib.optional (cfg.dev && cfg.devRootTokenID != null) "-dev-root-token-id=${cfg.devRootTokenID}" | ||
| ++ (concatMap (p: ["-config" p]) allConfigPaths)); | ||
|
|
||
| storagePath = if cfg.storageBackend == "file" || cfg.storageBackend == "raft" then cfg.settings.storage.${cfg.storageBackend}.path else null; | ||
| in | ||
|
|
||
| { | ||
| imports = [ | ||
| (mkRenamedOptionModule [ "services" "vault" "address" ] [ "services" "vault" "settings" "listener" "tcp" "address" ]) | ||
| (mkRenamedOptionModule [ "services" "vault" "tlsCertFile" ] [ "services" "vault" "settings" "listener" "tcp" "tls_cert_file" ]) | ||
| (mkRenamedOptionModule [ "services" "vault" "tlsKeyFile" ] [ "services" "vault" "settings" "listener" "tcp" "tls_key_file" ]) | ||
| (mkRenamedOptionModule [ "services" "vault" "storagePath" ] [ "services" "vault" "settings" "storage" cfg.storageBackend "path" ]) | ||
|
|
||
| (mkRemovedOptionModule [ "services" "vault" "listenerExtraConfig" ] "Use services.vault.settings.listener.tcp instead") | ||
| (mkRemovedOptionModule [ "services" "vault" "storageConfig" ] "Use services.vault.settings.storage.${cfg.storageBackend} instead") | ||
| (mkRemovedOptionModule [ "services" "vault" "telemetryConfig" ] "Use services.vault.settings.telemetry instead") | ||
| (mkRemovedOptionModule [ "services" "vault" "extraConfig" ] "Use services.vault.settings instead") | ||
| ]; | ||
|
|
||
| options = { | ||
| services.vault = { | ||
| enable = mkEnableOption "Vault daemon"; | ||
|
|
@@ -63,76 +53,149 @@ in | |
| ''; | ||
| }; | ||
|
|
||
| address = mkOption { | ||
| type = types.str; | ||
| default = "127.0.0.1:8200"; | ||
| description = "The name of the ip interface to listen to"; | ||
| }; | ||
|
|
||
| tlsCertFile = mkOption { | ||
| type = types.nullOr types.str; | ||
| default = null; | ||
| example = "/path/to/your/cert.pem"; | ||
| description = "TLS certificate file. TLS will be disabled unless this option is set"; | ||
| }; | ||
|
|
||
| tlsKeyFile = mkOption { | ||
| type = types.nullOr types.str; | ||
| default = null; | ||
| example = "/path/to/your/key.pem"; | ||
| description = "TLS private key file. TLS will be disabled unless this option is set"; | ||
| }; | ||
|
|
||
| listenerExtraConfig = mkOption { | ||
| type = types.lines; | ||
| default = '' | ||
| tls_min_version = "tls12" | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was removed because this is already the default value source: https://developer.hashicorp.com/vault/docs/configuration/listener/tcp#tls_min_version |
||
| ''; | ||
| description = "Extra text appended to the listener section."; | ||
| }; | ||
|
|
||
| storageBackend = mkOption { | ||
| type = types.enum [ "inmem" "file" "consul" "zookeeper" "s3" "azure" "dynamodb" "etcd" "mssql" "mysql" "postgresql" "swift" "gcs" "raft" ]; | ||
| default = "inmem"; | ||
| description = "The name of the type of storage backend"; | ||
| }; | ||
|
|
||
| storagePath = mkOption { | ||
| type = types.nullOr types.path; | ||
| default = if cfg.storageBackend == "file" || cfg.storageBackend == "raft" then "/var/lib/vault" else null; | ||
| defaultText = literalExpression '' | ||
| if config.${opt.storageBackend} == "file" || cfg.storageBackend == "raft" | ||
| then "/var/lib/vault" | ||
| else null | ||
| ''; | ||
| description = "Data directory for file backend"; | ||
| }; | ||
|
|
||
| storageConfig = mkOption { | ||
| type = types.nullOr types.lines; | ||
| default = null; | ||
| settings = mkOption { | ||
| type = types.submodule { | ||
| freeformType = format.type; | ||
|
|
||
| options = { | ||
| listener = mkOption { | ||
| type = types.nullOr (types.submodule { | ||
| freeformType = format.type; | ||
|
|
||
| options = { | ||
| tcp = mkOption { | ||
| type = types.nullOr (types.submodule ({ config, ... }: { | ||
| freeformType = format.type; | ||
|
|
||
| options = { | ||
| address = mkOption { | ||
| type = types.str; | ||
| default = "127.0.0.1:8200"; | ||
| description = '' | ||
| Specifies the address to bind to for listening. This can be dynamically defined | ||
| with a [go-sockaddr](https://pkg.go.dev/github.com/hashicorp/go-sockaddr/template) | ||
| template that is resolved at runtime. | ||
| ''; | ||
| }; | ||
|
|
||
| tls_cert_file = mkOption { | ||
| type = types.nullOr types.str; | ||
| default = null; | ||
| example = "/path/to/your/cert.pem"; | ||
| description = "TLS certificate file. TLS will be disabled unless this option is set"; | ||
| }; | ||
|
|
||
| tls_key_file = mkOption { | ||
| type = types.nullOr types.str; | ||
| default = null; | ||
| example = "/path/to/your/key.pem"; | ||
| description = "TLS private key file. TLS will be disabled unless this option is set"; | ||
| }; | ||
|
|
||
| tls_disable = mkOption { | ||
| type = types.bool; | ||
| default = config.tls_cert_file == null || config.tls_key_file == null; | ||
| description = '' | ||
| Specifies if TLS will be disabled. | ||
| ''; | ||
| }; | ||
| }; | ||
| })); | ||
| default = { }; | ||
| description = '' | ||
| The TCP listener configures Vault to listen on a TCP address/port. | ||
|
|
||
| See <https://developer.hashicorp.com/vault/docs/configuration/listener/tcp#tcp-listener-parameters> | ||
| for details. | ||
| ''; | ||
| }; | ||
| }; | ||
| }); | ||
| default = { }; | ||
| description = '' | ||
| The `listener` stanza configures the addresses and ports on which Vault will respond to requests. | ||
|
|
||
| See <https://developer.hashicorp.com/vault/docs/configuration/listener> for details. | ||
| ''; | ||
| }; | ||
|
|
||
| storage = mkOption { | ||
| type = types.nullOr (types.submodule { | ||
| freeformType = format.type; | ||
|
|
||
| options = { | ||
| file = mkOption { | ||
| type = types.nullOr (types.submodule { | ||
| freeformType = format.type; | ||
|
|
||
| options = { | ||
| path = mkOption { | ||
| type = types.path; | ||
| default = "/var/lib/vault"; | ||
| description = "The absolute path on disk to the directory where the data will be stored."; | ||
| }; | ||
| }; | ||
| }); | ||
| default = null; | ||
| description = '' | ||
| The Filesystem storage backend stores Vault's data on the filesystem using a standard directory | ||
| structure. It can be used for durable single server situations, or to develop locally where | ||
| durability is not critical. | ||
|
|
||
| See <https://developer.hashicorp.com/vault/docs/configuration/storage/filesystem#file-parameters> | ||
| for details. | ||
| ''; | ||
| }; | ||
|
|
||
| raft = mkOption { | ||
| type = types.nullOr (types.submodule { | ||
| freeformType = format.type; | ||
|
|
||
| options = { | ||
| path = mkOption { | ||
| type = types.path; | ||
| default = "/var/lib/vault"; | ||
| description = "The file system path where all the Vault data gets stored."; | ||
| }; | ||
| }; | ||
| }); | ||
| default = null; | ||
| description = '' | ||
| The Integrated Storage backend is used to persist Vault's data. Unlike other storage | ||
| backends, Integrated Storage does not operate from a single source of data. Instead all the nodes | ||
| in a Vault cluster will have a replicated copy of Vault's data. Data gets replicated across all | ||
| the nodes via the [Raft Consensus Algorithm](https://raft.github.io/). | ||
|
|
||
| See <https://developer.hashicorp.com/vault/docs/configuration/storage/raft#raft-parameters> | ||
| for details. | ||
| ''; | ||
| }; | ||
| }; | ||
| }); | ||
| default = { }; | ||
| description = '' | ||
| The `storage` stanza configures the storage backend, which represents the location for the durable | ||
| storage of Vault's information. Each backend has pros, cons, advantages, and trade-offs. For example, | ||
| some backends support high availability while others provide a more robust backup and restoration | ||
| process. | ||
|
|
||
| See <https://developer.hashicorp.com/vault/docs/configuration/storage> for details. | ||
| ''; | ||
| }; | ||
| }; | ||
| }; | ||
| default = { }; | ||
| description = '' | ||
| HCL configuration to insert in the storageBackend section. | ||
|
|
||
| Confidential values should not be specified here because this option's | ||
| value is written to the Nix store, which is publicly readable. | ||
| Provide credentials and such in a separate file using | ||
| [](#opt-services.vault.extraSettingsPaths). | ||
| Configuration of Vault. See https://developer.hashicorp.com/vault/docs/configuration for a description of options. | ||
| ''; | ||
| }; | ||
|
|
||
| telemetryConfig = mkOption { | ||
| type = types.lines; | ||
| default = ""; | ||
| description = "Telemetry configuration"; | ||
| }; | ||
|
|
||
| extraConfig = mkOption { | ||
| type = types.lines; | ||
| default = ""; | ||
| description = "Extra text appended to {file}`vault.hcl`."; | ||
| }; | ||
|
|
||
| extraSettingsPaths = mkOption { | ||
| type = types.listOf types.path; | ||
| default = []; | ||
|
|
@@ -166,18 +229,15 @@ in | |
| }; | ||
|
|
||
| config = mkIf cfg.enable { | ||
| assertions = [ | ||
| services.vault.settings = mkMerge [ | ||
| { | ||
| assertion = cfg.storageBackend == "inmem" -> (cfg.storagePath == null && cfg.storageConfig == null); | ||
| message = ''The "inmem" storage expects no services.vault.storagePath nor services.vault.storageConfig''; | ||
| } | ||
| { | ||
| assertion = ( | ||
| (cfg.storageBackend == "file" -> (cfg.storagePath != null && cfg.storageConfig == null)) && | ||
| (cfg.storagePath != null -> (cfg.storageBackend == "file" || cfg.storageBackend == "raft")) | ||
| ); | ||
| message = ''You must set services.vault.storagePath only when using the "file" or "raft" backend''; | ||
| storage.${cfg.storageBackend} = { }; | ||
| } | ||
|
|
||
| # vault in dev mode will refuse to start if its configuration sets listener | ||
| (mkIf cfg.dev { | ||
| listener = mkForce null; | ||
| }) | ||
| ]; | ||
|
|
||
| users.users.vault = { | ||
|
|
@@ -188,8 +248,8 @@ in | |
| }; | ||
| users.groups.vault.gid = config.ids.gids.vault; | ||
|
|
||
| systemd.tmpfiles.rules = optional (cfg.storagePath != null) | ||
| "d '${cfg.storagePath}' 0700 vault vault - -"; | ||
| systemd.tmpfiles.rules = optional (storagePath != null) | ||
| "d '${storagePath}' 0700 vault vault - -"; | ||
|
|
||
| systemd.services.vault = { | ||
| description = "Vault server daemon"; | ||
|
|
@@ -222,7 +282,7 @@ in | |
| Restart = "on-failure"; | ||
| }; | ||
|
|
||
| unitConfig.RequiresMountsFor = optional (cfg.storagePath != null) cfg.storagePath; | ||
| unitConfig.RequiresMountsFor = optional (storagePath != null) storagePath; | ||
| }; | ||
| }; | ||
|
|
||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.