auto_elasticache 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
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
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in easy_elasticache.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Chad McGimpsey
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # EasyElasticache
2
+
3
+ Automatically start and configure an AWS ElastiCache cluster from an Elastic Beanstalk environment.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'easy_elasticache'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install easy_elasticache
18
+
19
+ ### Configuration
20
+
21
+ Execute the following command to create the `.ebextensions/elasticache.config` and `config/auto_elasticache.yml` files
22
+
23
+ ```bash
24
+ $ auto_elasticache
25
+ ```
26
+
27
+ Change the names of the created resources to match your application and environment, and change the cache size to the appropriate value.
28
+
29
+ ```yaml
30
+ Resources:
31
+ AppNameEnvironmentElastiCache: <<<<<------
32
+ Type: AWS::ElastiCache::CacheCluster
33
+ Properties:
34
+ CacheNodeType: cache.m1.small <<<<<------
35
+ NumCacheNodes: 1
36
+ Engine : memcached
37
+ CacheSecurityGroupNames:
38
+ - Ref: AppNameEnvironmentCacheSecurityGroup <<<<<------
39
+ AppNameEnvironmentCacheSecurityGroup: <<<<<------
40
+ Type: AWS::ElastiCache::SecurityGroup
41
+ Properties:
42
+ Description: "Lock cache down to webserver access only"
43
+ AppNameEnvironmentCacheSecurityGroupIngress: <<<<<------
44
+ Type: AWS::ElastiCache::SecurityGroupIngress
45
+ Properties:
46
+ CacheSecurityGroupName:
47
+ Ref: AppNameEnvironmentCacheSecurityGroup <<<<<------
48
+ EC2SecurityGroupName:
49
+ Ref: AWSEBSecurityGroup
50
+ ```
51
+
52
+ Add the AWS credentials for a IAM user/group that has the access to read Elastic Beanstalk data and create Elasticache instances to the `config/auto_elasticache.yml` file
53
+
54
+ ```yaml
55
+ staging:
56
+ access_key_id: 'my_key_id'
57
+ secret_access_key: 'my_secret_key'
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ Add the following to your environment config file (e.g. `config/environments/staging.rb`)
63
+
64
+ ```ruby
65
+ elasticache = AutoElasticache::Elasticache.new
66
+ config.cache_store = :dalli_store, elasticache.servers
67
+ ```
68
+
69
+ You can also add options
70
+
71
+ ```ruby
72
+ elasticache = AutoElasticache::Elasticache.new
73
+ config.cache_store = :dalli_store,
74
+ elasticache.servers,
75
+ {
76
+ :expires_in => 1.day,
77
+ :socket_timeout => 1,
78
+ :down_retry_delay => 2
79
+ }
80
+ ```
81
+
82
+ ## Contributing
83
+
84
+ 1. Fork it
85
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
86
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
87
+ 4. Push to the branch (`git push origin my-new-feature`)
88
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'auto_elasticache/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "auto_elasticache"
8
+ gem.version = AutoElasticache::VERSION
9
+ gem.authors = ["Chad McGimpsey"]
10
+ gem.email = ["chad.mcgimpsey@gmail.com"]
11
+ gem.description = %q{Automatically start and configure an AWS ElastiCache cluster from an Elastic Beanstalk environment}
12
+ gem.summary = %q{AutoElasticache automatically starts an AWS ElastiCache cluster and configures Rails to use it. This gem requires that you are using AWS Elastic Beanstalk.}
13
+ gem.homepage = "https://github.com/dignoe/auto_elasticache"
14
+
15
+ gem.add_dependency('aws-sdk')
16
+ gem.add_dependency('dalli-elasticache')
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'fileutils'
4
+
5
+ ec_config_content = <<-FILE
6
+ Resources:
7
+ AppNameEnvironmentElastiCache:
8
+ Type: AWS::ElastiCache::CacheCluster
9
+ Properties:
10
+ CacheNodeType: cache.m1.small
11
+ NumCacheNodes: 1
12
+ Engine : memcached
13
+ CacheSecurityGroupNames:
14
+ - Ref: AppNameEnvironmentCacheSecurityGroup
15
+ AppNameEnvironmentCacheSecurityGroup:
16
+ Type: AWS::ElastiCache::SecurityGroup
17
+ Properties:
18
+ Description: "Lock cache down to webserver access only"
19
+ AppNameEnvironmentCacheSecurityGroupIngress:
20
+ Type: AWS::ElastiCache::SecurityGroupIngress
21
+ Properties:
22
+ CacheSecurityGroupName:
23
+ Ref: AppNameEnvironmentCacheSecurityGroup
24
+ EC2SecurityGroupName:
25
+ Ref: AWSEBSecurityGroup
26
+ FILE
27
+
28
+ file = '.ebextensions/elasticache.config'
29
+ if File.exists?(file)
30
+ warn "`#{file}' already exists, overwriting"
31
+ elsif File.exists?(file.downcase)
32
+ warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
33
+ elsif !File.exists?(File.dirname(file))
34
+ warn "[skip] directory `#{File.dirname(file)}' does not exist"
35
+ else
36
+ puts "[add] writing `#{file}'"
37
+ File.open(file, "w") { |f| f.write(ec_config_content) }
38
+ end
39
+
40
+
41
+ aws_credentials_content = <<-FILE
42
+ staging:
43
+ access_key_id: ''
44
+ secret_access_key: ''
45
+ production:
46
+ access_key_id: ''
47
+ secret_access_key: ''
48
+ FILE
49
+
50
+ file = 'config/auto_elasticache.yml'
51
+ if File.exists?(file)
52
+ warn "[skip] `#{file}' already exists"
53
+ elsif File.exists?(file.downcase)
54
+ warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
55
+ elsif !File.exists?(File.dirname(file))
56
+ warn "[skip] directory `#{File.dirname(file)}' does not exist"
57
+ else
58
+ puts "[add] writing `#{file}'"
59
+ File.open(file, "w") { |f| f.write(aws_credentials_content) }
60
+ end
@@ -0,0 +1 @@
1
+ require 'auto_elasticache/elasticache'
@@ -0,0 +1,68 @@
1
+ require "version"
2
+ require 'dalli-elasticache'
3
+ require 'aws-sdk'
4
+
5
+ module AutoElasticache
6
+ class Elasticache
7
+ ENVIRONMENT_NAME_FILE = "/var/app/support/env_name"
8
+ SERVERS_FILE = "/var/app/support/elasticache_servers"
9
+ attr_accessor :config_endpoint
10
+
11
+ def initialize
12
+ @config_endpoint = config_endpoint
13
+ end
14
+
15
+ def servers
16
+ if File.exists?(SERVERS_FILE)
17
+ return File.read(SERVERS_FILE).split("\n")
18
+ else
19
+ elasticache = Dalli::ElastiCache.new(configuration_endpoint)
20
+ File.open(SERVERS_FILE, 'w') {|f| f.write(elasticache.servers.join("\n")) }
21
+ return elasticache.servers
22
+ end
23
+ end
24
+
25
+ def refresh_servers
26
+ elasticache = Dalli::ElastiCache.new(configuration_endpoint)
27
+ File.open(SERVERS_FILE, 'w') {|f| f.write(elasticache.servers.join("\n")) }
28
+ return elasticache.servers
29
+ end
30
+
31
+
32
+ private
33
+
34
+ def configuration_endpoint
35
+ aws_config
36
+
37
+ # Find the stack
38
+ cf = AWS::CloudFormation.new
39
+ env_name = environment_name
40
+ stack_name = cf.stacks.each {|s| break s.name if s.parameters["AWSEBEnvironmentName"] == env_name}
41
+
42
+ # Find the ElastiCache resource physical id
43
+ ec_id = cf.stacks[stack_name].resources.each {|r| break r.physical_resource_id if r.resource_type == "AWS::ElastiCache::CacheCluster"}
44
+
45
+ # Find the ElastiCache configuration endpoint
46
+ ec = AWS::ElastiCache.new
47
+ config_endpoint = ec.client.describe_cache_clusters(:cache_cluster_id => ec_id)[:cache_clusters].first[:configuration_endpoint]
48
+ "#{config_endpoint[:address]}:#{config_endpoint[:port]}"
49
+ end
50
+
51
+ def environment_name
52
+ if File.exists?(ENVIRONMENT_NAME_FILE)
53
+ return File.read(ENVIRONMENT_NAME_FILE)
54
+ else
55
+ instance_id = `/opt/aws/bin/ec2-metadata -i | awk '{print $2}'`.strip
56
+ aws_config
57
+ ec2 = AWS::EC2.new
58
+ env_name = ec2.instances[instance_id].tags["elasticbeanstalk:environment-name"]
59
+ File.open(ENVIRONMENT_NAME_FILE, 'w') {|f| f.write(env_name) }
60
+ env_name
61
+ end
62
+ end
63
+
64
+ def aws_config
65
+ @aws_config ||= AWS.config(YAML.load_file("config/auto_elasticache.yml")[Rails.env])
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ module AutoElasticache
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: auto_elasticache
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chad McGimpsey
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aws-sdk
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: dalli-elasticache
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Automatically start and configure an AWS ElastiCache cluster from an
47
+ Elastic Beanstalk environment
48
+ email:
49
+ - chad.mcgimpsey@gmail.com
50
+ executables:
51
+ - auto_elasticache
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - LICENSE.txt
58
+ - README.md
59
+ - Rakefile
60
+ - auto_elasticache.gemspec
61
+ - bin/auto_elasticache
62
+ - lib/auto_elasticache.rb
63
+ - lib/auto_elasticache/elasticache.rb
64
+ - lib/auto_elasticache/version.rb
65
+ homepage: https://github.com/dignoe/auto_elasticache
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.24
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: AutoElasticache automatically starts an AWS ElastiCache cluster and configures
89
+ Rails to use it. This gem requires that you are using AWS Elastic Beanstalk.
90
+ test_files: []