За время моей работы в блоге Twilio я заметил одну вещь. Мы постоянно говорим вам хранить ваш account SID и auth token в переменных окружения. Однако мы не уделяем слишком много времени тому, как лучше управлять этими переменными окружения.
На моей предыдущей работе в цифровом агентстве я занимался множеством различных приложений. Каждое из этих приложений полагалось на различные API и хранило различные учетные данные. Лучшие практики, такие как Twelve Factor App, и ограничения определенных платформ хостинга, таких как Heroku, привели нас к использованию переменных окружения для хранения этих секретов. Однако нам потребовалось много времени, чтобы стандартизировать наш подход: от взлома процесса загрузки Rails до создания гема, который решал бы эту задачу.
В простых случаях легко установить переменную окружения, но при наличии множества приложений, множества учетных данных и быстро меняющейся среде установка и сброс переменных окружения очень быстро становятся громоздкими. Но именно здесь на помощь приходят Ruby и сообщество. Существует ряд способов хранения и управления переменными окружения. Давайте посмотрим, как они могут улучшить вашу среду разработки.
Начнем с простого способа использования переменных окружения. Допустим, вы разрабатываете приложение и используете Twilio, вам понадобится ваш account SID и auth token. Итак, загрузим их в окружение. В командной строке Mac или Linux вы введете:
Я лично не разрабатываю на Windows, но на superuser.com есть очень подробный ответ об переменных окружения для различных операционных систем, который может помочь вам, если вы работаете на ней.
При запуске вашего приложения вы можете ссылаться на ENV[‘TWILIO_ACCOUNT_SID’] и ENV[‘TWILIO_AUTH_TOKEN’]. Давайте попробуем это с помощью простой однострочной команды для вывода переменных. Добавление флага -e к команде ruby позволяет нам выполнить строку кода прямо в командной строке, что полезно для этого примера.
Отлично, у нас есть переменные окружения!
Если мы продолжим разработку из окна терминала, которое мы только что использовали, все будет в порядке. Однако откройте новое окно терминала и снова выполните ту же команду Ruby, чтобы увидеть, что произойдет:
Переменные окружения исчезли. Чтобы использовать их снова, нам придется повторно экспортировать их для каждой сессии терминала, в которой мы хотим запустить наше приложение. Должен быть лучший способ!
Конечно, возможно установить переменные окружения более постоянно. На Mac и Linux вы можете добавить те же строки экспорта в ваш файл ~/.profile, и они будут загружены при создании новой сессии терминала. Я снова отсылаю вас к экспертам на superuser.com по управлению переменными окружения в Windows.
Проблема, с которой я столкнулся, заключается в том, что хотя у меня много проектов, которые могут использовать одни и те же сервисы, такие как Twilio, Twitter, Facebook, Mailchimp и т. д., они не все используют одни и те же учетные данные. Вы могли бы использовать префикс имени приложения для ваших переменных окружения в качестве своего рода пространства имен, но со временем это становится очень запутанным.
Нам нужно три вещи, чтобы сделать переменные окружения управляемыми:
— Нам нужно загружать учетные данные, секреты и другие элементы конфигурации в окружение для каждого проекта.
— Нам нужно иметь возможность делать это от простейших скриптов до полноценных приложений Rails.
— Нам нужно хранить секреты вне системы контроля версий, чтобы они не распространялись непреднамеренно.
Как я сказал в начале, сообщество Ruby действительно позаботилось об этом. Просмотр списка гемов для управления конфигурацией на The Ruby Toolbox показывает нам многое, хотя не все из них полезны в данной ситуации. Два, которые выделяются для загрузки конфигурации в окружение, — это dotenv и Figaro. Я хотел бы предложить envyable как еще одного кандидата в этот список, поскольку он вырос из моей предыдущей работы в агентстве, чтобы охватить и этот вариант использования.
Вот краткий обзор того, как работает каждая из этих библиотек и как они могут избавить вас от проблем с загрузкой конфигурации в ваше окружение.
Для envyable вам нужно всего лишь добавить гем в ваш Gemfile:
Запустите bundle install, затем добавьте файл env.yml в ваш каталог config. Если вы не работаете в Rails, вам, возможно, придется создать этот каталог.
Добавьте этот файл в ваш файл .gitignore (или файл игнорирования для вашей системы контроля версий по вашему выбору).
И затем начните добавлять ваши секреты в env.yml.
Если вы используете Rails, конфигурация будет загружена для вас при перезапуске вашего приложения. Если вы используете его в другом фреймворке или приложении, вам просто нужно включить гем и вызвать:
перед тем, как вам понадобится ваша конфигурация. Теперь, в вашем приложении, у вас будет доступ к ENV[‘TWILIO_ACCOUNT_SID’] и ENV[‘TWILIO_AUTH_TOKEN’].
Figaro похож на envyable, но с некоторыми дополнительными функциями. Его недостаток в том, что он работает только с Rails. Добавьте гем в ваш Gemfile, как обычно:
После запуска bundle install запустите скрипт установки Figaro:
Это создаст файл config/application.yml для вашей конфигурации и добавит его в ваш .gitignore одним махом. Теперь вы можете начать добавлять секреты в файл:
Как вы можете видеть в этом случае, Figaro позволяет добавлять переменные окружения по умолчанию, а затем переопределять их на уровне каждого окружения. Figaro имеет и другие полезные функции, такие как обязательные ключи и скрипт для автоматической настройки Heroku.
В отличие от предыдущих гемов, dotenv не полагается на yaml для файла конфигурации, помещенного в каталог config, вместо этого используя файл .env в корне проекта. Чтобы начать, добавьте гем в ваш Gemfile:
Или для приложений Rails:
Запустите bundle install и создайте файл .env.
Теперь вы можете добавить свою конфигурацию в файл в формате, который намеренно напоминает экспорт переменных окружения в командной строке:
Вы даже можете добавить оператор экспорта в начало, если хотите запустить файл в bash:
Я рекомендую также добавить файл .env в ваш файл .gitignore, хотя Брэндон Киперс, создатель dotenv, предлагает закоммитить файл в проект, сохранив только ваши учетные данные для разработки. Это немного философское различие между dotenv и envyable/figaro. Мои учетные данные для разработки обычно основаны на моих аккаунтах, поэтому я не хочу делиться ими и предпочитаю хранить секреты вне системы контроля версий.
Если вы используете Rails, переменные окружения будут загружены автоматически, но в других приложениях вы можете просто:
Вы также можете предоставить конфигурацию для конкретного окружения, создав файлы .env.production или .env.development, которые будут переопределять любую конфигурацию, установленную в файле .env в соответствующем окружении.
Ах да. Начиная с версии 4.1, Rails имеет свой собственный способ загрузки секретов. Недавно созданные проекты Rails 4.1 поставляются с файлом config/secrets.yml. К любому ключу в этом файле можно получить доступ, вызвав Rails.application.secrets.key_name. По сути, в Rails 4.2 также есть Rails.application.config_for, который можно использовать для загрузки произвольных yaml-файлов из каталога config. Хотя этот пост посвящен только secrets.yml, я думаю, Стив Рихтерт (автор Figaro) лучше всего описывает, почему Rails все еще не решил проблему.
Конечно, простого ответа на этот вопрос нет. Честно говоря, каждый из гемов, о которых я говорил выше, и, вероятно, есть другие, которые я не нашел, отлично справляется с обеспечением безопасности ваших секретов и загрузкой их в окружение для каждого проекта. Каждый из них решает проблемы, которые я описал при работе с множеством приложений, и позволяет вам придерживаться методологии Twelve Factor.
Лично я предпочитаю использовать envyable (видимо, это неудивительно, поскольку он возник из наших методологий на моем прошлом месте работы). Мне нравится удобство файла yaml в каталоге config в отличие от скрытого файла .env. Мне также нравится, что он работает во всех Ruby-приложениях и что, по сути, он очень прост. Ваши предпочтения могут оказаться Figaro с его дополнительными функциями или dotenv, который является самым популярным из трех по данным Ruby Toolbox.
Если у вас есть другой способ загрузки переменных окружения, который я не осветил, я хотел бы услышать о нем и о том, почему вы его выбрали. Оставьте мне комментарий здесь или свяжитесь со мной в Twitter или по электронной почте. И если вы считаете, что envyable слишком прост, я всегда открыт для pull request.
Независимо от выбранного вами метода, вам больше не придется возиться с постоянным экспортом переменных в командной строке или засорять ваши dotfiles. Вы сможете просто приступить к созданию вашего следующего замечательного приложения!