enscalator 0.4.0.pre.alpha.pre.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +9 -0
  4. data/.rubocop_todo.yml +59 -0
  5. data/.travis.yml +22 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +148 -0
  10. data/Rakefile +43 -0
  11. data/bin/console +11 -0
  12. data/bin/setup +7 -0
  13. data/enscalator.gemspec +57 -0
  14. data/exe/enscalator +13 -0
  15. data/lib/enscalator/core/cf_parameters.rb +146 -0
  16. data/lib/enscalator/core/cf_resources.rb +225 -0
  17. data/lib/enscalator/core/instance_type.rb +205 -0
  18. data/lib/enscalator/core/network_config.rb +21 -0
  19. data/lib/enscalator/core.rb +10 -0
  20. data/lib/enscalator/enapp.rb +248 -0
  21. data/lib/enscalator/helpers/dns.rb +62 -0
  22. data/lib/enscalator/helpers/stack.rb +107 -0
  23. data/lib/enscalator/helpers/sub_process.rb +72 -0
  24. data/lib/enscalator/helpers/wrappers.rb +55 -0
  25. data/lib/enscalator/helpers.rb +127 -0
  26. data/lib/enscalator/plugins/amazon_linux.rb +93 -0
  27. data/lib/enscalator/plugins/auto_scale.rb +80 -0
  28. data/lib/enscalator/plugins/core_os.rb +88 -0
  29. data/lib/enscalator/plugins/couchbase.rb +98 -0
  30. data/lib/enscalator/plugins/debian.rb +71 -0
  31. data/lib/enscalator/plugins/elastic_beanstalk.rb +74 -0
  32. data/lib/enscalator/plugins/elasticache.rb +168 -0
  33. data/lib/enscalator/plugins/elasticsearch_amazon.rb +75 -0
  34. data/lib/enscalator/plugins/elasticsearch_bitnami.rb +198 -0
  35. data/lib/enscalator/plugins/elasticsearch_opsworks.rb +225 -0
  36. data/lib/enscalator/plugins/elb.rb +139 -0
  37. data/lib/enscalator/plugins/nat_gateway.rb +71 -0
  38. data/lib/enscalator/plugins/rds.rb +141 -0
  39. data/lib/enscalator/plugins/redis.rb +38 -0
  40. data/lib/enscalator/plugins/rethink_db.rb +21 -0
  41. data/lib/enscalator/plugins/route53.rb +143 -0
  42. data/lib/enscalator/plugins/ubuntu.rb +85 -0
  43. data/lib/enscalator/plugins/user-data/elasticsearch +367 -0
  44. data/lib/enscalator/plugins/vpc_peering_connection.rb +48 -0
  45. data/lib/enscalator/plugins.rb +30 -0
  46. data/lib/enscalator/rich_template_dsl.rb +209 -0
  47. data/lib/enscalator/templates/vpc_peering.rb +112 -0
  48. data/lib/enscalator/templates.rb +20 -0
  49. data/lib/enscalator/version.rb +5 -0
  50. data/lib/enscalator/vpc.rb +11 -0
  51. data/lib/enscalator/vpc_with_nat_gateway.rb +311 -0
  52. data/lib/enscalator/vpc_with_nat_instance.rb +402 -0
  53. data/lib/enscalator.rb +103 -0
  54. metadata +427 -0
@@ -0,0 +1,225 @@
1
+ module Enscalator
2
+ module Core
3
+ # Resources for cloudformation template dsl
4
+ module CfResources
5
+ # VPC resource
6
+ #
7
+ # @param [String] name of the vpc name
8
+ # @param [String] cidr ip address block in CIDR notation (Classless Inter-Domain Routing)
9
+ # @param [String] enable_dns_support enable dns support
10
+ # @param [String] enable_dns_hostnames enable dns hostname
11
+ # @param [Array] depends_on list of resources this vpc needs
12
+ # @param [Hash] tags tags
13
+ def vpc(name, cidr, enable_dns_support: nil, enable_dns_hostnames: nil, depends_on: [], tags: {})
14
+ properties = {
15
+ CidrBlock: cidr
16
+ }
17
+ properties[:EnableDnsSupport] = enable_dns_support unless enable_dns_support.nil?
18
+ properties[:EnableDnsHostnames] = enable_dns_hostnames unless enable_dns_hostnames.nil?
19
+ unless tags.include?('Name')
20
+ tags['Name'] = join('-', aws_stack_name, name)
21
+ end
22
+ properties[:Tags] = tags_to_properties(tags)
23
+ options = {
24
+ Type: 'AWS::EC2::VPC',
25
+ Properties: properties
26
+ }
27
+ options[:DependsOn] = depends_on unless depends_on.empty?
28
+ resource name, options
29
+ name
30
+ end
31
+
32
+ # Subnet resource
33
+ #
34
+ # @param [String] name of the vpc name
35
+ # @param [String] cidr ip address block in CIDR notation (Classless Inter-Domain Routing)
36
+ # @param [String] availability_zone where subnet gets created
37
+ # @param [Array] depends_on list of resources this vpc needs
38
+ # @param [Hash] tags tags
39
+ def subnet(name, vpc, cidr, availability_zone: '', depends_on: [], tags: {})
40
+ properties = {
41
+ VpcId: vpc,
42
+ CidrBlock: cidr
43
+ }
44
+ properties[:AvailabilityZone] = availability_zone unless availability_zone.empty?
45
+ unless tags.include?('Name')
46
+ tags['Name'] = join('-', aws_stack_name, name)
47
+ end
48
+ properties[:Tags] = tags_to_properties(tags)
49
+
50
+ options = {
51
+ Type: 'AWS::EC2::Subnet',
52
+ Properties: properties
53
+ }
54
+ options[:DependsOn] = depends_on unless depends_on.empty?
55
+ resource name, options
56
+ name
57
+ end
58
+
59
+ # Security group
60
+ #
61
+ # @param [String] name of the security group
62
+ # @param [String] description of security group
63
+ # @param [Array] security_group_egress list of outbound rules
64
+ # @param [Array] security_group_ingress list of inbound rules
65
+ # @param [Array] depends_on list of resources this vpc needs
66
+ # @param [Hash] tags tags
67
+ def security_group(name,
68
+ description,
69
+ security_group_egress: [],
70
+ security_group_ingress: [],
71
+ depends_on: [],
72
+ tags: {})
73
+ properties = {
74
+ GroupDescription: description
75
+ }
76
+ properties[:SecurityGroupEgress] = security_group_egress unless security_group_egress.empty?
77
+ properties[:SecurityGroupIngress] = security_group_ingress unless security_group_ingress.empty?
78
+ unless tags.include?('Name')
79
+ tags['Name'] = join('-', aws_stack_name, name)
80
+ end
81
+ properties[:Tags] = tags_to_properties(tags)
82
+ options = {
83
+ Type: 'AWS::EC2::SecurityGroup',
84
+ Properties: properties
85
+ }
86
+ options[:DependsOn] = depends_on unless depends_on.empty?
87
+ resource name, options
88
+ name
89
+ end
90
+
91
+ # VPC Security group
92
+ #
93
+ # @param [String] name of the security group
94
+ # @param [String] description of security group
95
+ # @param [Array] security_group_egress list of outbound rules
96
+ # @param [Array] security_group_ingress list of inbound rules
97
+ # @param [Array] depends_on list of resources this vpc needs
98
+ # @param [Hash] tags tags
99
+ def security_group_vpc(name,
100
+ description,
101
+ vpc,
102
+ security_group_egress: [],
103
+ security_group_ingress: [],
104
+ depends_on: [],
105
+ tags: {})
106
+ properties = {
107
+ VpcId: vpc,
108
+ GroupDescription: description
109
+ }
110
+ properties[:SecurityGroupEgress] = security_group_egress unless security_group_egress.empty?
111
+ properties[:SecurityGroupIngress] = security_group_ingress unless security_group_ingress.empty?
112
+ unless tags.include?('Name')
113
+ tags['Name'] = join('-', aws_stack_name, name)
114
+ end
115
+ properties[:Tags] = tags_to_properties(tags)
116
+ options = {
117
+ Type: 'AWS::EC2::SecurityGroup',
118
+ Properties: properties
119
+ }
120
+ options[:DependsOn] = depends_on unless depends_on.empty?
121
+ resource name, options
122
+ name
123
+ end
124
+
125
+ # IAM instance profile with full access policies to passed services
126
+ #
127
+ # @param [String] role_name iam role name
128
+ # @param [Array<String>] services a list of aws service name
129
+ # @return [String] iam instance profile name
130
+ def iam_instance_profile_with_full_access(role_name, *services)
131
+ resource "#{role_name}Role",
132
+ Type: 'AWS::IAM::Role',
133
+ Properties: {
134
+ AssumeRolePolicyDocument: {
135
+ Statement: [
136
+ {
137
+ Effect: 'Allow',
138
+ Principal: {
139
+ Service: ['ec2.amazonaws.com']
140
+ },
141
+ Action: ['sts:AssumeRole']
142
+ }
143
+ ]
144
+ },
145
+ Path: '/',
146
+ Policies: [
147
+ {
148
+ PolicyName: "#{role_name}Policy",
149
+ PolicyDocument: {
150
+ Statement: services.map do |s|
151
+ {
152
+ Effect: 'Allow',
153
+ Action: "#{s}:*",
154
+ Resource: '*'
155
+ }
156
+ end
157
+ }
158
+ }
159
+ ]
160
+ }
161
+
162
+ resource "#{role_name}InstanceProfile",
163
+ Type: 'AWS::IAM::InstanceProfile',
164
+ Properties: {
165
+ Path: '/',
166
+ Roles: [ref("#{role_name}Role")]
167
+ }
168
+
169
+ ref("#{role_name}InstanceProfile")
170
+ end
171
+
172
+ # Create ec2 instance in given vpc
173
+ #
174
+ # @param [String] name instance name
175
+ # @param [String] image_id instance ami_id
176
+ # @param [String] subnet instance subnet id
177
+ # @param [String] security_groups instance security_groups (string of Security Groups IDs)
178
+ # @param [Array] depends_on resources necessary to be create prior to this instance
179
+ # @param [Hash] properties other properties
180
+ def instance_vpc(name, image_id, subnet, security_groups, depends_on: [], properties: {})
181
+ fail "VPC instance #{name} can not contain non VPC SecurityGroups" if properties.include?(:SecurityGroups)
182
+ if properties.include?(:NetworkInterfaces)
183
+ fail "VPC instance #{name} can not contain NetworkInterfaces and subnet or security_groups"
184
+ end
185
+ properties[:ImageId] = image_id
186
+ properties[:SubnetId] = subnet
187
+ properties[:SecurityGroupIds] = security_groups
188
+ if properties[:Tags] && !properties[:Tags].any? { |x| x[:Key] == 'Name' }
189
+ properties[:Tags] << { Key: 'Name', Value: join('-', aws_stack_name, name) }
190
+ end
191
+ options = {
192
+ Type: 'AWS::EC2::Instance',
193
+ Properties: properties
194
+ }
195
+
196
+ options[:DependsOn] = depends_on unless depends_on.empty?
197
+ resource name, options
198
+ name
199
+ end
200
+
201
+ # Create ec2 instance with attached to it network interface
202
+ #
203
+ # @param [String] name instance name
204
+ # @param [String] image_id instance ami_id
205
+ # @param [String] network_interfaces network interfaces
206
+ # @param [Hash] properties other properties
207
+ def instance_with_network(name, image_id, network_interfaces, properties: {})
208
+ if ([:SubnetId, :SecurityGroups, :SecurityGroupIds] & properties).any?
209
+ fail "Instance with NetworkInterfaces #{name} can not contain instance subnet or security_groups"
210
+ end
211
+ properties[:ImageId] = image_id
212
+ properties[:NetworkInterfaces] = network_interfaces
213
+ if properties[:Tags] && !properties[:Tags].any? { |x| x[:Key] == 'Name' }
214
+ properties[:Tags] << { Key: 'Name', Value: join('-', aws_stack_name, name) }
215
+ end
216
+ options = {
217
+ Type: 'AWS::EC2::Instance',
218
+ Properties: properties
219
+ }
220
+ resource name, options
221
+ name
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,205 @@
1
+ module Enscalator
2
+ module Core
3
+ # Instance type
4
+ module InstanceType
5
+ # Generic Aws instance
6
+ class AwsInstance
7
+ attr_reader :current_generation, :previous_generation
8
+
9
+ # Create new AwsInstance
10
+ #
11
+ # @param [Hash] current generation instances
12
+ # @param [Hash] previous generation instances
13
+ def initialize(current = {}, previous = {})
14
+ fail('Unable to instantiate if its not Hash') unless current.is_a?(Hash) && previous.is_a?(Hash)
15
+ @current_generation ||= current
16
+ @previous_generation ||= previous
17
+ end
18
+
19
+ # Check if given instance type is either current or previous generation
20
+ #
21
+ # @param [String] type instance type
22
+ # @return [Boolean]
23
+ def supported?(type)
24
+ (@current_generation.values + @previous_generation.values).flatten.include? type
25
+ end
26
+
27
+ # Checks if given instance type is in previous generation
28
+ #
29
+ # @param [String] type instance type
30
+ # @return [Boolean]
31
+ def obsolete?(type)
32
+ @previous_generation.values.flatten.include? type
33
+ end
34
+
35
+ # List of all allowed values
36
+ #
37
+ # @param [String] type instance type
38
+ # @return [Array]
39
+ def allowed_values(type)
40
+ return [] unless self.supported?(type)
41
+ self.obsolete?(type) ? @previous_generation.values.flatten : @current_generation.values.flatten
42
+ end
43
+ end
44
+
45
+ # EC2 instance
46
+ class EC2 < AwsInstance
47
+ def initialize
48
+ super(current_generation, previous_generation)
49
+ end
50
+
51
+ # Current generation instance types
52
+ #
53
+ # @return [Hash] instance family and type
54
+ def current_generation
55
+ {
56
+ general_purpose: %w(
57
+ t2.micro t2.small t2.medium t2.large
58
+ m4.large m4.xlarge m4.2xlarge m4.4xlarge m4.10xlarge
59
+ m3.medium m3.large m3.xlarge m3.2xlarge
60
+ ),
61
+ compute_optimized: %w(
62
+ c4.large c4.xlarge c4.2xlarge c4.4xlarge c4.8xlarge
63
+ c3.large c3.xlarge c3.2xlarge c3.4xlarge c3.8xlarge
64
+ ),
65
+ memory_optimized: %w( r3.large r3.xlarge r3.2xlarge r3.4xlarge r3.8xlarge ),
66
+ gpu: %w( g2.2xlarge g2.8xlarge ),
67
+ high_io_optimized: %w( i2.xlarge i2.xlarge i2.4xlarge i2.8xlarge ),
68
+ dense_storage_optimized: %w( d2.xlarge d2.2xlarge d2.4xlarge d2.8xlarge )
69
+ }
70
+ end
71
+
72
+ # @deprecated Will be removed once Amazon fully stops supporting these instances
73
+ # Previous generation instance types
74
+ #
75
+ # @return [Hash] instance family and type
76
+ def previous_generation
77
+ {
78
+ general_purpose: %w( m1.small m1.medium m1.large m1.xlarge ),
79
+ compute_optimized: %w( c1.medium c1.xlarge cc2.8xlarge ),
80
+ gpu: %w( cg1.4xlarge ),
81
+ memory_optimized: %w( m2.xlarge m2.2xlarge m2.4xlarge cr1.8xlarge ),
82
+ storage_optimized: %w( hi1.4xlarge hs1.8xlarge ),
83
+ micro: %w( t1.micro )
84
+ }
85
+ end
86
+ end # class EC2
87
+
88
+ # ElastiCache instance
89
+ class ElastiCache < AwsInstance
90
+ def initialize
91
+ super(current_generation, previous_generation)
92
+ end
93
+
94
+ # Determine maximum available memory for given instance type
95
+ #
96
+ # @return [Hash] instance max memory
97
+ def max_memory(type)
98
+ {
99
+ 'cache.t1.micro': 142_606_336,
100
+ 'cache.t2.micro': 581_959_680,
101
+ 'cache.t2.small': 1_665_138_688,
102
+ 'cache.t2.medium': 3_461_349_376,
103
+ 'cache.m1.small': 943_718_400,
104
+ 'cache.m1.medium': 3_093_299_200,
105
+ 'cache.m1.large': 7_025_459_200,
106
+ 'cache.m1.xlarge': 14_889_779_200,
107
+ 'cache.m2.xlarge': 17_091_788_800,
108
+ 'cache.m2.2xlarge': 35_022_438_400,
109
+ 'cache.m2.4xlarge': 70_883_737_600,
110
+ 'cache.m3.medium': 2_988_441_600,
111
+ 'cache.m3.large': 6_501_171_200,
112
+ 'cache.m3.xlarge': 14_260_633_600,
113
+ 'cache.m3.2xlarge': 29_989_273_600,
114
+ 'cache.c1.xlarge': 6_501_171_200,
115
+ 'cache.r3.large': 14_470_348_800,
116
+ 'cache.r3.xlarge': 30_513_561_600,
117
+ 'cache.r3.2xlarge': 62_495_129_600,
118
+ 'cache.r3.4xlarge': 126_458_265_600,
119
+ 'cache.r3.8xlarge': 254_384_537_600
120
+ }.with_indifferent_access.fetch(type)
121
+ end
122
+
123
+ # Current generation instance types
124
+ #
125
+ # @return [Hash] instance family and type
126
+ def current_generation
127
+ {
128
+ standard: %w(
129
+ cache.t2.micro cache.t2.small cache.t2.medium
130
+ cache.m3.medium cache.m3.large cache.m3.xlarge cache.m3.2xlarge),
131
+ memory_optimized: %w(cache.r3.large cache.r3.xlarge cache.r3.2xlarge cache.r3.4xlarge cache.r3.8xlarge)
132
+ }
133
+ end
134
+
135
+ # @deprecated Will be removed once Amazon fully stops supporting these instances
136
+ # Previous generation instance types
137
+ #
138
+ # @return [Hash] instance family and type
139
+ def previous_generation
140
+ {
141
+ standard: %w(cache.m1.small cache.m1.medium cache.m1.large cache.m1.xlarge),
142
+ memory_optimized: %w(cache.m2.xlarge cache.m2.2xlarge cache.m2.4xlarge),
143
+ compute_optimized: %w(cache.c1.xlarge),
144
+ micro: %w(cache.t1.micro)
145
+ }
146
+ end
147
+ end
148
+
149
+ # RDS instance
150
+ class RDS < AwsInstance
151
+ def initialize
152
+ super(current_generation, previous_generation)
153
+ end
154
+
155
+ # Current generation instance types
156
+ #
157
+ # @return [Hash] instance family and type
158
+ def current_generation
159
+ {
160
+ standard: %w( db.m4.large db.m4.xlarge db.m4.2xlarge db.m4.4xlarge db.m4.10xlarge ),
161
+ memory_optimized: %w( db.r3.large db.r3.xlarge db.r3.2xlarge db.r3.4xlarge db.r3.8xlarge ),
162
+ burstable_performance: %w( db.t2.micro db.t2.small db.t2.medium )
163
+ }
164
+ end
165
+
166
+ # @deprecated Will be removed once Amazon fully stops supporting these instances
167
+ # Previous generation instance types
168
+ #
169
+ # @return [Hash] instance family and type
170
+ def previous_generation
171
+ {
172
+ standard: %w( db.m1.small db.m1.medium db.m1.large db.m1.xlarge
173
+ db.m3.medium db.m3.large db.m3.xlarge db.m3.2xlarge ),
174
+ memory_optimized: %w( db.m2.xlarge db.m2.2xlarge db.m2.4xlarge db.cr1.8xlarge ),
175
+ micro: %w( db.t1.micro )
176
+ }
177
+ end
178
+ end # class RDS
179
+
180
+ # Simple interface to directly access classes above using module methods
181
+ class << self
182
+ # Creates EC2 instance type with corresponding values set
183
+ #
184
+ # @return [Enscalator::InstanceType::EC2]
185
+ def ec2_instance_type
186
+ EC2.new
187
+ end
188
+
189
+ # Creates RDS instance type with corresponding values set
190
+ #
191
+ # @return [Enscalator::InstanceType::RDS]
192
+ def rds_instance_type
193
+ RDS.new
194
+ end
195
+
196
+ # Creates ElasticCache instance type with corresponding values set
197
+ #
198
+ # @return [Enscalator::InstanceType::ElastiCache]
199
+ def elasticache_instance_type
200
+ ElastiCache.new
201
+ end
202
+ end # class << self
203
+ end # module InstanceType
204
+ end # module Core
205
+ end # module Enscalator
@@ -0,0 +1,21 @@
1
+ module Enscalator
2
+ module Core
3
+ # Configuration specific for VPC setup
4
+ class NetworkConfig
5
+ # VPC network mapping
6
+ def self.mapping_vpc_net
7
+ {
8
+ 'us-east-1': { VPC: '10.0.0.0/16' },
9
+ 'us-west-1': { VPC: '10.16.0.0/16' },
10
+ 'us-west-2': { VPC: '10.8.0.0/16' },
11
+ 'eu-west-1': { VPC: '10.24.0.0/16' },
12
+ 'eu-central-1': { VPC: '10.32.0.0/16' },
13
+ 'ap-southeast-1': { VPC: '10.40.0.0/16' },
14
+ 'ap-northeast-1': { VPC: '10.48.0.0/16' },
15
+ 'ap-southeast-2': { VPC: '10.56.0.0/16' },
16
+ 'sa-east-1': { VPC: '10.64.0.0/16' }
17
+ }.with_indifferent_access
18
+ end # mapping_vpc_net
19
+ end # class NetworkConfig
20
+ end # module Core
21
+ end # module Enscalator
@@ -0,0 +1,10 @@
1
+ require_relative 'core/network_config'
2
+ require_relative 'core/instance_type'
3
+ require_relative 'core/cf_parameters'
4
+ require_relative 'core/cf_resources'
5
+
6
+ module Enscalator
7
+ # Namespace for enscalator core modules/classes
8
+ module Core
9
+ end
10
+ end