0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RustでYAMLに埋め込まれた環境変数を展開

Last updated at Posted at 2024-06-30

使用ライブラリ

ライブラリ 説明
envsubst 文字列テンプレートにおける変数の置換に使用
env_logger log crateによって公開されるロギングファサードで使用するために、環境変数によって設定できるシンプルなロガー
log ログ出力に使用(ログの設定は割愛)
once_cell 「一度しか初期化できない」型を提供
正規表現のパフォーマンス改善に使用
regex 正規表現
serde Rustデータ構造を効率的かつ汎用的にシリアライズおよびデシリアライズするためのフレームワーク
confy 環境変数、設定ファイル、コマンドライン引数など、複数の設定ソースを統合して管理できるクレート
[package]
name = "web"
version = "0.1.0"
edition = "2021"

[dependencies]
envsubst = "0.2.1"
env_logger = "0.11.3"
log = "0.4.21"
once_cell = "1.19.0"
regex = "1.10.5"
serde = { version = "1.0", features = ["derive"] }

[dependencies.confy]
version = "0.6.1"
features = ["yaml_conf"]
default-features = false

設定ファイル

  • 環境変数を埋め込みたい部分は ${環境変数名}で記述
config.yml
cors:
  allowed_origin: ${ALLOWED_ORIGIN}

実装

環境変数を置換するようのコード

env.rs
use envsubst;
use log::error;
use once_cell::sync::Lazy;
use regex::Regex;
use serde::{Deserialize, Deserializer};
use std::env;
use std::process;

/// ${val}を環境変数の値に置換
pub fn deserialize_with_env<'de, D>(deserializer: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
{
    let s: String = Deserialize::deserialize(deserializer)?;
    Ok(substitute_env_variables(&s))
}

static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"\$\{(\w+)\}").unwrap());

fn substitute_env_variables(input: &str) -> String {
    if envsubst::is_templated(input) {
        let mut context = std::collections::HashMap::new();
        for (_, [cap]) in RE.captures_iter(input).map(|c| c.extract()) {
            match env::var(cap) {
                Ok(val) => context.insert(cap.to_string(), val),
                Err(e) => {
                    error!("{}", e);
                    process::exit(1);
                }
            };
        }
        envsubst::substitute(input, &context).unwrap()
    } else {
        input.to_string()
    }
}

main処理

  • #[serde(deserialize_with = "deserialize_with_env")]を環境変数を設定する可能性がある箇所に付与
main.rs
use common::config::env::deserialize_with_env;
use confy::{self, ConfyError};
use log::{info, error};
use serde::{Deserialize, Serialize};
use std::process;
use env_logger::Env;

mod env;

#[derive(Default, Debug, Serialize, Deserialize)]
pub struct CorsConfig {
    #[serde(deserialize_with = "deserialize_with_env")]
    pub allowed_origin: String,
}

#[derive(Default, Debug, Serialize, Deserialize)]
pub struct Config {
    pub cors: CorsConfig,
}

/// YAMLからコンフィグの値を取得
pub fn get_config() -> Config {
    let cfg: Result<Config, ConfyError> = confy::load_path("config.yml");
    match cfg {
        Ok(cfg) => cfg,
        Err(e) => {
            error!("{}", e);
            process::exit(1);
        }
    }
}

fn main() {
    env_logger::init_from_env(Env::default().default_filter_or("info"));
    let config = env::get_config();
    info!("{:?}", config);
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?