После довольно длительного экспериментального этапа, пытаясь сделать эту работу, я наконец-то нашел то, что кажется возможным и надежным решением без чрезвычайно тревожных недостатков, которые могут возникнуть при использовании eval
.
Чтобы лучше выделить общее окончательное решение, я предлагаю немного больше обработки, с которой я сейчас работаю:
Цель
Получите секрет из AWS Secrets Manager
Синтаксически проанализируйте возвращенный JSON, который выглядит следующим образом:
{
"ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
"Name": "MyTestDatabaseSecret",
"VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE",
"SecretString": "{\n \"username\":\"david\",\n \"password\":\"BnQw&XDWgaEeT9XGTT29\"\n}\n",
"VersionStages": [
"AWSPREVIOUS"
],
"CreatedDate": 1523477145.713
}
Выполнить некоторые изменения в полученной строке JSON и выбрать только статически запрашиваемые ключи из секрета
Установить и экспортировать эти значения в качестве переменных среды
Script
# Capture a AWS Secret from secretsmanager, parse the JSON and expand the given
# variables within it to pick them from the secret and return given portion of
# the secret requested.
# @note similar to _.pick(obj, ["foo", "bar"])
getKeysFromSecret() {
aws secretsmanager get-secret-value --secret-id "$1" \
| jq -r '.SecretString | fromjson' \
| jq -r "{ $2 }"
}
# Uses `getKeysFromSecret` to capture the requested keys from the secret
# then transforms the JSON into a string that we can read and loop through
# to set each resulting value as an exported environment variable.
#
## Transformation Flow:
# { "foo": "bar", "baz": "qux" }
# -->
# foo=bar
# baz=qux
# -->
# export foo=bar
# export baz=qux
exportVariablesInSecret() {
while IFS== read -r key value; do
if [ -n "$value" ]; then
export "${key}"="${value}";
fi
done < <(getKeysFromSecret "$1" "$2" | jq -r 'to_entries | .[] | .key + "=" + .value')
}
Пример JSON
{
...othervalues
"SecretString": "{\"foo\": \"bar\", \"baz\": \"qux\"}"
}
Пример использования
exportVariablesInSecret MY_SECRET "foo, bar"
echo $foo
# bar
Некоторые заметки / контекст
Это предназначено для установки заданного набора значений в качестве переменных, чтобы мы не просто устанавливали весь произвольный объект JSON в качестве переменных, которые могут вызвать проблемы / затенение, если кто-то добавит значение типа «путь» к секрету
Важнейшей задачей было абсолютно никогда не использовать eval
для предотвращения возможных ситуаций инъекции.Слишком легко вводить вещи иначе.
Рад видеть, есть ли у кого-нибудь более хороший способ сделать это.Я видел много людей, которые рекомендовали использовать declare
, но это устанавливает переменную в область видимости локальной функции, поэтому она по сути бесполезна.
Благодаря @cas https://unix.stackexchange.com/a/413917/308550 за то, что я на правильном пути!