From 973fa1a7ff48e452c0a7a3d31026b23879069f0a Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Sun, 2 Mar 2025 09:27:50 -0700 Subject: [PATCH] Adds the ability to alias/map secrets --- lib/kamal/configuration/docs/env.yml | 24 ++++++++++++++++++++++++ lib/kamal/configuration/env.rb | 10 +++++++++- test/configuration/env_test.rb | 14 ++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/kamal/configuration/docs/env.yml b/lib/kamal/configuration/docs/env.yml index 98521ae4..23b5b60b 100644 --- a/lib/kamal/configuration/docs/env.yml +++ b/lib/kamal/configuration/docs/env.yml @@ -51,6 +51,30 @@ env: secret: - DB_PASSWORD +# Aliased secrets +# +# You can also alias secrets to other secrets using a `:` separator. +# +# This is useful when the ENV name is different from the secret name. For example, if you have two +# places where you need to define the ENV variable `DB_PASSWORD`, but the value is different depending +# on the context. +# +# ```shell +# SECRETS=$(kamal secrets fetch ...) +# +# MAIN_DB_PASSWORD=$(kamal secrets extract MAIN_DB_PASSWORD $SECRETS) +# SECONDARY_DB_PASSWORD=$(kamal secrets extract SECONDARY_DB_PASSWORD $SECRETS) +# ``` +accessories: + main_db_accessory: + env: + secret: + - DB_PASSWORD:MAIN_DB_PASSWORD + secondary_db_accessory: + env: + secret: + - DB_PASSWORD:SECONDARY_DB_PASSWORD + # Tags # # Tags are used to add extra env variables to specific hosts. diff --git a/lib/kamal/configuration/env.rb b/lib/kamal/configuration/env.rb index 8e52d9e4..077f1cf2 100644 --- a/lib/kamal/configuration/env.rb +++ b/lib/kamal/configuration/env.rb @@ -18,7 +18,7 @@ class Kamal::Configuration::Env end def secrets_io - Kamal::EnvFile.new(secret_keys.to_h { |key| [ key, secrets[key] ] }).to_io + Kamal::EnvFile.new(secrets_hash).to_io end def merge(other) @@ -26,4 +26,12 @@ class Kamal::Configuration::Env config: { "clear" => clear.merge(other.clear), "secret" => secret_keys | other.secret_keys }, secrets: secrets end + + private + def secrets_hash + secret_keys.to_h do |key| + key_name, key_aliased_to = key.split(":") + [ key_name, secrets[key_aliased_to || key_name] ] + end + end end diff --git a/test/configuration/env_test.rb b/test/configuration/env_test.rb index 627d3a6c..29cf0d85 100644 --- a/test/configuration/env_test.rb +++ b/test/configuration/env_test.rb @@ -48,6 +48,20 @@ class ConfigurationEnvTest < ActiveSupport::TestCase end end + test "aliased secrets" do + with_test_secrets("secrets" => "ALIASED_PASSWORD=hello") do + config = { + "secret" => [ "PASSWORD:ALIASED_PASSWORD" ], + "clear" => {} + } + + assert_config \ + config: config, + clear: {}, + secrets: { "PASSWORD" => "hello" } + end + end + private def assert_config(config:, clear: {}, secrets: {}) env = Kamal::Configuration::Env.new config: config, secrets: Kamal::Secrets.new