- netboot-base.nix with SSH key auth - Launch scripts for node01/02/03 - Node configuration.nix and disko.nix - Nix modules for first-boot automation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.4 KiB
Unified Configuration Guidelines
This document outlines the standardized approach for managing configuration across all components of the Cloud project. Adhering to these guidelines ensures consistency, maintainability, and ease of operation for all services.
1. Layered Configuration with config-rs
All components MUST use the config-rs crate for managing application settings. This allows for a robust, layered configuration system with clear precedence:
- Defaults: Sensible, hard-coded default values provided by the application. These are the lowest precedence.
- Environment Variables: Values loaded from environment variables. These override defaults.
- Configuration Files: Values loaded from a TOML configuration file. These override environment variables and defaults.
- Command-Line Arguments: Values provided via command-line arguments. These are the highest precedence and always override all other sources.
Implementation Details:
ServerConfig::default()as base: Usetoml::to_string(&MyServerConfig::default())to provide the base default configuration toconfig-rs. This ensuresDefaultimplementations are the source of truth for base settings.- Workspace Dependency: The
configcrate should be a[workspace.dependencies]entry in the component'sCargo.toml, and member crates should reference it withconfig.workspace = true.
2. Configuration File Format: TOML
All configuration files MUST be in the TOML format.
config-rsshould be configured to read TOML files (config::FileFormat::Toml).- Configuration structs MUST derive
serde::Serializeandserde::Deserializeto enableconfig-rsto populate them.
3. Command-Line Argument Overrides with clap
All components MUST use clap::Parser for parsing command-line arguments.
- Critical configuration parameters MUST be exposed as CLI arguments.
- CLI arguments are applied after
config-rshas loaded all other configuration sources, ensuring they have the highest precedence. This typically involves manually setting fields in the deserialized configuration struct ifOption<T>arguments are provided.
4. Consistent Environment Variable Prefixes
All components MUST use a consistent naming convention for environment variables.
- Prefix Format:
UPPERCASE_COMPONENT_NAME_(e.g.,CHAINFIRE_,FLAREDB_,IAM_). - Nested Fields: Use double underscores (
__) to represent nested fields in the configuration structure.- Example: For
network.api_addr, the environment variable would beCHAINFIRE_NETWORK__API_ADDR.
- Example: For
- Case Conversion: Configure
config-rsto convert environment variable names tosnake_caseto match Rust struct field names (.convert_case(config::Case::Snake)).
5. Configuration Struct Guidelines
- Top-Level
ServerConfig: Each executable component (e.g.,chainfire-server,flaredb-server) should have a single top-levelServerConfig(or similar name) struct that encapsulates all its settings. - Modularity: Break down
ServerConfiginto smaller, logical sub-structs (e.g.,NodeConfig,NetworkConfig,StorageConfig,ClusterConfig) to improve readability and maintainability. DefaultImplementation: All configuration structs and their sub-structs MUST implementDefaultto provide sensible starting values.- Doc Comments: Use clear doc comments for all configuration fields, explaining their purpose and acceptable values.
6. TLS/mTLS Configuration (Security)
All services MUST support optional TLS configuration for production deployments. The TLS configuration pattern ensures consistent security across all components.
Standard TLS Configuration Structure
use serde::{Deserialize, Serialize};
/// TLS configuration for gRPC servers
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TlsConfig {
/// Path to server certificate file (PEM format)
pub cert_file: String,
/// Path to server private key file (PEM format)
pub key_file: String,
/// Path to CA certificate file for client verification (optional, enables mTLS)
pub ca_file: Option<String>,
/// Require client certificates (mTLS mode)
#[serde(default)]
pub require_client_cert: bool,
}
Integration Pattern
Services should include tls: Option<TlsConfig> in their server configuration:
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerSettings {
/// Listen address
pub addr: SocketAddr,
/// TLS configuration (optional)
pub tls: Option<TlsConfig>,
}
Server Builder Pattern (tonic)
use tonic::transport::{Server, ServerTlsConfig, Identity, Certificate};
let mut server = Server::builder();
if let Some(tls_config) = &config.server.tls {
let cert = tokio::fs::read(&tls_config.cert_file).await?;
let key = tokio::fs::read(&tls_config.key_file).await?;
let server_identity = Identity::from_pem(cert, key);
let tls = if tls_config.require_client_cert {
// mTLS: require and verify client certificates
let ca_cert = tokio::fs::read(
tls_config.ca_file.as_ref()
.ok_or("ca_file required when require_client_cert=true")?
).await?;
let ca = Certificate::from_pem(ca_cert);
ServerTlsConfig::new()
.identity(server_identity)
.client_ca_root(ca)
} else {
// TLS only: no client certificate required
ServerTlsConfig::new()
.identity(server_identity)
};
server = server.tls_config(tls)?;
}
server.add_service(my_service).serve(config.server.addr).await?;
TOML Configuration Example
[server]
addr = "0.0.0.0:50051"
[server.tls]
cert_file = "/etc/centra-cloud/certs/iam/server.crt"
key_file = "/etc/centra-cloud/certs/iam/server.key"
ca_file = "/etc/centra-cloud/certs/ca.crt"
require_client_cert = true # Enable mTLS
Certificate Management
- Development: Use
scripts/generate-dev-certs.shto create self-signed CA and service certificates - Production: Integrate with external PKI or use cert-manager for automated rotation
- Storage: Certificates stored in
/etc/centra-cloud/certs/(NixOS managed) - Permissions: Private keys must be readable only by service user (chmod 600)
By following these guidelines, we aim to achieve a unified, operator-friendly, and robust configuration system across the entire Cloud project.