Skip to content

Instantly share code, notes, and snippets.

@unosk
Last active November 18, 2015 10:12
Show Gist options
  • Save unosk/f0b1e112108a899865cb to your computer and use it in GitHub Desktop.
Save unosk/f0b1e112108a899865cb to your computer and use it in GitHub Desktop.
lock '3.4.0'
set :application, 'smart2channel'
set :deploy_to, "/opt/#{fetch(:application)}"
set :repo_url, '[email protected]:unosk/smart2channel.git'
set :branch, 'master'
set :scm, :git
set :linked_dirs, %w(log tmp/pids tmp/cache tmp/sockets vendor/bundle public/uploads)
set :format, :pretty
set :log_level, :info
# dotenv
after 'deploy:updating', 'dotenv:upload'
# unicorn
after 'deploy:updated', 'unicorn:unmonitor'
after 'deploy:published', 'unicorn:upgrade'
after 'deploy:published', 'unicorn:monitor'
# sidekiq
after 'deploy:starting', 'sidekiq:quiet'
after 'deploy:updated', 'sidekiq:unmonitor'
after 'deploy:updated', 'sidekiq:stop'
after 'deploy:reverted', 'sidekiq:stop'
after 'deploy:published', 'sidekiq:start'
after 'deploy:published', 'sidekiq:monitor'
namespace :dotenv do
desc 'Upload .env'
task :upload do
on roles(:app, :worker) do
dotenv = fetch(:dotenv)
upload! StringIO.new(dotenv), release_path.join('.env')
end
end
end
namespace :itamae do
desc 'Itamae plan(dry-run)'
task :plan do
run_itamae(dry_run: true)
end
desc 'Itamae apply'
task :apply do
run_itamae(dry_run: false)
end
def run_itamae(dry_run: true)
options = []
options << "--no-color"
options << "--dry-run" if dry_run
options << "--node-json #{node_json}"
on roles(:all) do |server|
run_locally do
with_verbosity Logger::DEBUG do
execute :bundle, :exec, :itamae, :ssh, *recipe_files, *options, *ssh_options(server)
end
end
end
end
def recipe_files
Array(fetch(:itamae_recipe_files))
end
def node_json
node_json = Tempfile.new('capistrano-node-json')
node_json.write(fetch(:itamae_attributes).to_json)
node_json.close
node_json.path
end
def ssh_options(server)
ssh_options = fetch(:ssh_options) || {}
ssh_options.merge!(server.ssh_options || {})
ssh_options[:user] ||= server.user
ssh_options[:port] ||= server.port
ssh_options[:keys] ||= server.keys
ssh_options[:key] = ssh_options[:keys] && ssh_options[:keys].first
options = []
options << "--host #{server.hostname}"
options << "--user #{ssh_options[:user]}" if ssh_options[:user]
options << "--port #{ssh_options[:port]}" if ssh_options[:port]
options << "--key #{ssh_options[:key]}" if ssh_options[:key]
end
end
namespace :monit do
desc 'Monit status'
task :status do
on roles :all do
with_verbosity Logger::DEBUG do
sudo :monit, :status
end
end
end
end
require 'itamae/secrets'
def secrets
@secrets ||= Itamae::Secrets('./ops/secrets')
end
# Itamae
#
set :itamae_recipe_files, %w(./ops/itamae/bootstrap.rb)
set :itamae_attributes, lambda {
{
app: {
environment: fetch(:rails_env),
deploy_to: fetch(:deploy_to),
deploy_as: 'ubuntu',
deploy_id_rsa: secrets[:ec2_id_rsa]
},
unicorn: {
processes: 2,
timeout: 30
},
sidekiq: {
concurrency: 2,
timeout: 180
}
}
}
#
# Terraform
#
set :terraform_local_path, './ops/terraform'
set :terraform_remote_backend, 's3'
set :terraform_remote_backend_config, lambda {
{
bucket: 'smart2channel-ops',
key: 'production.tfstate',
access_key: secrets[:ops_aws_access_key_id],
secret_key: secrets[:ops_aws_secret_access_key],
region: 'ap-northeast-1'
}
}
set :terraform_vars, lambda {
{
aws_access_key: secrets[:ops_aws_access_key_id],
aws_secret_key: secrets[:ops_aws_secret_access_key],
aws_region: 'ap-northeast-1',
ec2_public_key: secrets[:ec2_id_rsa_pub]
}
}
namespace :sidekiq do
%w(start stop quiet restart).each do |action|
desc "Sidekiq #{action}"
task action do
on roles(:worker) do
if test("[ -d #{current_path} ]")
sudo :service, :sidekiq, action
end
end
end
end
%w(monitor unmonitor).each do |action|
desc "Sidekiq #{action}"
task action do
on roles(:app) do
if test("[ -d #{current_path} ]")
sudo :monit, action, :sidekiq
end
end
end
end
end
desc 'SSH login'
task :ssh do
server = roles(:all).first
ssh_options = fetch(:ssh_options) || {}
ssh_options.merge!(server.ssh_options || {})
ssh_options[:user] ||= server.user
ssh_options[:port] ||= server.port
ssh_options[:keys] ||= server.keys
ssh_options[:key] = ssh_options[:keys] && ssh_options[:keys].first
ssh_cmd = 'ssh '
ssh_cmd << "#{ssh_options[:user]}@" if ssh_options[:user]
ssh_cmd << "#{server.hostname}"
ssh_cmd << " -p #{ssh_options[:port]}" if ssh_options[:port]
ssh_cmd << " -i #{ssh_options[:key]}" if ssh_options[:key]
Kernel.system ssh_cmd
end
namespace :terraform do
task :configure do
options = []
options << "-backend=#{fetch(:terraform_remote_backend)}"
options += fetch(:terraform_remote_backend_config).map { |key, value| "-backend-config='#{key}=#{value}'" }
run_terraform :remote, :config, *options
end
desc 'Terraform plan(dry-run)'
task plan: :configure do
run_terraform :plan, terraform_vars
end
desc 'Terraform apply'
task apply: :configure do
run_terraform :apply, terraform_vars
end
def run_terraform(*args)
run_locally do
within fetch(:terraform_local_path) do
with_verbosity Logger::DEBUG do
execute :terraform, *args
end
end
end
end
def terraform_vars
fetch(:terraform_vars).map { |key, value| "-var='#{key}=#{value}'" }
end
end
namespace :unicorn do
%w(start stop restart upgrade).each do |action|
desc "Unicorn #{action}"
task action do
on roles(:app) do
if test("[ -d #{current_path} ]")
sudo :service, :unicorn, action
end
end
end
end
%w(monitor unmonitor).each do |action|
desc "Unicorn #{action}"
task action do
on roles(:app) do
if test("[ -d #{current_path} ]")
sudo :monit, action, :unicorn
end
end
end
end
end
def with_verbosity(output_verbosity)
old_verbosity = SSHKit.config.output_verbosity
begin
SSHKit.config.output_verbosity = output_verbosity
yield
ensure
SSHKit.config.output_verbosity = old_verbosity
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment