eb_deployer 0.4.4 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -18
- data/CHANGELOG.md +7 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +73 -0
- data/README.md +69 -0
- data/TODOS.md +10 -0
- data/eb_deployer.gemspec +1 -1
- data/lib/eb_deployer.rb +1 -0
- data/lib/eb_deployer/aws_driver/beanstalk.rb +2 -1
- data/lib/eb_deployer/default_config.yml +9 -1
- data/lib/eb_deployer/eb_environment.rb +11 -2
- data/lib/eb_deployer/version.rb +1 -1
- data/lib/generators/eb_deployer/install/install_generator.rb +77 -0
- data/lib/generators/eb_deployer/install/templates/eb_deployer.rake +31 -0
- data/lib/generators/eb_deployer/install/templates/eb_deployer.yml.erb +148 -0
- data/lib/generators/eb_deployer/install/templates/ebextensions/01_postgres_packages.config +5 -0
- data/lib/generators/eb_deployer/install/templates/postgres_rds.json +88 -0
- data/test/aws_driver_stubs.rb +5 -1
- data/test/eb_environment_test.rb +6 -0
- data/test/rails_generators_test.rb +67 -0
- metadata +13 -4
data/.gitignore
CHANGED
@@ -1,22 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
.config
|
5
|
-
.yardoc
|
6
|
-
Gemfile.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
|
-
coverage
|
10
|
-
doc/
|
11
|
-
lib/bundler/man
|
12
|
-
pkg
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
1
|
+
/pkg
|
2
|
+
/test/tmp
|
3
|
+
/tmp
|
18
4
|
/.rvmrc
|
19
|
-
_site
|
20
5
|
/samples/jruby_rails4/jruby_rails4.war
|
21
6
|
/samples/jruby_rails4/public/assets/*
|
22
7
|
/TAGS
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.4.5
|
2
|
+
====
|
3
|
+
* Rails 3+ support: Rails Generator to install default configurations with
|
4
|
+
Postgres RDS resource and everything need for blue-green
|
5
|
+
deployment
|
6
|
+
* Add ability to tag beanstalk environment (from @pmcfadden)
|
7
|
+
|
1
8
|
0.4.4
|
2
9
|
=====
|
3
10
|
* Fix S3 upload on Windows.
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
eb_deployer (0.4.4)
|
5
|
+
aws-sdk (>= 1.33.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionpack (3.2.18)
|
11
|
+
activemodel (= 3.2.18)
|
12
|
+
activesupport (= 3.2.18)
|
13
|
+
builder (~> 3.0.0)
|
14
|
+
erubis (~> 2.7.0)
|
15
|
+
journey (~> 1.0.4)
|
16
|
+
rack (~> 1.4.5)
|
17
|
+
rack-cache (~> 1.2)
|
18
|
+
rack-test (~> 0.6.1)
|
19
|
+
sprockets (~> 2.2.1)
|
20
|
+
activemodel (3.2.18)
|
21
|
+
activesupport (= 3.2.18)
|
22
|
+
builder (~> 3.0.0)
|
23
|
+
activesupport (3.2.18)
|
24
|
+
i18n (~> 0.6, >= 0.6.4)
|
25
|
+
multi_json (~> 1.0)
|
26
|
+
aws-sdk (1.42.0)
|
27
|
+
json (~> 1.4)
|
28
|
+
nokogiri (>= 1.4.4)
|
29
|
+
builder (3.0.4)
|
30
|
+
erubis (2.7.0)
|
31
|
+
hike (1.2.3)
|
32
|
+
i18n (0.6.9)
|
33
|
+
journey (1.0.4)
|
34
|
+
json (1.8.1)
|
35
|
+
mini_portile (0.6.0)
|
36
|
+
multi_json (1.10.1)
|
37
|
+
nokogiri (1.6.2.1)
|
38
|
+
mini_portile (= 0.6.0)
|
39
|
+
rack (1.4.5)
|
40
|
+
rack-cache (1.2)
|
41
|
+
rack (>= 0.4)
|
42
|
+
rack-ssl (1.3.4)
|
43
|
+
rack
|
44
|
+
rack-test (0.6.2)
|
45
|
+
rack (>= 1.0)
|
46
|
+
railties (3.2.18)
|
47
|
+
actionpack (= 3.2.18)
|
48
|
+
activesupport (= 3.2.18)
|
49
|
+
rack-ssl (~> 1.3.2)
|
50
|
+
rake (>= 0.8.7)
|
51
|
+
rdoc (~> 3.4)
|
52
|
+
thor (>= 0.14.6, < 2.0)
|
53
|
+
rake (10.3.2)
|
54
|
+
rdoc (3.9.5)
|
55
|
+
redcarpet (3.0.0)
|
56
|
+
sprockets (2.2.2)
|
57
|
+
hike (~> 1.2)
|
58
|
+
multi_json (~> 1.0)
|
59
|
+
rack (~> 1.0)
|
60
|
+
tilt (~> 1.1, != 1.3.0)
|
61
|
+
thor (0.19.1)
|
62
|
+
tilt (1.4.1)
|
63
|
+
yard (0.8.7.3)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
eb_deployer!
|
70
|
+
railties (= 3.2.18)
|
71
|
+
rake
|
72
|
+
redcarpet
|
73
|
+
yard
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# EbDeployer [![Build Status](https://travis-ci.org/ThoughtWorksStudios/eb_deployer.png?branch=master)](https://travis-ci.org/ThoughtWorksStudios/eb_deployer)
|
2
|
+
[From Thoughtworks Mingle Team](http://getmingle.io)
|
2
3
|
|
3
4
|
Low friction deployments should be a breeze. Elastic Beanstalk provides a great foundation for performing Blue-Green deployments, and EbDeployer add a missing link to automate the whole flow out of box.
|
4
5
|
|
@@ -22,6 +23,9 @@ Create an AWS IAM user for deploy and give it privilege to operate Elastic Beans
|
|
22
23
|
|
23
24
|
You need to package your application for Elastic Beanstalk stack first. For Java app a warball is appropriate. For Ruby on Rails app a tar.gz file is good. You can also package a Rails/Sinatra app as a war ball using warbler and deploy to Java stack. (Please remember to run rake assets:precompile first for a rails app.)
|
24
25
|
|
26
|
+
If you were deploying to Elastic Beanstalk Ruby stack, simply zip your codebase is good enough, for example:
|
27
|
+
|
28
|
+
$ git ls-files | zip your-app-name.zip -@
|
25
29
|
|
26
30
|
### Step Three: Generate configuration and Configure deployment process
|
27
31
|
|
@@ -84,6 +88,71 @@ Later tutorials coming soon will cover
|
|
84
88
|
|
85
89
|
Take a look at code if you can not wait for the documentation.
|
86
90
|
|
91
|
+
## Rails 3+ support
|
92
|
+
|
93
|
+
EbDeployer ships with a Rails 3+ generator since version 0.4.5.
|
94
|
+
|
95
|
+
### Install
|
96
|
+
|
97
|
+
Add eb_deployer to your Gemfile
|
98
|
+
|
99
|
+
gem 'eb_deployer'
|
100
|
+
|
101
|
+
Setup AWS credentials:
|
102
|
+
|
103
|
+
$ export AWS_ACCESS_KEY_ID=xxx
|
104
|
+
$ export AWS_SECRET_ACCESS_KEY=xxx
|
105
|
+
|
106
|
+
### Initial configurations and rake tasks
|
107
|
+
|
108
|
+
Run Rails generator to generate configurations and rake file:
|
109
|
+
|
110
|
+
rails generate eb_deployer:install
|
111
|
+
|
112
|
+
It will setup AWS Elastic Beanstalk blue-green deployment configuration with a Postgres RDS instance as your Rails' backend database.
|
113
|
+
The followings are details:
|
114
|
+
|
115
|
+
* Add file "lib/tasks/eb_deployer.rake", please run "rake -T eb" for tasks description. These tasks are simple and designed for you to customize.
|
116
|
+
* Add file "config/eb_deployer.yml", it includes basic blue-green configurations with a Postgres RDS instance resource.
|
117
|
+
* Add file "config/rds.json", it is a CloudFormation template file which provisions the Postgres RDS instance. A separated CloudFormation stack maintains all resources that are shared between different Elastic Beanstalk environments in blue-green deployment. Notice: each eb_deployer environment will create one.
|
118
|
+
* Add "gem 'pg'" to your Gemfile, as this initial configuration is hooking up with a Postgres RDS instance, we need postgres driver.
|
119
|
+
* Add file ".ebextenstions/01_postgres_packages.config", which installs Postgres dev packages on EC2 instances, so that we can build gem "pg" on your EC2 machine after deployed.
|
120
|
+
* Add a new production database configuration into "config/database.yml" file. Your original production configuration will be commented out.
|
121
|
+
|
122
|
+
### Deploy
|
123
|
+
|
124
|
+
Add all files that need to be deployed into your Git repository, because we will simply use "git ls-files" to find all files need to be packaged.
|
125
|
+
|
126
|
+
Deploy a dev environment for testing your application deployment:
|
127
|
+
|
128
|
+
rake eb:deploy
|
129
|
+
|
130
|
+
Then, when you're ready to deploy a production environment:
|
131
|
+
|
132
|
+
EB_DEPLOYER_ENV=production rake eb:deploy
|
133
|
+
|
134
|
+
## EbDeployer environment
|
135
|
+
|
136
|
+
There are so many things called environment:
|
137
|
+
|
138
|
+
* Rails environment: development, test, production
|
139
|
+
* Elastic Beanstalk environment
|
140
|
+
* Development environment
|
141
|
+
* Staging environment
|
142
|
+
* Production environment
|
143
|
+
|
144
|
+
An EbDeployer environment is your application running environment (= your running application + infrastructure), e.g. staging environment, production environment.
|
145
|
+
All EbDeployer environments including dev environment are deployed as Rails production environment.
|
146
|
+
|
147
|
+
What is different between EbDeployer environment and Elastic Beanstalk environment?
|
148
|
+
|
149
|
+
* There are 2 level concepts in Elastic Beanstalk: Application and Environment
|
150
|
+
* EbDeployer environment sits between Elastic Beanstalk Application and Elastic Beanstalk Environment:
|
151
|
+
* One Elastic Beanstalk Application has many EbDeployer environments: dev, staging, production, or whatever names you like.
|
152
|
+
* Depending on deployment strategy, one EbDeployer environment has one or more Elastic Beanstalk environments
|
153
|
+
* For 'inplace-update' deployment strategy, it's one Elastic Beanstalk environment.
|
154
|
+
* For 'blue-green' deployment strategy, it's two Elastic Beanstalk environments.
|
155
|
+
* You should consider an Elastic Beanstalk environment is designed to be replacable (by another Elastic Beanstalk environment).
|
87
156
|
|
88
157
|
## Contributing
|
89
158
|
|
data/TODOS.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
* Support warmup_script option, which runs after smoke test to enhance smoothness of DNS switching in Blue Green deployment.
|
2
|
+
* Wait for all auto scaling group to reach MIN size before running smoke tests in Blue Green deployment. This will make sure DNS switching not generating 50x error under big load, even without warmup steps.
|
3
|
+
* Refactoring: extract Config class wrapping config defaut and merging logic.
|
4
|
+
* Make clear solution_stack is a creation only option in document
|
5
|
+
* Updating an EB environment with a different solution_stack should give warning
|
6
|
+
* Remove all old environment settings to keep settings always sync up
|
7
|
+
* Make it possible to provide an environment specific components settings
|
8
|
+
* Support smoke_test_script option
|
9
|
+
* Document for how to use components
|
10
|
+
* Document for how to use inactive-settings
|
data/eb_deployer.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.homepage = "https://github.com/ThoughtWorksStudios/eb_deployer"
|
10
10
|
gem.license = 'MIT'
|
11
11
|
|
12
|
-
gem.add_runtime_dependency 'aws-sdk'
|
12
|
+
gem.add_runtime_dependency 'aws-sdk', '>= 1.33.0'
|
13
13
|
|
14
14
|
gem.files = `git ls-files`.split($\).reject {|f| f =~ /^samples\// }
|
15
15
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
data/lib/eb_deployer.rb
CHANGED
@@ -40,7 +40,7 @@ module EbDeployer
|
|
40
40
|
alive_envs(app_name).collect { |env| env[:environment_name] }
|
41
41
|
end
|
42
42
|
|
43
|
-
def create_environment(app_name, env_name, stack_name, cname_prefix, version, tier, settings)
|
43
|
+
def create_environment(app_name, env_name, stack_name, cname_prefix, version, tier, tags, settings)
|
44
44
|
request = {
|
45
45
|
:application_name => app_name,
|
46
46
|
:environment_name => env_name,
|
@@ -48,6 +48,7 @@ module EbDeployer
|
|
48
48
|
:version_label => version,
|
49
49
|
:option_settings => settings,
|
50
50
|
:tier => environment_tier(tier),
|
51
|
+
:tags => tags,
|
51
52
|
:cname_prefix => cname_prefix
|
52
53
|
}
|
53
54
|
|
@@ -4,7 +4,7 @@ application: <%= app_name %>
|
|
4
4
|
# common settings for all environments
|
5
5
|
common:
|
6
6
|
# Solution stack for elastic beanstalk, default is 64bit tomcat 7 for JAVA app
|
7
|
-
# solution_stack_name: 64bit Amazon Linux 2014.
|
7
|
+
# solution_stack_name: 64bit Amazon Linux 2014.03 v1.0.3 running Tomcat 7 Java 7
|
8
8
|
|
9
9
|
# Tier name for environments. Current supported values are WebServer and Worker
|
10
10
|
# tier: WebServer
|
@@ -37,6 +37,14 @@ common:
|
|
37
37
|
# you override it to 'on' for production environment.
|
38
38
|
# phoenix_mode: false
|
39
39
|
|
40
|
+
# The tags you would like to be associated with your resources.
|
41
|
+
# These tags will only be used when you first launch an environment. If you are using
|
42
|
+
# phoenix_mode set as true each time you deploy you will get a new environment and therefore
|
43
|
+
# any changes to your tags. If phoenix_mode is false then it will only use your tags on the
|
44
|
+
# initial deploy.
|
45
|
+
# tags:
|
46
|
+
# my_tag_key: my_tag_value
|
47
|
+
|
40
48
|
# Specifies the maximum number of versions to keep. Older versions are removed
|
41
49
|
# and deleted from the S3 source bucket as well. If specified as zero or not
|
42
50
|
# specified, all versions will be kept. If a version_prefix is given, only removes
|
@@ -65,9 +65,10 @@ module EbDeployer
|
|
65
65
|
|
66
66
|
def create_eb_env(settings, version_label)
|
67
67
|
solution_stack = @creation_opts[:solution_stack]
|
68
|
+
tags = convert_tags_hash_to_array(@creation_opts.delete(:tags))
|
68
69
|
validate_solutions_stack(solution_stack)
|
69
70
|
with_polling_events(/Successfully launched environment/i) do
|
70
|
-
@bs.create_environment(@app, @name, solution_stack, @creation_opts[:cname_prefix], version_label, @creation_opts[:tier], settings)
|
71
|
+
@bs.create_environment(@app, @name, solution_stack, @creation_opts[:cname_prefix], version_label, @creation_opts[:tier], tags, settings)
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -104,6 +105,14 @@ module EbDeployer
|
|
104
105
|
end
|
105
106
|
end
|
106
107
|
|
108
|
+
def convert_tags_hash_to_array tags
|
109
|
+
tags ||= {}
|
110
|
+
tags.inject([]) do |arr, (k, v)|
|
111
|
+
arr << {:key => k, :value => v}
|
112
|
+
arr
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
107
116
|
def wait_for_env_become_healthy
|
108
117
|
Timeout.timeout(600) do
|
109
118
|
current_health_status = @bs.environment_health_state(@app, @name)
|
@@ -124,7 +133,7 @@ module EbDeployer
|
|
124
133
|
|
125
134
|
def default_create_options
|
126
135
|
{
|
127
|
-
:solution_stack => "64bit Amazon Linux 2014.
|
136
|
+
:solution_stack => "64bit Amazon Linux 2014.03 v1.0.3 running Tomcat 7 Java 7",
|
128
137
|
:smoke_test => Proc.new {},
|
129
138
|
:tier => 'WebServer'
|
130
139
|
}
|
data/lib/eb_deployer/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'eb_deployer/default_config'
|
3
|
+
require 'aws/elastic_beanstalk'
|
4
|
+
|
5
|
+
module EbDeployer
|
6
|
+
module Generators
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
8
|
+
DEFAULT_STACK_NAME = '64bit Amazon Linux 2014.03 v1.0.3 running Ruby 2.0 (Puma)'
|
9
|
+
source_root File.expand_path("../templates", __FILE__)
|
10
|
+
|
11
|
+
def do_install
|
12
|
+
in_root do
|
13
|
+
copy_file 'eb_deployer.rake', 'lib/tasks/eb_deployer.rake'
|
14
|
+
template 'eb_deployer.yml.erb', 'config/eb_deployer.yml'
|
15
|
+
setup_database
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def setup_database
|
21
|
+
gem 'pg'
|
22
|
+
setup_database_yml
|
23
|
+
copy_file 'postgres_rds.json', 'config/rds.json'
|
24
|
+
directory 'ebextensions', '.ebextensions'
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_database_yml
|
28
|
+
gsub_file('config/database.yml', /^production:.+/m) do |match|
|
29
|
+
prod_start = false
|
30
|
+
match.split("\n").map do |l|
|
31
|
+
case l
|
32
|
+
when /^production/
|
33
|
+
prod_start = true
|
34
|
+
"# #{l}"
|
35
|
+
when /^\s+/
|
36
|
+
prod_start ? "# #{l}" : l
|
37
|
+
else
|
38
|
+
prod_start = false
|
39
|
+
l
|
40
|
+
end
|
41
|
+
end.join("\n")
|
42
|
+
end
|
43
|
+
append_to_file('config/database.yml', <<-YAML)
|
44
|
+
|
45
|
+
|
46
|
+
production:
|
47
|
+
adapter: postgresql
|
48
|
+
database: <%= ENV['DATABASE_NAME'] || '#{app_name}_production' %>
|
49
|
+
host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
|
50
|
+
port: <%= ENV['DATABASE_PORT'] || 5432 %>
|
51
|
+
username: <%= ENV['DATABASE_USERNAME'] || #{ENV['USER'].inspect} %>
|
52
|
+
password: <%= ENV['DATABASE_PASSWORD'] %>
|
53
|
+
min_messages: ERROR
|
54
|
+
YAML
|
55
|
+
end
|
56
|
+
def db_password
|
57
|
+
"PleaseChangeMe"
|
58
|
+
end
|
59
|
+
|
60
|
+
def solution_stack_name
|
61
|
+
AWS::ElasticBeanstalk.new.client.list_available_solution_stacks[:solution_stacks].find do |s|
|
62
|
+
s =~ /Amazon Linux/ && s =~ /running Ruby 2.0 \(Puma\)/
|
63
|
+
end
|
64
|
+
rescue
|
65
|
+
'64bit Amazon Linux 2014.03 v1.0.4 running Ruby 2.0 (Puma)'
|
66
|
+
end
|
67
|
+
|
68
|
+
def alphanumeric_name
|
69
|
+
app_name.gsub(/-/, '')
|
70
|
+
end
|
71
|
+
|
72
|
+
def app_name
|
73
|
+
File.basename(Dir.pwd).downcase.gsub(/[^0-9a-z]/, '-').gsub(/--/, '-')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
namespace :eb do
|
2
|
+
def eb_deployer_env
|
3
|
+
ENV['EB_DEPLOYER_ENV'] || 'dev'
|
4
|
+
end
|
5
|
+
|
6
|
+
def eb_deployer_package
|
7
|
+
name = File.basename(Dir.pwd).downcase.gsub(/[^0-9a-z]/, '-').gsub(/--/, '-')
|
8
|
+
"tmp/#{name}.zip"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Remove the package file we generated."
|
12
|
+
task :clean do
|
13
|
+
sh "rm -rf #{eb_deployer_package}"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Build package for eb_deployer to deploy to a Ruby environment in tmp directory. It zips all file list by 'git ls-files'"
|
17
|
+
task :package => [:clean, :environment] do
|
18
|
+
sh "git ls-files | zip #{eb_deployer_package} -@"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Deploy package we built in tmp directory. default to dev environment, specify environment variable EB_DEPLOYER_ENV to override, for example: EB_DEPLOYER_ENV=production rake eb:deploy."
|
22
|
+
task :deploy => [:package] do
|
23
|
+
app_name = Rails.application.class.parent_name.downcase
|
24
|
+
sh "eb_deploy -p #{eb_deployer_package} -e #{eb_deployer_env}"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Destroy Elastic Beanstalk environments. It won't destroy resources defined in eb_deployer.yml. Default to dev environment, specify EB_DEPLOYER_ENV to override."
|
28
|
+
task :destroy do
|
29
|
+
sh "eb_deploy -d -e #{eb_deployer_env}"
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# applicaiton name
|
2
|
+
application: <%= app_name %>
|
3
|
+
|
4
|
+
# common settings for all environments
|
5
|
+
common:
|
6
|
+
# Solution stack for elastic beanstalk, default is 64bit tomcat 7 for JAVA app
|
7
|
+
solution_stack_name: <%= solution_stack_name %>
|
8
|
+
|
9
|
+
# Tier name for environments. Current supported values are WebServer and Worker
|
10
|
+
# tier: WebServer
|
11
|
+
|
12
|
+
# AWS region to deploy. Default to us-east-1
|
13
|
+
# region: us-west-1
|
14
|
+
|
15
|
+
# There are two deployment strategies: 'blue-green' or 'inplace-update'.
|
16
|
+
# Blue green deployments keep two elastic beanstalk environments and always deploy to
|
17
|
+
# inactive one, to achieve zero downtime.
|
18
|
+
# Inplace-update strategy will only keep one environment, and update the version inplace on
|
19
|
+
# deploy. Inplace-update will save resources but will suffer from downtime.
|
20
|
+
# (All old environments need be destroyed when you switching between strategies.)
|
21
|
+
# Default strategy is 'blue-green'.
|
22
|
+
# strategy: blue-green
|
23
|
+
|
24
|
+
# Name of s3 bucket where uploaded application packages will be stored.
|
25
|
+
# Note that the string ".packages" will be added as a suffix to your bucket.
|
26
|
+
# So, if "thoughtworks.simple" is passed as the bucket name, the actual s3 bucket
|
27
|
+
# name will be thoughtworks.simple.packages. Default to application name.
|
28
|
+
# package_bucket: my-s3-bucket
|
29
|
+
|
30
|
+
# If phoenix mode is turned 'on', it will terminate the old elastic
|
31
|
+
# beanstalk environment and recreate a new one on deploy. For blue-green
|
32
|
+
# deployment it will terminate the inactive environment first then
|
33
|
+
# recreate it. This is useful to avoid configuration drift and
|
34
|
+
# accumulating state on the ec2 instances. Also it has the benefit of
|
35
|
+
# keeping your ec2 instance system package upto date, because everytime ec2
|
36
|
+
# instance boots up from AMI it does a system update. Default is 'off' but we suggest
|
37
|
+
# you override it to 'on' for production environment.
|
38
|
+
# phoenix_mode: false
|
39
|
+
|
40
|
+
# Specifies the maximum number of versions to keep. Older versions are removed
|
41
|
+
# and deleted from the S3 source bucket as well. If specified as zero or not
|
42
|
+
# specified, all versions will be kept. If a version_prefix is given, only removes
|
43
|
+
# version starting with the prefix.
|
44
|
+
# keep_latest: 200
|
45
|
+
|
46
|
+
# Specifies a prefix to prepend to the version label.
|
47
|
+
# This can be useful if you want to use different binaries for different
|
48
|
+
# environments.
|
49
|
+
# version_prefix:
|
50
|
+
|
51
|
+
# Generating version label for package to be deployed. A readable version label will
|
52
|
+
# provide better traceablity of your deployment process.
|
53
|
+
# By default setting is:
|
54
|
+
# version_label: <%%= package_digest %>
|
55
|
+
# which means using MD5 digest of the package file. If you deploy using build
|
56
|
+
# pipeline tool such as GO, switching to pipline counter is highly suggested to
|
57
|
+
# increase the readability. Following example will read pipeline counter from environment
|
58
|
+
# variable with a fall back to digest for local deployment:
|
59
|
+
# version_label: <%%= ENV['GO_PIPELINE_COUNTER'] || package_digest %>
|
60
|
+
|
61
|
+
|
62
|
+
# Smoke test value should be a piece of ruby code with access to single variable
|
63
|
+
# "host_name" -- environment DNS name. Smoke test snippet will be evaluated at
|
64
|
+
# the end of the deployment for inplace-update deployment. For blue-green
|
65
|
+
# deployment it will run after inactive environment update is completed and before
|
66
|
+
# switching over.
|
67
|
+
# Defining a smoke test is highly recommended for serious usage. By default we use
|
68
|
+
# The simplest one that just be checking server landing page using curl, e.g.
|
69
|
+
smoke_test: |
|
70
|
+
curl_http_code = "curl -s -o /dev/null -w \"%{http_code}\" http://#{host_name}"
|
71
|
+
Timeout.timeout(600) do
|
72
|
+
until ['200', '301', '302'].include?(`#{curl_http_code}`.strip)
|
73
|
+
sleep 5
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Elastic Beanstalk settings that will apply to the environments you are
|
78
|
+
# deploying.
|
79
|
+
# For all available options take a look at
|
80
|
+
# http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html
|
81
|
+
option_settings:
|
82
|
+
# Following is an example of set EC2 ssh key name. This allow you ssh into the ec2
|
83
|
+
# instance. See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html
|
84
|
+
# - namespace: aws:autoscaling:launchconfiguration
|
85
|
+
# option_name: EC2KeyName
|
86
|
+
# value: <my-ec2-key-name>
|
87
|
+
|
88
|
+
# Following is an example which changes EC2 instance type
|
89
|
+
# from t1.micro (default) to m1.small. Instances with t1.micro type sometime
|
90
|
+
# are not very responsible, so m1.small is suggested for saving time.
|
91
|
+
# But if you care about the marginal cost difference you can comment this out to
|
92
|
+
# go back to t1.micro.
|
93
|
+
- namespace: aws:autoscaling:launchconfiguration
|
94
|
+
option_name: InstanceType
|
95
|
+
value: m1.small
|
96
|
+
|
97
|
+
- namespace: aws:elasticbeanstalk:application:environment
|
98
|
+
option_name: DATABASE_NAME
|
99
|
+
value: <%= alphanumeric_name %>
|
100
|
+
- namespace: aws:elasticbeanstalk:application:environment
|
101
|
+
option_name: DATABASE_USERNAME
|
102
|
+
value: <%= alphanumeric_name %>
|
103
|
+
- namespace: aws:elasticbeanstalk:application:environment
|
104
|
+
option_name: DATABASE_PASSWORD
|
105
|
+
value: <%= db_password %>
|
106
|
+
|
107
|
+
|
108
|
+
# If resources specified, eb_deployer will use the CloudFormation
|
109
|
+
# template you provide to create a default CloudFormation stack with
|
110
|
+
# name <application_name>-<env-name> for the environment current
|
111
|
+
# deploying. And Outputs of the CloudFormation can be mapped to Elastic Beanstalk
|
112
|
+
# options settings.
|
113
|
+
# keys:
|
114
|
+
# template => CloudFormation template file with JSON format
|
115
|
+
# inputs => A Hash, input values for the CloudFormation template
|
116
|
+
# outputs => A Hash with key map to your CloudFormation template outputs and value as elastic beanstalk settings namespace and option_name.
|
117
|
+
# capabilities => An array. You need set it to ['CAPABILITY_IAM'] if the
|
118
|
+
# template include IAM Instance Profile.
|
119
|
+
resources:
|
120
|
+
# Creating a RDS instance by CloudFormation, so that database will not hook up with any ElasticBeanstalk environment
|
121
|
+
template: config/rds.json
|
122
|
+
inputs:
|
123
|
+
DBName: <%= alphanumeric_name %>
|
124
|
+
DBUser: <%= alphanumeric_name %>
|
125
|
+
DBPassword: <%= db_password %>
|
126
|
+
outputs:
|
127
|
+
RDSPassSecurityGroup:
|
128
|
+
namespace: aws:autoscaling:launchconfiguration
|
129
|
+
option_name: SecurityGroups
|
130
|
+
RDSHost:
|
131
|
+
namespace: aws:elasticbeanstalk:application:environment
|
132
|
+
option_name: DATABASE_HOST
|
133
|
+
RDSPort:
|
134
|
+
namespace: aws:elasticbeanstalk:application:environment
|
135
|
+
option_name: DATABASE_PORT
|
136
|
+
|
137
|
+
# You can define environment here. Each environment can overriden any common settings
|
138
|
+
environments:
|
139
|
+
dev:
|
140
|
+
# overriding common settings
|
141
|
+
strategy: inplace-update
|
142
|
+
production:
|
143
|
+
option_settings:
|
144
|
+
# example for overriding common option_settings: providing least redundancy
|
145
|
+
# in production environment.
|
146
|
+
# - namespace: aws:autoscaling:asg
|
147
|
+
# option_name: MinSize
|
148
|
+
# value: "2"
|
@@ -0,0 +1,88 @@
|
|
1
|
+
{
|
2
|
+
"Outputs": {
|
3
|
+
"RDSHost": {
|
4
|
+
"Description": "Database endpoint address",
|
5
|
+
"Value": { "Fn::GetAtt": ["RDSDatabase", "Endpoint.Address"] }
|
6
|
+
},
|
7
|
+
"RDSPort": {
|
8
|
+
"Description": "Database endpoint port",
|
9
|
+
"Value": { "Fn::GetAtt": ["RDSDatabase", "Endpoint.Port"] }
|
10
|
+
},
|
11
|
+
"RDSPassSecurityGroup": {
|
12
|
+
"Description": "Security group assign to ec2 instance that need access to rds instance",
|
13
|
+
"Value": {
|
14
|
+
"Ref": "RDSPassSecurityGroup"
|
15
|
+
}
|
16
|
+
}
|
17
|
+
},
|
18
|
+
|
19
|
+
"Parameters": {
|
20
|
+
"DBUser": {
|
21
|
+
"NoEcho": "false",
|
22
|
+
"Description": "The name of master user for the client DB Instance.",
|
23
|
+
"Type": "String",
|
24
|
+
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters"
|
25
|
+
},
|
26
|
+
|
27
|
+
"DBName": {
|
28
|
+
"NoEcho": "false",
|
29
|
+
"Description": "The DB Name of the RDS instance",
|
30
|
+
"Type": "String",
|
31
|
+
"ConstraintDescription": "must contain only alphanumeric characters"
|
32
|
+
},
|
33
|
+
|
34
|
+
"DBPassword": {
|
35
|
+
"NoEcho": "true",
|
36
|
+
"Description": "The master password for the DB instance.",
|
37
|
+
"Type": "String",
|
38
|
+
"ConstraintDescription": "must contain only alphanumeric characters"
|
39
|
+
}
|
40
|
+
},
|
41
|
+
|
42
|
+
"Resources": {
|
43
|
+
"RDSDBSecurityGroup": {
|
44
|
+
"Type": "AWS::RDS::DBSecurityGroup",
|
45
|
+
"Properties": {
|
46
|
+
"GroupDescription": "Enable database access to Beanstalk application",
|
47
|
+
"DBSecurityGroupIngress": {
|
48
|
+
"EC2SecurityGroupName": {
|
49
|
+
"Ref": "RDSPassSecurityGroup"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
},
|
54
|
+
|
55
|
+
"RDSDatabase": {
|
56
|
+
"Type": "AWS::RDS::DBInstance",
|
57
|
+
"DeletionPolicy": "Delete",
|
58
|
+
"Properties": {
|
59
|
+
"MasterUsername": {
|
60
|
+
"Ref": "DBUser"
|
61
|
+
},
|
62
|
+
"DBSecurityGroups": [
|
63
|
+
{
|
64
|
+
"Ref": "RDSDBSecurityGroup"
|
65
|
+
}
|
66
|
+
],
|
67
|
+
"DBInstanceClass": "db.m1.small",
|
68
|
+
"AllocatedStorage": "5",
|
69
|
+
"MultiAZ": "false",
|
70
|
+
"EngineVersion": "9.3.3",
|
71
|
+
"DBName": {
|
72
|
+
"Ref": "DBName"
|
73
|
+
},
|
74
|
+
"MasterUserPassword": {
|
75
|
+
"Ref": "DBPassword"
|
76
|
+
},
|
77
|
+
"Engine": "postgres"
|
78
|
+
}
|
79
|
+
},
|
80
|
+
|
81
|
+
"RDSPassSecurityGroup": {
|
82
|
+
"Type": "AWS::EC2::SecurityGroup",
|
83
|
+
"Properties": {
|
84
|
+
"GroupDescription": "SecurityGroup access RDS database."
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
data/test/aws_driver_stubs.rb
CHANGED
@@ -22,7 +22,7 @@ class EBStub
|
|
22
22
|
@apps.include?(app)
|
23
23
|
end
|
24
24
|
|
25
|
-
def create_environment(app, env, solution_stack, cname_prefix, version, tier, settings)
|
25
|
+
def create_environment(app, env, solution_stack, cname_prefix, version, tier, tags, settings)
|
26
26
|
raise 'cname prefix is not avaible' if @envs.values.detect { |env| env[:cname_prefix] == cname_prefix }
|
27
27
|
raise "env name #{env} is longer than 23 chars" if env.size > 23
|
28
28
|
raise "app not exists" unless application_exists?(app)
|
@@ -33,6 +33,7 @@ class EBStub
|
|
33
33
|
:version => version,
|
34
34
|
:cname_prefix => cname_prefix,
|
35
35
|
:tier => tier,
|
36
|
+
:tags => tags,
|
36
37
|
:settings => settings }
|
37
38
|
set_env_ready(app, env, false)
|
38
39
|
end
|
@@ -150,6 +151,9 @@ class EBStub
|
|
150
151
|
@envs[env_key(app_name, env_name)][:tier]
|
151
152
|
end
|
152
153
|
|
154
|
+
def environment_tags(app_name, env_name)
|
155
|
+
@envs[env_key(app_name, env_name)][:tags]
|
156
|
+
end
|
153
157
|
|
154
158
|
def environment_settings(app_name, env_name)
|
155
159
|
@envs[env_key(app_name, env_name)][:settings]
|
data/test/eb_environment_test.rb
CHANGED
@@ -26,6 +26,12 @@ class EbEnvironmentTest < MiniTest::Unit::TestCase
|
|
26
26
|
assert_equal({s1: 'v1' }, @eb_driver.environment_settings('myapp', t('production', 'myapp')))
|
27
27
|
end
|
28
28
|
|
29
|
+
def test_deploy_should_include_tags
|
30
|
+
env = EbDeployer::EbEnvironment.new("myapp", "production", @eb_driver, {:tags => {:my_tag => 'my_value', :tag2 => 'value2'}})
|
31
|
+
env.deploy("version1")
|
32
|
+
assert_equal [{:key => :my_tag, :value => 'my_value'}, {:key => :tag2, :value => 'value2'}], @eb_driver.environment_tags('myapp', t('production', 'myapp'))
|
33
|
+
end
|
34
|
+
|
29
35
|
def test_should_run_smoke_test_after_deploy
|
30
36
|
smoked_host = nil
|
31
37
|
env = EbDeployer::EbEnvironment.new("myapp", "production", @eb_driver, :smoke_test => Proc.new { |host| smoked_host = host })
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'rails'
|
3
|
+
require 'shellwords'
|
4
|
+
require 'generators/eb_deployer/install/install_generator'
|
5
|
+
|
6
|
+
class RailsGenratorsTest < Rails::Generators::TestCase
|
7
|
+
tests EbDeployer::Generators::InstallGenerator
|
8
|
+
destination File.expand_path('../../tmp', __FILE__)
|
9
|
+
setup :prepare_destination
|
10
|
+
|
11
|
+
setup do
|
12
|
+
mkdir_p path('config')
|
13
|
+
touch path('config/database.yml')
|
14
|
+
touch path('Gemfile')
|
15
|
+
end
|
16
|
+
|
17
|
+
test "install" do
|
18
|
+
run_generator
|
19
|
+
|
20
|
+
assert_file 'config/eb_deployer.yml'
|
21
|
+
assert_file 'lib/tasks/eb_deployer.rake'
|
22
|
+
|
23
|
+
assert_file 'config/rds.json'
|
24
|
+
assert_file '.ebextensions/01_postgres_packages.config'
|
25
|
+
assert_file 'config/database.yml', /database: <%= ENV\['RDS_DB_NAME'\]/m, /host: <%= ENV\['RDS_HOSTNAME'\]/m
|
26
|
+
assert_file 'Gemfile', /gem "pg"/
|
27
|
+
end
|
28
|
+
|
29
|
+
test "should comment production configuration in database.yml" do
|
30
|
+
File.open(path('config/database.yml'), 'w') do |f|
|
31
|
+
f.write(<<-YAML)
|
32
|
+
development:
|
33
|
+
host: localhost
|
34
|
+
|
35
|
+
production:
|
36
|
+
host: localhost
|
37
|
+
|
38
|
+
test:
|
39
|
+
host: localhost
|
40
|
+
YAML
|
41
|
+
end
|
42
|
+
run_generator
|
43
|
+
assert_file 'config/database.yml', <<-YAML
|
44
|
+
development:
|
45
|
+
host: localhost
|
46
|
+
|
47
|
+
# production:
|
48
|
+
# host: localhost
|
49
|
+
|
50
|
+
test:
|
51
|
+
host: localhost
|
52
|
+
|
53
|
+
production:
|
54
|
+
adapter: postgresql
|
55
|
+
database: <%= ENV['RDS_DB_NAME'] || 'tmp_production' %>
|
56
|
+
host: <%= ENV['RDS_HOSTNAME'] || 'localhost' %>
|
57
|
+
port: <%= ENV['RDS_PORT'] || 5432 %>
|
58
|
+
username: <%= ENV['RDS_USERNAME'] || \"xli\" %>
|
59
|
+
password: <%= ENV['RDS_PASSWORD'] %>
|
60
|
+
min_messages: ERROR
|
61
|
+
YAML
|
62
|
+
end
|
63
|
+
|
64
|
+
def path(*f)
|
65
|
+
File.join(destination_root, *f)
|
66
|
+
end
|
67
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eb_deployer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-06-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 1.33.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,7 +27,7 @@ dependencies:
|
|
27
27
|
requirements:
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version:
|
30
|
+
version: 1.33.0
|
31
31
|
description: For automating Blue-Green deployment flows on Elastic Beanstalk.
|
32
32
|
email:
|
33
33
|
- alex.hal9000@gmail.com
|
@@ -43,9 +43,11 @@ files:
|
|
43
43
|
- .travis.yml
|
44
44
|
- CHANGELOG.md
|
45
45
|
- Gemfile
|
46
|
+
- Gemfile.lock
|
46
47
|
- LICENSE
|
47
48
|
- README.md
|
48
49
|
- Rakefile
|
50
|
+
- TODOS.md
|
49
51
|
- bin/eb_deploy
|
50
52
|
- eb_deployer.gemspec
|
51
53
|
- lib/eb_deployer.rb
|
@@ -73,6 +75,11 @@ files:
|
|
73
75
|
- lib/eb_deployer/utils.rb
|
74
76
|
- lib/eb_deployer/version.rb
|
75
77
|
- lib/eb_deployer/version_cleaner.rb
|
78
|
+
- lib/generators/eb_deployer/install/install_generator.rb
|
79
|
+
- lib/generators/eb_deployer/install/templates/eb_deployer.rake
|
80
|
+
- lib/generators/eb_deployer/install/templates/eb_deployer.yml.erb
|
81
|
+
- lib/generators/eb_deployer/install/templates/ebextensions/01_postgres_packages.config
|
82
|
+
- lib/generators/eb_deployer/install/templates/postgres_rds.json
|
76
83
|
- test/aws_driver_stubs.rb
|
77
84
|
- test/blue_green_deploy_test.rb
|
78
85
|
- test/cloud_formation_provisioner_test.rb
|
@@ -81,6 +88,7 @@ files:
|
|
81
88
|
- test/eb_environment_test.rb
|
82
89
|
- test/inplace_update_deploy_test.rb
|
83
90
|
- test/multi_components_deploy_test.rb
|
91
|
+
- test/rails_generators_test.rb
|
84
92
|
- test/resources_deploy_test.rb
|
85
93
|
- test/smoke_test_test.rb
|
86
94
|
- test/test_helper.rb
|
@@ -122,6 +130,7 @@ test_files:
|
|
122
130
|
- test/eb_environment_test.rb
|
123
131
|
- test/inplace_update_deploy_test.rb
|
124
132
|
- test/multi_components_deploy_test.rb
|
133
|
+
- test/rails_generators_test.rb
|
125
134
|
- test/resources_deploy_test.rb
|
126
135
|
- test/smoke_test_test.rb
|
127
136
|
- test/test_helper.rb
|