#опытным
Любой серьезный сервис нуждается в конфигурации. Файлы конфигурации (JSON, YAML, INI) — популярный способ хранения настроек приложений. Так параметры можно хранить в репозитории, версионировать, да и просто удобно, когда все можно менять в одном месте и никак не менять команду запуска.
Однако не одними конфигами едины. Не всегда они подходят для решения определенных задач.
Возьмем например ключи шифрования. Не всегда они генерируются новые, для интеграции двух партнеров могут использоваться ключи, которые обновляются раз в год или раз в полгода. Безопасно ли ключ шифрования выставлять в конфиге?
Не совсем. Что если какой-нибудь умник после тестирования приложения случайно закоммитит ключ в репозиторий? Это серьезная опасность: репозиторий вашей команды скорее всего может читать любой сотрудник, у которого есть доступ к вашей системе совместной разработки. А если у вас еще сторонние лица имеют доступ к репе... Не завидую вам. Безопасники будут радостно потирать ладоши, когда будут вам пистоны вставлять за эту ошибку. Потом еще ключ перевыпускать скомпрометированный, долго и мучительно заменять его... Сам наступал на эти грабли, приятного мало.
{
"data_key": "qwerty123" // Утечка при публикации кода!
}Да и хранить ключ в открытом виде в файле на сервере такое себе. А если кто-нибудь подглядит?
То же самое можно сказать про креды базы данных, in-memory кэша, брокеров сообщений и прочего. Пароли могут быть скомпрометированы.
# config.yml (попадает в Git)
db:
host: db.example.com
username: admin
password: "P@ssw0rd123!" # Утечка при публикации кода!
А как с докерами и кубернетисами вашими работать? Иметь 100500 образов с разными настройками кредов и множить их постоянно? Выглядит, как не очень расширяемое решение.
Конечно же никто не хранит в конфигах чувствительные данные и специфичные для конкретного инстанса переменные. Вместо этого используют переменные окружения.
Переменные окружения можно установить видимыми только для конкретного запущенного docker контейнера:
docker run -e MY_VAR=value my_image
В k8s можно брать переменые окружения из отдельно развернутого и защищенного Vault. В этом случае вообще отсутсвует явное указание секрета:
env:
- name: MY_VAR
- value: vault:my_group/my_service#my_var
Переменные окружения не попадают в репозиторий -> нет компрометации секретов.
Можно без изменения конфига на одном и том же сервере тестировать приложение в разных контурах:
# Local
export DB_HOST=localhost
# Dev
export DB_HOST=dev-db.example.com
В общем, переменные окружения в приложении - полезная вещь, не стоит ими принебрегать.
К чему это я и причем здесь С++?
Ну нам же нужно выяснить, как в стандартных плюсах можно получать значения переменных окружения. Об этом поговорим в следующем посте.
Protect your secrets. Stay cool.
#goodpractice #tools