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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +59 -0
- data/.travis.yml +22 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +148 -0
- data/Rakefile +43 -0
- data/bin/console +11 -0
- data/bin/setup +7 -0
- data/enscalator.gemspec +57 -0
- data/exe/enscalator +13 -0
- data/lib/enscalator/core/cf_parameters.rb +146 -0
- data/lib/enscalator/core/cf_resources.rb +225 -0
- data/lib/enscalator/core/instance_type.rb +205 -0
- data/lib/enscalator/core/network_config.rb +21 -0
- data/lib/enscalator/core.rb +10 -0
- data/lib/enscalator/enapp.rb +248 -0
- data/lib/enscalator/helpers/dns.rb +62 -0
- data/lib/enscalator/helpers/stack.rb +107 -0
- data/lib/enscalator/helpers/sub_process.rb +72 -0
- data/lib/enscalator/helpers/wrappers.rb +55 -0
- data/lib/enscalator/helpers.rb +127 -0
- data/lib/enscalator/plugins/amazon_linux.rb +93 -0
- data/lib/enscalator/plugins/auto_scale.rb +80 -0
- data/lib/enscalator/plugins/core_os.rb +88 -0
- data/lib/enscalator/plugins/couchbase.rb +98 -0
- data/lib/enscalator/plugins/debian.rb +71 -0
- data/lib/enscalator/plugins/elastic_beanstalk.rb +74 -0
- data/lib/enscalator/plugins/elasticache.rb +168 -0
- data/lib/enscalator/plugins/elasticsearch_amazon.rb +75 -0
- data/lib/enscalator/plugins/elasticsearch_bitnami.rb +198 -0
- data/lib/enscalator/plugins/elasticsearch_opsworks.rb +225 -0
- data/lib/enscalator/plugins/elb.rb +139 -0
- data/lib/enscalator/plugins/nat_gateway.rb +71 -0
- data/lib/enscalator/plugins/rds.rb +141 -0
- data/lib/enscalator/plugins/redis.rb +38 -0
- data/lib/enscalator/plugins/rethink_db.rb +21 -0
- data/lib/enscalator/plugins/route53.rb +143 -0
- data/lib/enscalator/plugins/ubuntu.rb +85 -0
- data/lib/enscalator/plugins/user-data/elasticsearch +367 -0
- data/lib/enscalator/plugins/vpc_peering_connection.rb +48 -0
- data/lib/enscalator/plugins.rb +30 -0
- data/lib/enscalator/rich_template_dsl.rb +209 -0
- data/lib/enscalator/templates/vpc_peering.rb +112 -0
- data/lib/enscalator/templates.rb +20 -0
- data/lib/enscalator/version.rb +5 -0
- data/lib/enscalator/vpc.rb +11 -0
- data/lib/enscalator/vpc_with_nat_gateway.rb +311 -0
- data/lib/enscalator/vpc_with_nat_instance.rb +402 -0
- data/lib/enscalator.rb +103 -0
- metadata +427 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
module Enscalator
|
2
|
+
module Templates
|
3
|
+
# VPC Peering connection between two VPCs
|
4
|
+
class VPCPeering < Enscalator::RichTemplateDSL
|
5
|
+
include Enscalator::Plugins::VPCPeeringConnection
|
6
|
+
|
7
|
+
# Retrieve local VPC configuration from provisioned stack
|
8
|
+
# @return [Aws::CloudFormation::Stack]
|
9
|
+
def local_vpc_stack
|
10
|
+
@local_vpc_stack ||= cfn_resource(cfn_client(region)).stack(vpc_stack_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Interface for VPC
|
14
|
+
# @param [String] id logical id of VPC
|
15
|
+
# @return [Aws::EC2::Vpc]
|
16
|
+
def vpc(id: get_resource(local_vpc_stack, 'VPC'))
|
17
|
+
Aws::EC2::Vpc.new(id: id, region: region)
|
18
|
+
end
|
19
|
+
|
20
|
+
# VPC Peering connection can be created only when
|
21
|
+
#
|
22
|
+
# - both VPCs are in the same region
|
23
|
+
# - connected VPCs has distinct CIDR blocks
|
24
|
+
#
|
25
|
+
# Route tables should be created in the following way:
|
26
|
+
#
|
27
|
+
# VPC Local's route table
|
28
|
+
# 172.16.0.0/16 -> Local
|
29
|
+
# 10.0.0.0/16 -> pcx-11112222
|
30
|
+
#
|
31
|
+
# VPC Remote's route table
|
32
|
+
# 10.0.0.0/16 Local
|
33
|
+
# 172.16.0.0/16 pcx-11112222
|
34
|
+
def tpl
|
35
|
+
connection_name = 'PrivateConnection'
|
36
|
+
local_vpc_id_ref, remote_vpc_id_ref = %W(#{connection_name}VpcId #{connection_name}PeerVpcId)
|
37
|
+
|
38
|
+
def validate_params(*params)
|
39
|
+
params.each do |param|
|
40
|
+
fail "Unable to find required parameter #{param}" unless @parameters.key?(param)
|
41
|
+
end
|
42
|
+
rescue RuntimeError => e
|
43
|
+
puts e
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
|
47
|
+
validate_params(*[remote_vpc_id_ref])
|
48
|
+
|
49
|
+
local_vpc, remote_vpc = [vpc, vpc(id: @parameters[remote_vpc_id_ref])]
|
50
|
+
|
51
|
+
description 'Stack to create peering connection between two VPCs'
|
52
|
+
|
53
|
+
parameter_vpc_id(local_vpc_id_ref,
|
54
|
+
'VpcId from where connection gets created',
|
55
|
+
local_vpc.id)
|
56
|
+
|
57
|
+
parameter_vpc_id(remote_vpc_id_ref,
|
58
|
+
'VpcId where peering connection should go',
|
59
|
+
remote_vpc.id)
|
60
|
+
|
61
|
+
# Initialize Peering connection
|
62
|
+
vpc_peering_init(connection_name,
|
63
|
+
tags: [
|
64
|
+
{
|
65
|
+
Key: 'Name',
|
66
|
+
Value: connection_name
|
67
|
+
}
|
68
|
+
])
|
69
|
+
|
70
|
+
def read_vpc_route_tables(vpc)
|
71
|
+
routes = []
|
72
|
+
vpc.route_tables.each do |rt|
|
73
|
+
routes << rt
|
74
|
+
end
|
75
|
+
routes
|
76
|
+
end
|
77
|
+
|
78
|
+
# Add rules to local VPC routing table
|
79
|
+
read_vpc_route_tables(local_vpc).map(&:id).each_with_index do |rt_id, i|
|
80
|
+
local_vpc_route_rule = "LocalVPCPeeringRoute#{i + 1}"
|
81
|
+
resource local_vpc_route_rule,
|
82
|
+
Type: 'AWS::EC2::Route',
|
83
|
+
Properties: {
|
84
|
+
RouteTableId: rt_id,
|
85
|
+
DestinationCidrBlock: remote_vpc.cidr_block,
|
86
|
+
VpcPeeringConnectionId: ref(connection_name)
|
87
|
+
}
|
88
|
+
|
89
|
+
output local_vpc_route_rule,
|
90
|
+
Description: "Local VPC Peering connection for #{rt_id}",
|
91
|
+
Value: ref(local_vpc_route_rule)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add rules to remote VPC routing table
|
95
|
+
read_vpc_route_tables(remote_vpc).map(&:id).each_with_index do |rt_id, i|
|
96
|
+
remote_vpc_route_rule = "RemoteVPCPeeringRoute#{i + 1}"
|
97
|
+
resource remote_vpc_route_rule,
|
98
|
+
Type: 'AWS::EC2::Route',
|
99
|
+
Properties: {
|
100
|
+
RouteTableId: rt_id,
|
101
|
+
DestinationCidrBlock: local_vpc.cidr_block,
|
102
|
+
VpcPeeringConnectionId: ref(connection_name)
|
103
|
+
}
|
104
|
+
|
105
|
+
output remote_vpc_route_rule,
|
106
|
+
Description: "Remote VPC Peering connection for #{rt_id}",
|
107
|
+
Value: ref(remote_vpc_route_rule)
|
108
|
+
end
|
109
|
+
end # tpl
|
110
|
+
end # class VPCPeering
|
111
|
+
end # module Plugins
|
112
|
+
end # module Enscalator
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'templates/vpc_peering'
|
2
|
+
|
3
|
+
module Enscalator
|
4
|
+
# Namespace for template collection
|
5
|
+
module Templates
|
6
|
+
# Get all loaded template classes
|
7
|
+
# @return [Array]
|
8
|
+
def self.all
|
9
|
+
namespace = Enscalator::Templates
|
10
|
+
templates = namespace.constants
|
11
|
+
templates.map { |t| (namespace.to_s.split('::') << t.to_s).join('::').constantize }
|
12
|
+
end
|
13
|
+
|
14
|
+
# Verify if all loaded templates have required tpl method
|
15
|
+
# @return [Boolean]
|
16
|
+
def self.all_valid?
|
17
|
+
all.map { |t| t.instance_methods.include?(:tpl) }.all?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Enscalator
|
2
|
+
module Templates
|
3
|
+
# Amazon AWS Virtual Private Cloud template (defaults to template with NAT gateway)
|
4
|
+
class VPC < Enscalator::Templates::VPCWithNATGateway
|
5
|
+
# Call method with same name from superclass
|
6
|
+
def tpl
|
7
|
+
super
|
8
|
+
end
|
9
|
+
end # class VPC
|
10
|
+
end # module Templates
|
11
|
+
end # module Enscalator
|
@@ -0,0 +1,311 @@
|
|
1
|
+
module Enscalator
|
2
|
+
module Templates
|
3
|
+
# Amazon AWS Virtual Private Cloud template with NAT gateway
|
4
|
+
class VPCWithNATGateway < Enscalator::RichTemplateDSL
|
5
|
+
include Enscalator::Plugins::NATGateway
|
6
|
+
|
7
|
+
# Subnet size (256 addresses)
|
8
|
+
SUBNET_CIDR_BLOCK_SIZE = 24
|
9
|
+
|
10
|
+
# Template method
|
11
|
+
def tpl
|
12
|
+
description = <<-EOS.gsub(/^\s+\|/, '')
|
13
|
+
|AWS CloudFormation template for the VPC environment.
|
14
|
+
|For each availability zone stack creates: the public subnet, internet and NAT gateways,
|
15
|
+
|internet access from private subnets, routing configuration for corresponding subnets
|
16
|
+
|and security groups.
|
17
|
+
EOS
|
18
|
+
|
19
|
+
value Description: description
|
20
|
+
|
21
|
+
mapping 'AWSRegionNetConfig', Core::NetworkConfig.mapping_vpc_net
|
22
|
+
|
23
|
+
resource 'VPC',
|
24
|
+
Type: 'AWS::EC2::VPC',
|
25
|
+
Properties: {
|
26
|
+
CidrBlock: find_in_map('AWSRegionNetConfig', ref('AWS::Region'), 'VPC'),
|
27
|
+
EnableDnsSupport: 'true',
|
28
|
+
EnableDnsHostnames: 'true',
|
29
|
+
Tags: [
|
30
|
+
{
|
31
|
+
Key: 'Name',
|
32
|
+
Value: aws_stack_name
|
33
|
+
},
|
34
|
+
{
|
35
|
+
Key: 'Application',
|
36
|
+
Value: aws_stack_name
|
37
|
+
},
|
38
|
+
{
|
39
|
+
Key: 'Network',
|
40
|
+
Value: 'Public'
|
41
|
+
}
|
42
|
+
]
|
43
|
+
}
|
44
|
+
|
45
|
+
resource 'InternetGateway',
|
46
|
+
Type: 'AWS::EC2::InternetGateway',
|
47
|
+
Properties: {
|
48
|
+
Tags: [
|
49
|
+
{
|
50
|
+
Key: 'Name',
|
51
|
+
Value: 'Public Gateway'
|
52
|
+
},
|
53
|
+
{
|
54
|
+
Key: 'Application',
|
55
|
+
Value: aws_stack_name
|
56
|
+
},
|
57
|
+
{
|
58
|
+
Key: 'Network',
|
59
|
+
Value: 'Public'
|
60
|
+
}
|
61
|
+
]
|
62
|
+
}
|
63
|
+
|
64
|
+
resource 'GatewayToInternet',
|
65
|
+
DependsOn: %w( VPC InternetGateway ),
|
66
|
+
Type: 'AWS::EC2::VPCGatewayAttachment',
|
67
|
+
Properties: {
|
68
|
+
VpcId: ref('VPC'),
|
69
|
+
InternetGatewayId: ref('InternetGateway')
|
70
|
+
}
|
71
|
+
|
72
|
+
resource 'PublicRouteTable',
|
73
|
+
DependsOn: ['VPC'],
|
74
|
+
Type: 'AWS::EC2::RouteTable',
|
75
|
+
Properties: {
|
76
|
+
VpcId: ref('VPC'),
|
77
|
+
Tags: [
|
78
|
+
{
|
79
|
+
Key: 'Name',
|
80
|
+
Value: 'Public'
|
81
|
+
},
|
82
|
+
{
|
83
|
+
Key: 'Application',
|
84
|
+
Value: aws_stack_name
|
85
|
+
},
|
86
|
+
{
|
87
|
+
Key: 'Network',
|
88
|
+
Value: 'Public'
|
89
|
+
}
|
90
|
+
]
|
91
|
+
}
|
92
|
+
|
93
|
+
resource 'PublicRoute',
|
94
|
+
DependsOn: %w( PublicRouteTable InternetGateway ),
|
95
|
+
Type: 'AWS::EC2::Route',
|
96
|
+
Properties: {
|
97
|
+
RouteTableId: ref('PublicRouteTable'),
|
98
|
+
DestinationCidrBlock: '0.0.0.0/0',
|
99
|
+
GatewayId: ref('InternetGateway')
|
100
|
+
}
|
101
|
+
|
102
|
+
resource 'PublicNetworkAcl',
|
103
|
+
DependsOn: ['VPC'],
|
104
|
+
Type: 'AWS::EC2::NetworkAcl',
|
105
|
+
Properties: {
|
106
|
+
VpcId: ref('VPC'),
|
107
|
+
Tags: [
|
108
|
+
{
|
109
|
+
Key: 'Name',
|
110
|
+
Value: 'Public'
|
111
|
+
},
|
112
|
+
{
|
113
|
+
Key: 'Application',
|
114
|
+
Value: aws_stack_name
|
115
|
+
},
|
116
|
+
{
|
117
|
+
Key: 'Network',
|
118
|
+
Value: 'Public'
|
119
|
+
}
|
120
|
+
]
|
121
|
+
}
|
122
|
+
|
123
|
+
resource 'InboundHTTPPublicNetworkAclEntry',
|
124
|
+
DependsOn: ['PublicNetworkAcl'],
|
125
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
126
|
+
Properties: {
|
127
|
+
NetworkAclId: ref('PublicNetworkAcl'),
|
128
|
+
RuleNumber: '100',
|
129
|
+
Protocol: '-1',
|
130
|
+
RuleAction: 'allow',
|
131
|
+
Egress: 'false',
|
132
|
+
CidrBlock: '0.0.0.0/0',
|
133
|
+
PortRange: { From: '0', To: '65535' }
|
134
|
+
}
|
135
|
+
|
136
|
+
resource 'OutboundHTTPPublicNetworkAclEntry',
|
137
|
+
DependsOn: ['PublicNetworkAcl'],
|
138
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
139
|
+
Properties: {
|
140
|
+
NetworkAclId: ref('PublicNetworkAcl'),
|
141
|
+
RuleNumber: '100',
|
142
|
+
Protocol: '-1',
|
143
|
+
RuleAction: 'allow',
|
144
|
+
Egress: 'true',
|
145
|
+
CidrBlock: '0.0.0.0/0',
|
146
|
+
PortRange: { From: '0', To: '65535' }
|
147
|
+
}
|
148
|
+
|
149
|
+
resource 'PrivateNetworkAcl',
|
150
|
+
DependsOn: ['VPC'],
|
151
|
+
Type: 'AWS::EC2::NetworkAcl',
|
152
|
+
Properties: {
|
153
|
+
VpcId: ref('VPC'),
|
154
|
+
Tags: [
|
155
|
+
{
|
156
|
+
Key: 'Name',
|
157
|
+
Value: 'Private'
|
158
|
+
},
|
159
|
+
{
|
160
|
+
Key: 'Application',
|
161
|
+
Value: aws_stack_name
|
162
|
+
},
|
163
|
+
{
|
164
|
+
Key: 'Network',
|
165
|
+
Value: 'Private'
|
166
|
+
}
|
167
|
+
]
|
168
|
+
}
|
169
|
+
|
170
|
+
resource 'InboundPrivateNetworkAclEntry',
|
171
|
+
DependsOn: ['PrivateNetworkAcl'],
|
172
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
173
|
+
Properties: {
|
174
|
+
NetworkAclId: ref('PrivateNetworkAcl'),
|
175
|
+
RuleNumber: '100',
|
176
|
+
Protocol: '6',
|
177
|
+
RuleAction: 'allow',
|
178
|
+
Egress: 'false',
|
179
|
+
CidrBlock: '0.0.0.0/0',
|
180
|
+
PortRange: { From: '0', To: '65535' }
|
181
|
+
}
|
182
|
+
|
183
|
+
resource 'OutBoundPrivateNetworkAclEntry',
|
184
|
+
DependsOn: ['PrivateNetworkAcl'],
|
185
|
+
Type: 'AWS::EC2::NetworkAclEntry',
|
186
|
+
Properties: {
|
187
|
+
NetworkAclId: ref('PrivateNetworkAcl'),
|
188
|
+
RuleNumber: '100',
|
189
|
+
Protocol: '6',
|
190
|
+
RuleAction: 'allow',
|
191
|
+
Egress: 'true',
|
192
|
+
CidrBlock: '0.0.0.0/0',
|
193
|
+
PortRange: { From: '0', To: '65535' }
|
194
|
+
}
|
195
|
+
|
196
|
+
resource 'PrivateSecurityGroup',
|
197
|
+
DependsOn: ['VPC'],
|
198
|
+
Type: 'AWS::EC2::SecurityGroup',
|
199
|
+
Properties: {
|
200
|
+
GroupDescription: 'Allow the Application instances to access the NAT device',
|
201
|
+
VpcId: ref('VPC'),
|
202
|
+
SecurityGroupEgress: [
|
203
|
+
{
|
204
|
+
IpProtocol: 'tcp',
|
205
|
+
FromPort: '0',
|
206
|
+
ToPort: '65535',
|
207
|
+
CidrIp: '10.0.0.0/8'
|
208
|
+
}
|
209
|
+
],
|
210
|
+
SecurityGroupIngress: [
|
211
|
+
{
|
212
|
+
IpProtocol: 'tcp',
|
213
|
+
FromPort: '0',
|
214
|
+
ToPort: '65535',
|
215
|
+
CidrIp: '10.0.0.0/8'
|
216
|
+
}
|
217
|
+
],
|
218
|
+
Tags: [
|
219
|
+
{
|
220
|
+
Key: 'Name',
|
221
|
+
Value: 'Private'
|
222
|
+
}
|
223
|
+
]
|
224
|
+
}
|
225
|
+
|
226
|
+
current_cidr_block = Core::NetworkConfig.mapping_vpc_net[region.to_sym][:VPC]
|
227
|
+
public_cidr_blocks =
|
228
|
+
IPAddress(current_cidr_block).subnet(SUBNET_CIDR_BLOCK_SIZE).map(&:to_string).first(availability_zones.size)
|
229
|
+
|
230
|
+
availability_zones.zip(public_cidr_blocks).each do |pair, cidr_block|
|
231
|
+
suffix = pair.first
|
232
|
+
public_subnet_name = "PublicSubnet#{suffix.upcase}"
|
233
|
+
resource public_subnet_name,
|
234
|
+
DependsOn: ['VPC'],
|
235
|
+
Type: 'AWS::EC2::Subnet',
|
236
|
+
Properties: {
|
237
|
+
VpcId: ref('VPC'),
|
238
|
+
AvailabilityZone: join('', ref('AWS::Region'), suffix.to_s),
|
239
|
+
CidrBlock: cidr_block,
|
240
|
+
Tags: [
|
241
|
+
{
|
242
|
+
Key: 'Name',
|
243
|
+
Value: "Public #{suffix.upcase}"
|
244
|
+
},
|
245
|
+
{
|
246
|
+
Key: 'Application',
|
247
|
+
Value: aws_stack_name
|
248
|
+
},
|
249
|
+
{
|
250
|
+
Key: 'Network',
|
251
|
+
Value: 'Public'
|
252
|
+
}
|
253
|
+
]
|
254
|
+
}
|
255
|
+
|
256
|
+
resource "PublicSubnetRouteTableAssociation#{suffix.upcase}",
|
257
|
+
DependsOn: [public_subnet_name, 'PublicRouteTable'],
|
258
|
+
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
259
|
+
Properties: {
|
260
|
+
SubnetId: ref(public_subnet_name),
|
261
|
+
RouteTableId: ref('PublicRouteTable')
|
262
|
+
}
|
263
|
+
|
264
|
+
private_route_table_name = "PrivateRouteTable#{suffix.upcase}"
|
265
|
+
resource private_route_table_name,
|
266
|
+
DependsOn: ['VPC'],
|
267
|
+
Type: 'AWS::EC2::RouteTable',
|
268
|
+
Properties: {
|
269
|
+
VpcId: ref('VPC'),
|
270
|
+
Tags: [
|
271
|
+
{
|
272
|
+
Key: 'Name',
|
273
|
+
Value: "Private #{suffix.upcase}"
|
274
|
+
},
|
275
|
+
{
|
276
|
+
Key: 'Application',
|
277
|
+
Value: aws_stack_name
|
278
|
+
},
|
279
|
+
{
|
280
|
+
Key: 'Network',
|
281
|
+
Value: 'Private'
|
282
|
+
}
|
283
|
+
]
|
284
|
+
}
|
285
|
+
|
286
|
+
# Important!
|
287
|
+
# When updating stack that was previously deployed using VPC template with NAT EC2 instance:
|
288
|
+
# 1. Comment out lines related to NAT device below
|
289
|
+
# 2. Update stack using this template (it will remove NAT instances and related security and routing rules)
|
290
|
+
# 3. Revert changes from 1. (i.e. uncomment lines below)
|
291
|
+
# 4. Update stack again (this time it will create new NAT Gateway, EIP and routing rule resources)
|
292
|
+
nat_device_name = "NATDevice#{suffix.upcase}"
|
293
|
+
nat_gateway_init(nat_device_name, public_subnet_name, private_route_table_name,
|
294
|
+
depends_on: [public_subnet_name, 'PublicRouteTable', 'GatewayToInternet'])
|
295
|
+
|
296
|
+
output public_subnet_name,
|
297
|
+
Description: "Created Subnet #{suffix.upcase}",
|
298
|
+
Value: ref(public_subnet_name)
|
299
|
+
end # each availability zone
|
300
|
+
|
301
|
+
output 'VpcId',
|
302
|
+
Description: 'Created VPC',
|
303
|
+
Value: ref('VPC')
|
304
|
+
|
305
|
+
output 'PrivateSecurityGroup',
|
306
|
+
Description: 'SecurityGroup to add private resources',
|
307
|
+
Value: ref('PrivateSecurityGroup')
|
308
|
+
end # def tpl
|
309
|
+
end # class VPC
|
310
|
+
end # module Templates
|
311
|
+
end # module Enscalator
|