Created
February 15, 2014 19:16
-
-
Save jbgo/9023884 to your computer and use it in GitHub Desktop.
Heroku-style config management with capistrano and chef
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set :application, "app_name" | |
set :rails_root, File.expand_path('../..', __FILE__) | |
# ... more custom config | |
require 'capistrano/ext/multistage' | |
set :stages, %w(staging production) | |
set :default_stage, "staging" | |
set :rails_env, -> { stage } | |
# ... more custom config | |
require 'dotenv/capistrano' | |
# ... more custom config | |
load "#{fetch :rails_root}/config/deploy/recipes/config.rb" | |
# ... more custom config |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'chef' | |
require 'chef/knife' | |
before "config:get", "config:load_chef" | |
before "config:set", "config:load_chef" | |
namespace :config do | |
desc "Show application config" | |
task :default do | |
top.config.get | |
end | |
desc "Get application config" | |
task :get do | |
env = data_bag_item[stage.to_s]['env'] | |
env.keys.sort.each do |k| | |
puts "#{k}=#{env[k]}" | |
end | |
end | |
desc "Set application config" | |
task :set do | |
item = data_bag_item | |
item[stage.to_s]['env'].merge! env_updates_from_args | |
enc = encrypted_data_bag_item item | |
new_item = Chef::DataBagItem.from_hash enc | |
new_item.data_bag('apps') | |
new_item.save | |
top.config.apply | |
end | |
task :apply do | |
wait_for 5, 'waiting for config changes to propagate...' | |
sudo 'chef-client' | |
top.deploy.restart | |
end | |
task :load_chef do | |
knife = Chef::Knife.new | |
Chef::Config[:verbosity] = 1 | |
knife.configure_chef | |
end | |
def wait_for(t=5, message=nil) | |
logger.info message if message | |
t.times { sleep 1; print '.' } | |
print "\n" | |
end | |
def get_args_for_task(task_name) | |
args = ARGV.dup | |
_ = args.shift until _ == task_name | |
args | |
end | |
def env_updates_from_args | |
args = get_args_for_task 'config:set' | |
Hash[args.map do |arg| | |
m = arg.match(/\A(\w+)=(.*)\z/) | |
raise "Not a valid environment variable: #{arg}" if m.nil? | |
[m[1], m[2]] | |
end] | |
end | |
def encrypted_data_bag_item(item) | |
Chef::EncryptedDataBagItem.encrypt_data_bag_item( | |
item, encrypted_data_bag_secret).to_hash | |
end | |
def data_bag_item | |
@_data_bag_item ||= Chef::EncryptedDataBagItem.load( | |
'apps', 'app_name', encrypted_data_bag_secret).to_hash | |
end | |
def encrypted_data_bag_secret | |
File.read(Chef::Config[:encrytped_data_bag_secret]).chomp | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app_user = node['app_name']['app_user'] | |
stage = node.chef_environment | |
conf = Chef::EncryptedDataBagItem.load('apps', 'app_name')[stage] | |
template "/home/apps/app_name/shared/.env" do | |
source "env.erb" | |
owner app_user | |
group app_user | |
mode '0600' | |
action :create | |
variables(env_vars: conf['env']) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<% @env_vars.each do |key, val| %> | |
<%= key %>=<%= val %> | |
<% end %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"id": "app_name", | |
"production": { | |
"env": { | |
"KEY1": "value1", | |
"KEY2": "value2", | |
} | |
}, | |
"staging": { | |
"env": { | |
"KEY1": "staging-value1", | |
"KEY2": "staging-value2", | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem 'dotenv-rails' | |
group :deployment do | |
gem 'capistrano', '~>2.15' | |
gem 'chef' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment