dslh 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dslh.rb +86 -58
- data/lib/dslh/version.rb +1 -1
- data/spec/Drupal_Multi_AZ.template +455 -0
- data/spec/dslh_spec.rb +1185 -3
- data/spec/spec_helper.rb +0 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 041bb7cf886d6a16fb6be02ba6ef356bf31810c7
|
4
|
+
data.tar.gz: b96cb8ee97322d53745dda628eca4e8fe6ace944
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6753cfa8efa4438bcdfb2193bb827c4268c65bef24f302d2494c759047de84442d3b318dc79871e013214641aca7e19e99e0c102e9256c53eb47fd8dab069d0a
|
7
|
+
data.tar.gz: 7d43a7ca6c3633460e47e5251dbadcb7336f7f6e342965bda4404737c2426fc9fe17125d718b221de5b33860bd6c36c706670282da265e5dfd46c0fcb93b8e8c
|
data/lib/dslh.rb
CHANGED
@@ -76,6 +76,7 @@ class Dslh
|
|
76
76
|
next_indent = (INDENT_SPACES * (depth + 1))
|
77
77
|
key_conv = @options[:key_conv] || @options[:conv]
|
78
78
|
value_conv = @options[:value_conv] || @options[:conv]
|
79
|
+
nested = false
|
79
80
|
|
80
81
|
if exclude_key?(key_conv, hash.keys)
|
81
82
|
buf.puts('(' + ("\n" + hash.pretty_inspect.strip).gsub("\n", "\n" + indent) + ')')
|
@@ -83,86 +84,96 @@ class Dslh
|
|
83
84
|
end
|
84
85
|
|
85
86
|
hash.each do |key, value|
|
86
|
-
|
87
|
-
|
87
|
+
value_proc = proc do |value_buf|
|
88
|
+
case value
|
89
|
+
when Hash
|
90
|
+
if exclude_key?(key_conv, value.keys)
|
91
|
+
value_buf.puts('(' + ("\n" + value.pretty_inspect.strip).gsub("\n", "\n" + next_indent) + ')')
|
92
|
+
else
|
93
|
+
nested = true
|
94
|
+
value_buf.puts(' do')
|
95
|
+
deval0(value, depth + 1, value_buf)
|
96
|
+
value_buf.puts(indent + 'end')
|
97
|
+
end
|
98
|
+
when Array
|
99
|
+
if value.any? {|v| [Array, Hash].any? {|c| v.kind_of?(c) }}
|
100
|
+
nested = true
|
101
|
+
value_buf.puts(' [')
|
102
|
+
|
103
|
+
value.each_with_index do |v, i|
|
104
|
+
if v.kind_of?(Hash)
|
105
|
+
value_buf.puts(next_indent + '_{')
|
106
|
+
deval0(v, depth + 2, value_buf)
|
107
|
+
value_buf.print(next_indent + '}')
|
108
|
+
else
|
109
|
+
value_buf.print(next_indent + v.pretty_inspect.strip.gsub("\n", "\n" + next_indent))
|
110
|
+
end
|
111
|
+
|
112
|
+
value_buf.puts(i < (value.length - 1) ? ',' : '')
|
113
|
+
end
|
88
114
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
115
|
+
value_buf.puts(indent + ']')
|
116
|
+
elsif value.length == 1
|
117
|
+
value_buf.puts(' ' + value.inspect)
|
118
|
+
else
|
119
|
+
value_buf.puts(' ' + value.map {|v|
|
120
|
+
v = value_conv.call(v) if value_conv
|
121
|
+
|
122
|
+
if v.kind_of?(Hash)
|
123
|
+
'(' + v.inspect + ')'
|
124
|
+
else
|
125
|
+
v.inspect
|
126
|
+
end
|
127
|
+
}.join(', '))
|
128
|
+
end
|
93
129
|
else
|
94
|
-
|
95
|
-
|
96
|
-
buf.puts(indent + 'end')
|
130
|
+
value = value_conv.call(value) if value_conv
|
131
|
+
value_buf.puts(' ' + value.inspect)
|
97
132
|
end
|
98
|
-
|
99
|
-
if value.any? {|v| [Array, Hash].any? {|c| v.kind_of?(c) }}
|
100
|
-
buf.puts(' [')
|
101
|
-
|
102
|
-
value.each_with_index do |v, i|
|
103
|
-
if v.kind_of?(Hash)
|
104
|
-
buf.puts(next_indent + '_{')
|
105
|
-
deval0(v, depth + 2, buf)
|
106
|
-
buf.print(next_indent + '}')
|
107
|
-
else
|
108
|
-
buf.print(next_indent + v.pretty_inspect.strip.gsub("\n", "\n" + next_indent))
|
109
|
-
end
|
133
|
+
end
|
110
134
|
|
111
|
-
|
112
|
-
end
|
135
|
+
key = key_conv.call(key) if key_conv
|
113
136
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
else
|
118
|
-
buf.puts(' ' + value.map {|v|
|
119
|
-
v = value_conv.call(v) if value_conv
|
137
|
+
if key.kind_of?(Proc)
|
138
|
+
tmp_buf = StringIO.new
|
139
|
+
value_proc.call(tmp_buf)
|
120
140
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
141
|
+
key_value = case key.arity
|
142
|
+
when 0
|
143
|
+
key.call
|
144
|
+
when 1
|
145
|
+
key.call(tmp_buf.string.strip)
|
146
|
+
else
|
147
|
+
key.call(tmp_buf.string.strip, nested)
|
148
|
+
end
|
149
|
+
|
150
|
+
buf.puts(indent + key_value)
|
128
151
|
else
|
129
|
-
|
130
|
-
|
152
|
+
buf.print(indent + key)
|
153
|
+
value_proc.call(buf)
|
131
154
|
end
|
132
155
|
end
|
133
156
|
end
|
134
157
|
|
135
158
|
def exclude_key?(key_conv, keys)
|
136
159
|
exclude_key = @options[:exclude_key] || proc {|k| k.to_s !~ /\A[_a-z]\w+\Z/i }
|
137
|
-
|
160
|
+
|
161
|
+
if not @options.has_key?(:exclude_key) and key_conv
|
162
|
+
keys = keys.map {|k| key_conv.call(k) }
|
163
|
+
end
|
164
|
+
|
165
|
+
keys.any? {|k| exclude_key.call(k) }
|
138
166
|
end
|
139
167
|
|
140
168
|
class Scope
|
141
169
|
def _(&block)
|
142
|
-
|
143
|
-
hash_orig = @__hash__
|
144
|
-
@__hash__ = {}
|
145
|
-
self.instance_eval(&block)
|
146
|
-
nested_hash = @__hash__
|
147
|
-
@__hash__ = hash_orig
|
148
|
-
return nested_hash
|
149
|
-
end
|
170
|
+
ScopeBlock.nest(binding, 'block')
|
150
171
|
end
|
151
172
|
|
152
173
|
def method_missing(method_name, *args, &block)
|
153
174
|
key_conv = @__options__[:key_conv] || @__options__[:conv]
|
154
175
|
value_conv = @__options__[:value_conv] || @__options__[:conv]
|
155
|
-
|
156
|
-
nested_hash = nil
|
157
|
-
|
158
|
-
if block
|
159
|
-
hash_orig = @__hash__
|
160
|
-
@__hash__ = {}
|
161
|
-
self.instance_eval(&block)
|
162
|
-
nested_hash = @__hash__
|
163
|
-
@__hash__ = hash_orig
|
164
|
-
end
|
165
|
-
|
176
|
+
nested_hash = ScopeBlock.nest(binding, 'block')
|
166
177
|
method_name = key_conv.call(method_name) if key_conv
|
167
178
|
|
168
179
|
if args.empty?
|
@@ -183,4 +194,21 @@ class Dslh
|
|
183
194
|
end
|
184
195
|
end
|
185
196
|
end # of Scope
|
197
|
+
|
198
|
+
class ScopeBlock
|
199
|
+
def self.nest(bind, block_var)
|
200
|
+
eval(<<-EOS, bind)
|
201
|
+
if #{block_var}
|
202
|
+
__hash_orig = @__hash__
|
203
|
+
@__hash__ = {}
|
204
|
+
self.instance_eval(&#{block_var})
|
205
|
+
__nested_hash = @__hash__
|
206
|
+
@__hash__ = __hash_orig
|
207
|
+
__nested_hash
|
208
|
+
else
|
209
|
+
nil
|
210
|
+
end
|
211
|
+
EOS
|
212
|
+
end
|
213
|
+
end
|
186
214
|
end
|
data/lib/dslh/version.rb
CHANGED
@@ -0,0 +1,455 @@
|
|
1
|
+
{
|
2
|
+
"AWSTemplateFormatVersion" : "2010-09-09",
|
3
|
+
|
4
|
+
"Description" : "AWS CloudFormation Sample Template Drupal_Multi_AZ. Drupal is an open source content management platform powering millions of websites and applications. This template installs a highly-available, scalable Drupal deployment using a multi-az Amazon RDS database instance for storage. It uses the AWS CloudFormation bootstrap scripts to install packages and files at instance launch time. **WARNING** This template creates one or more Amazon EC2 instances, an Elastic Load Balancer and an Amazon RDS database. You will be billed for the AWS resources used if you create a stack from this template.",
|
5
|
+
|
6
|
+
"Parameters" : {
|
7
|
+
|
8
|
+
"KeyName": {
|
9
|
+
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
|
10
|
+
"Type": "String",
|
11
|
+
"MinLength": "1",
|
12
|
+
"MaxLength": "255",
|
13
|
+
"AllowedPattern" : "[\\x20-\\x7E]*",
|
14
|
+
"ConstraintDescription" : "can contain only ASCII characters."
|
15
|
+
},
|
16
|
+
|
17
|
+
"InstanceType" : {
|
18
|
+
"Description" : "WebServer EC2 instance type",
|
19
|
+
"Type" : "String",
|
20
|
+
"Default" : "m1.small",
|
21
|
+
"ConstraintDescription" : "must be a valid EC2 instance type."
|
22
|
+
},
|
23
|
+
|
24
|
+
"SiteName": {
|
25
|
+
"Default": "My Site",
|
26
|
+
"Description" : "The name of the Drupal Site",
|
27
|
+
"Type": "String"
|
28
|
+
},
|
29
|
+
|
30
|
+
"SiteEMail": {
|
31
|
+
"Description" : "EMail for site adminitrator",
|
32
|
+
"Type": "String"
|
33
|
+
},
|
34
|
+
|
35
|
+
"SiteAdmin": {
|
36
|
+
"Description" : "The Drupal site admin account username",
|
37
|
+
"Type": "String",
|
38
|
+
"MinLength": "1",
|
39
|
+
"MaxLength": "16",
|
40
|
+
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
|
41
|
+
"ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
|
42
|
+
},
|
43
|
+
|
44
|
+
"SitePassword": {
|
45
|
+
"NoEcho": "true",
|
46
|
+
"Description" : "The Drupal site admin account password",
|
47
|
+
"Type": "String",
|
48
|
+
"MinLength": "1",
|
49
|
+
"MaxLength": "41",
|
50
|
+
"AllowedPattern" : "[a-zA-Z0-9]*",
|
51
|
+
"ConstraintDescription" : "must contain only alphanumeric characters."
|
52
|
+
},
|
53
|
+
|
54
|
+
"DBName": {
|
55
|
+
"Default": "drupaldb",
|
56
|
+
"Description" : "The Drupal database name",
|
57
|
+
"Type": "String",
|
58
|
+
"MinLength": "1",
|
59
|
+
"MaxLength": "64",
|
60
|
+
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
|
61
|
+
"ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
|
62
|
+
},
|
63
|
+
|
64
|
+
"DBUsername": {
|
65
|
+
"Default": "admin",
|
66
|
+
"NoEcho": "true",
|
67
|
+
"Description" : "The Drupal database admin account username",
|
68
|
+
"Type": "String",
|
69
|
+
"MinLength": "1",
|
70
|
+
"MaxLength": "16",
|
71
|
+
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
|
72
|
+
"ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
|
73
|
+
},
|
74
|
+
|
75
|
+
"DBPassword": {
|
76
|
+
"Default": "password",
|
77
|
+
"NoEcho": "true",
|
78
|
+
"Description" : "The Drupal database admin account password",
|
79
|
+
"Type": "String",
|
80
|
+
"MinLength": "8",
|
81
|
+
"MaxLength": "41",
|
82
|
+
"AllowedPattern" : "[a-zA-Z0-9]*",
|
83
|
+
"ConstraintDescription" : "must contain only alphanumeric characters."
|
84
|
+
},
|
85
|
+
|
86
|
+
"DBClass" : {
|
87
|
+
"Default" : "db.m1.small",
|
88
|
+
"Description" : "Database instance class",
|
89
|
+
"Type" : "String",
|
90
|
+
"AllowedValues" : [ "db.m1.small", "db.m1.large", "db.m1.xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge" ],
|
91
|
+
"ConstraintDescription" : "must select a valid database instance type."
|
92
|
+
},
|
93
|
+
|
94
|
+
"DBAllocatedStorage" : {
|
95
|
+
"Default": "5",
|
96
|
+
"Description" : "The size of the database (Gb)",
|
97
|
+
"Type": "Number",
|
98
|
+
"MinValue": "5",
|
99
|
+
"MaxValue": "1024",
|
100
|
+
"ConstraintDescription" : "must be between 5 and 1024Gb."
|
101
|
+
},
|
102
|
+
|
103
|
+
"MultiAZDatabase": {
|
104
|
+
"Default": "true",
|
105
|
+
"Description" : "Create a multi-AZ MySQL Amazon RDS database instance",
|
106
|
+
"Type": "String",
|
107
|
+
"AllowedValues" : [ "true", "false" ],
|
108
|
+
"ConstraintDescription" : "must be either true or false."
|
109
|
+
},
|
110
|
+
|
111
|
+
"WebServerCapacity": {
|
112
|
+
"Default": "2",
|
113
|
+
"Description" : "The initial number of WebServer instances",
|
114
|
+
"Type": "Number",
|
115
|
+
"MinValue": "1",
|
116
|
+
"MaxValue": "5",
|
117
|
+
"ConstraintDescription" : "must be between 1 and 5 EC2 instances."
|
118
|
+
},
|
119
|
+
"SSHLocation" : {
|
120
|
+
"Description" : "The IP address range that can be used to SSH to the EC2 instances",
|
121
|
+
"Type": "String",
|
122
|
+
"MinLength": "9",
|
123
|
+
"MaxLength": "18",
|
124
|
+
"Default": "0.0.0.0/0",
|
125
|
+
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
126
|
+
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
|
127
|
+
}
|
128
|
+
},
|
129
|
+
|
130
|
+
"Mappings" : {
|
131
|
+
"AWSInstanceType2Arch" : {
|
132
|
+
"t1.micro" : { "Arch" : "64" },
|
133
|
+
"m1.small" : { "Arch" : "64" },
|
134
|
+
"m1.medium" : { "Arch" : "64" },
|
135
|
+
"m1.large" : { "Arch" : "64" },
|
136
|
+
"m1.xlarge" : { "Arch" : "64" },
|
137
|
+
"m2.xlarge" : { "Arch" : "64" },
|
138
|
+
"m2.2xlarge" : { "Arch" : "64" },
|
139
|
+
"m2.4xlarge" : { "Arch" : "64" },
|
140
|
+
"m3.xlarge" : { "Arch" : "64" },
|
141
|
+
"m3.2xlarge" : { "Arch" : "64" },
|
142
|
+
"c1.medium" : { "Arch" : "64" },
|
143
|
+
"c1.xlarge" : { "Arch" : "64" },
|
144
|
+
"cc1.4xlarge" : { "Arch" : "64HVM" },
|
145
|
+
"cc2.8xlarge" : { "Arch" : "64HVM" },
|
146
|
+
"cg1.4xlarge" : { "Arch" : "64HVM" }
|
147
|
+
},
|
148
|
+
|
149
|
+
"AWSRegionArch2AMI" : {
|
150
|
+
"us-east-1" : { "32" : "ami-a0cd60c9", "64" : "ami-aecd60c7", "64HVM" : "ami-a8cd60c1" },
|
151
|
+
"us-west-2" : { "32" : "ami-46da5576", "64" : "ami-48da5578", "64HVM" : "NOT_YET_SUPPORTED" },
|
152
|
+
"us-west-1" : { "32" : "ami-7d4c6938", "64" : "ami-734c6936", "64HVM" : "NOT_YET_SUPPORTED" },
|
153
|
+
"eu-west-1" : { "32" : "ami-61555115", "64" : "ami-6d555119", "64HVM" : "ami-67555113" },
|
154
|
+
"ap-southeast-1" : { "32" : "ami-220b4a70", "64" : "ami-3c0b4a6e", "64HVM" : "NOT_YET_SUPPORTED" },
|
155
|
+
"ap-southeast-2" : { "32" : "ami-8f990eb5", "64" : "ami-95990eaf", "64HVM" : "NOT_YET_SUPPORTED" },
|
156
|
+
"ap-northeast-1" : { "32" : "ami-2a19aa2b", "64" : "ami-2819aa29", "64HVM" : "NOT_YET_SUPPORTED" },
|
157
|
+
"sa-east-1" : { "32" : "ami-f836e8e5", "64" : "ami-fe36e8e3", "64HVM" : "NOT_YET_SUPPORTED" }
|
158
|
+
}
|
159
|
+
},
|
160
|
+
|
161
|
+
"Resources" : {
|
162
|
+
|
163
|
+
"S3Bucket" : {
|
164
|
+
"Type" : "AWS::S3::Bucket",
|
165
|
+
"DeletionPolicy" : "Retain"
|
166
|
+
},
|
167
|
+
|
168
|
+
"BucketPolicy" : {
|
169
|
+
"Type" : "AWS::S3::BucketPolicy",
|
170
|
+
"Properties" : {
|
171
|
+
"PolicyDocument": {
|
172
|
+
"Version" : "2008-10-17",
|
173
|
+
"Id" : "UploadPolicy",
|
174
|
+
"Statement" : [{
|
175
|
+
"Sid" : "EnableReadWrite",
|
176
|
+
"Action" : ["s3:GetObject", "s3:PutObject", "s3:PutObjectACL" ],
|
177
|
+
"Effect" : "Allow",
|
178
|
+
"Resource" : { "Fn::Join" : ["", ["arn:aws:s3:::", {"Ref" : "S3Bucket"} , "/*"]]},
|
179
|
+
"Principal" : { "AWS": {"Fn::GetAtt" : ["S3User", "Arn"]} }
|
180
|
+
}]
|
181
|
+
},
|
182
|
+
"Bucket" : {"Ref" : "S3Bucket"}
|
183
|
+
}
|
184
|
+
},
|
185
|
+
|
186
|
+
"S3User" : {
|
187
|
+
"Type" : "AWS::IAM::User",
|
188
|
+
"Properties" : {
|
189
|
+
"Path": "/",
|
190
|
+
"Policies": [{
|
191
|
+
"PolicyName": "root",
|
192
|
+
"PolicyDocument": { "Statement":[{
|
193
|
+
"Effect":"Allow",
|
194
|
+
"Action":"s3:*",
|
195
|
+
"Resource":"*"
|
196
|
+
}]}
|
197
|
+
}]
|
198
|
+
}
|
199
|
+
},
|
200
|
+
|
201
|
+
"S3Keys" : {
|
202
|
+
"Type" : "AWS::IAM::AccessKey",
|
203
|
+
"Properties" : {
|
204
|
+
"UserName" : {"Ref": "S3User"}
|
205
|
+
}
|
206
|
+
},
|
207
|
+
|
208
|
+
"ElasticLoadBalancer" : {
|
209
|
+
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
|
210
|
+
"Metadata" : {
|
211
|
+
"Comment" : "Configure the Load Balancer with a simple health check and cookie-based stickiness"
|
212
|
+
},
|
213
|
+
"Properties" : {
|
214
|
+
"AvailabilityZones" : { "Fn::GetAZs" : "" },
|
215
|
+
"LBCookieStickinessPolicy" : [ {
|
216
|
+
"PolicyName" : "CookieBasedPolicy",
|
217
|
+
"CookieExpirationPeriod" : "30"
|
218
|
+
} ],
|
219
|
+
"Listeners" : [ {
|
220
|
+
"LoadBalancerPort" : "80",
|
221
|
+
"InstancePort" : "80",
|
222
|
+
"Protocol" : "HTTP",
|
223
|
+
"PolicyNames" : [ "CookieBasedPolicy" ]
|
224
|
+
} ],
|
225
|
+
"HealthCheck" : {
|
226
|
+
"Target" : "HTTP:80/",
|
227
|
+
"HealthyThreshold" : "2",
|
228
|
+
"UnhealthyThreshold" : "5",
|
229
|
+
"Interval" : "10",
|
230
|
+
"Timeout" : "5"
|
231
|
+
}
|
232
|
+
}
|
233
|
+
},
|
234
|
+
|
235
|
+
"WebServerGroup" : {
|
236
|
+
"Type" : "AWS::AutoScaling::AutoScalingGroup",
|
237
|
+
"Properties" : {
|
238
|
+
"AvailabilityZones" : { "Fn::GetAZs" : "" },
|
239
|
+
"LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
|
240
|
+
"MinSize" : "1",
|
241
|
+
"MaxSize" : "5",
|
242
|
+
"DesiredCapacity" : { "Ref" : "WebServerCapacity" },
|
243
|
+
"LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ]
|
244
|
+
}
|
245
|
+
},
|
246
|
+
|
247
|
+
"LaunchConfig": {
|
248
|
+
"Type" : "AWS::AutoScaling::LaunchConfiguration",
|
249
|
+
"Metadata" : {
|
250
|
+
"AWS::CloudFormation::Init" : {
|
251
|
+
"config" : {
|
252
|
+
"packages" : {
|
253
|
+
"yum" : {
|
254
|
+
"httpd" : [],
|
255
|
+
"php" : [],
|
256
|
+
"php-mysql" : [],
|
257
|
+
"php-gd" : [],
|
258
|
+
"php-xml" : [],
|
259
|
+
"php-mbstring" : [],
|
260
|
+
"mysql" : [],
|
261
|
+
"gcc" : [],
|
262
|
+
"make" : [],
|
263
|
+
"libstdc++-devel" : [],
|
264
|
+
"gcc-c++" : [],
|
265
|
+
"fuse" : [],
|
266
|
+
"fuse-devel" : [],
|
267
|
+
"libcurl-devel" : [],
|
268
|
+
"libxml2-devel" : [],
|
269
|
+
"openssl-devel" : [],
|
270
|
+
"mailcap" : []
|
271
|
+
|
272
|
+
}
|
273
|
+
},
|
274
|
+
|
275
|
+
"sources" : {
|
276
|
+
"/var/www/html" : "http://ftp.drupal.org/files/projects/drupal-7.8.tar.gz",
|
277
|
+
"/home/ec2-user" : "http://ftp.drupal.org/files/projects/drush-7.x-4.5.tar.gz",
|
278
|
+
"/home/ec2-user/s3fs" : "http://s3fs.googlecode.com/files/s3fs-1.61.tar.gz"
|
279
|
+
},
|
280
|
+
|
281
|
+
"files" : {
|
282
|
+
"/etc/passwd-s3fs" : {
|
283
|
+
"content" : { "Fn::Join" : ["", [ { "Ref" : "S3Keys" }, ":", {"Fn::GetAtt": ["S3Keys", "SecretAccessKey"]}, "\n" ]]},
|
284
|
+
"mode" : "000400",
|
285
|
+
"owner" : "root",
|
286
|
+
"group" : "root"
|
287
|
+
},
|
288
|
+
|
289
|
+
"/home/ec2-user/settings.php" : {
|
290
|
+
"content" : { "Fn::Join" : ["", [
|
291
|
+
"<?php\n",
|
292
|
+
"\n",
|
293
|
+
"$databases = array (\n",
|
294
|
+
" 'default' =>\n",
|
295
|
+
" array (\n",
|
296
|
+
" 'default' =>\n",
|
297
|
+
" array (\n",
|
298
|
+
" 'database' => '", { "Ref" : "DBName" }, "',\n",
|
299
|
+
" 'username' => '", { "Ref" : "DBUsername" }, "',\n",
|
300
|
+
" 'password' => '", { "Ref" : "DBPassword" }, "',\n",
|
301
|
+
" 'host' => '", {"Fn::GetAtt" : ["DBInstance", "Endpoint.Address"]}, "',\n",
|
302
|
+
" 'port' => '", {"Fn::GetAtt" : ["DBInstance", "Endpoint.Port"]}, "',\n",
|
303
|
+
" 'driver' => 'mysql',\n",
|
304
|
+
" 'prefix' => 'drupal_',\n",
|
305
|
+
" ),\n",
|
306
|
+
" ),\n",
|
307
|
+
");\n",
|
308
|
+
"\n",
|
309
|
+
"$update_free_access = FALSE;\n",
|
310
|
+
"\n",
|
311
|
+
"$drupal_hash_salt = '0c3R8noNALe3shsioQr5hK1dMHdwRfikLoSfqn0_xpA';\n",
|
312
|
+
"\n",
|
313
|
+
"ini_set('session.gc_probability', 1);\n",
|
314
|
+
"ini_set('session.gc_divisor', 100);\n",
|
315
|
+
"ini_set('session.gc_maxlifetime', 200000);\n",
|
316
|
+
"ini_set('session.cookie_lifetime', 2000000);\n"
|
317
|
+
]]},
|
318
|
+
"mode" : "000400",
|
319
|
+
"owner" : "root",
|
320
|
+
"group" : "root"
|
321
|
+
}
|
322
|
+
},
|
323
|
+
|
324
|
+
"services" : {
|
325
|
+
"sysvinit" : {
|
326
|
+
"httpd" : { "enabled" : "true", "ensureRunning" : "true" },
|
327
|
+
"sendmail" : { "enabled" : "false", "ensureRunning" : "false" }
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
}
|
332
|
+
},
|
333
|
+
"Properties": {
|
334
|
+
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
|
335
|
+
{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
|
336
|
+
"InstanceType" : { "Ref" : "InstanceType" },
|
337
|
+
"SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ],
|
338
|
+
"KeyName" : { "Ref" : "KeyName" },
|
339
|
+
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
|
340
|
+
"#!/bin/bash -v\n",
|
341
|
+
"yum update -y aws-cfn-bootstrap\n",
|
342
|
+
|
343
|
+
"# Helper function\n",
|
344
|
+
"function error_exit\n",
|
345
|
+
"{\n",
|
346
|
+
" /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n",
|
347
|
+
" exit 1\n",
|
348
|
+
"}\n",
|
349
|
+
|
350
|
+
"# Install Apache Web Server, MySQL and Drupal\n",
|
351
|
+
"/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r LaunchConfig ",
|
352
|
+
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
|
353
|
+
|
354
|
+
"# Install s3fs\n",
|
355
|
+
"cd /home/ec2-user/s3fs/s3fs-1.61\n",
|
356
|
+
"./configure --prefix=/usr\n",
|
357
|
+
"make\n",
|
358
|
+
"make install\n",
|
359
|
+
|
360
|
+
"# Move the website files to the top level\n",
|
361
|
+
"mv /var/www/html/drupal-7.8/* /var/www/html\n",
|
362
|
+
"mv /var/www/html/drupal-7.8/.htaccess /var/www/html\n",
|
363
|
+
"rm -Rf /var/www/html/drupal-7.8\n",
|
364
|
+
|
365
|
+
"# Mount the S3 bucket\n",
|
366
|
+
"mv /var/www/html/sites/default/files /var/www/html/sites/default/files_original\n",
|
367
|
+
"mkdir -p /var/www/html/sites/default/files\n",
|
368
|
+
"s3fs -o allow_other -o use_cache=/tmp ", { "Ref" : "S3Bucket" } ," /var/www/html/sites/default/files || error_exit 'Failed to mount the S3 bucket'\n",
|
369
|
+
"echo `hostname` >> /var/www/html/sites/default/files/hosts\n",
|
370
|
+
|
371
|
+
"# Make changes to Apache Web Server configuration\n",
|
372
|
+
"sed -i 's/AllowOverride None/AllowOverride All/g' /etc/httpd/conf/httpd.conf\n",
|
373
|
+
"service httpd restart\n",
|
374
|
+
|
375
|
+
"# Only execute the site install if we are the first host up - otherwise we'll end up losing all the data\n",
|
376
|
+
"read first < /var/www/html/sites/default/files/hosts\n",
|
377
|
+
"if [ `hostname` = $first ]\n",
|
378
|
+
"then\n",
|
379
|
+
" # Create the site in Drupal\n",
|
380
|
+
" cd /var/www/html\n",
|
381
|
+
" ~ec2-user/drush/drush site-install standard --yes",
|
382
|
+
" --site-name='", { "Ref" : "SiteName" }, "' --site-mail=", { "Ref" : "SiteEMail" },
|
383
|
+
" --account-name=", { "Ref" : "SiteAdmin" }, " --account-pass=", { "Ref" : "SitePassword" },
|
384
|
+
" --db-url=mysql://", { "Ref" : "DBUsername" }, ":", { "Ref" : "DBPassword" }, "@", {"Fn::GetAtt" : ["DBInstance", "Endpoint.Address"]}, ":", {"Fn::GetAtt" : ["DBInstance", "Endpoint.Port"]}, "/", { "Ref" : "DBName" },
|
385
|
+
" --db-prefix=drupal_\n",
|
386
|
+
" # use the S3 bucket for shared file storage\n",
|
387
|
+
" cp -R sites/default/files_original/* sites/default/files\n",
|
388
|
+
" cp -R sites/default/files_original/.htaccess sites/default/files\n",
|
389
|
+
"else\n",
|
390
|
+
" # Copy settings.php file since everything else is configured\n",
|
391
|
+
" cp /home/ec2-user/settings.php /var/www/html/sites/default\n",
|
392
|
+
"fi\n",
|
393
|
+
"rm /home/ec2-user/settings.php\n",
|
394
|
+
|
395
|
+
"# All is well so signal success\n",
|
396
|
+
"/opt/aws/bin/cfn-signal -e 0 -r \"Drupal setup complete\" '", { "Ref" : "WaitHandle" }, "'\n"
|
397
|
+
|
398
|
+
]]}}
|
399
|
+
}
|
400
|
+
},
|
401
|
+
|
402
|
+
"WaitHandle" : {
|
403
|
+
"Type" : "AWS::CloudFormation::WaitConditionHandle"
|
404
|
+
},
|
405
|
+
|
406
|
+
"WaitCondition" : {
|
407
|
+
"Type" : "AWS::CloudFormation::WaitCondition",
|
408
|
+
"DependsOn" : "WebServerGroup",
|
409
|
+
"Properties" : {
|
410
|
+
"Handle" : {"Ref" : "WaitHandle"},
|
411
|
+
"Timeout" : "600"
|
412
|
+
}
|
413
|
+
},
|
414
|
+
|
415
|
+
"DBInstance" : {
|
416
|
+
"Type": "AWS::RDS::DBInstance",
|
417
|
+
"Properties": {
|
418
|
+
"DBName" : { "Ref" : "DBName" },
|
419
|
+
"Engine" : "MySQL",
|
420
|
+
"MultiAZ" : { "Ref": "MultiAZDatabase" },
|
421
|
+
"MasterUsername" : { "Ref" : "DBUsername" },
|
422
|
+
"DBInstanceClass" : { "Ref" : "DBClass" },
|
423
|
+
"DBSecurityGroups" : [{ "Ref" : "DBSecurityGroup" }],
|
424
|
+
"AllocatedStorage" : { "Ref" : "DBAllocatedStorage" },
|
425
|
+
"MasterUserPassword": { "Ref" : "DBPassword" }
|
426
|
+
}
|
427
|
+
},
|
428
|
+
|
429
|
+
"DBSecurityGroup": {
|
430
|
+
"Type": "AWS::RDS::DBSecurityGroup",
|
431
|
+
"Properties": {
|
432
|
+
"DBSecurityGroupIngress": { "EC2SecurityGroupName": { "Ref": "WebServerSecurityGroup"} },
|
433
|
+
"GroupDescription" : "Frontend Access"
|
434
|
+
}
|
435
|
+
},
|
436
|
+
|
437
|
+
"WebServerSecurityGroup" : {
|
438
|
+
"Type" : "AWS::EC2::SecurityGroup",
|
439
|
+
"Properties" : {
|
440
|
+
"GroupDescription" : "Enable HTTP access via port 80, locked down to requests from the load balancer only and SSH access",
|
441
|
+
"SecurityGroupIngress" : [
|
442
|
+
{"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]},"SourceSecurityGroupName" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}},
|
443
|
+
{"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}}
|
444
|
+
]
|
445
|
+
}
|
446
|
+
}
|
447
|
+
},
|
448
|
+
|
449
|
+
"Outputs" : {
|
450
|
+
"WebsiteURL" : {
|
451
|
+
"Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]] },
|
452
|
+
"Description" : "Drupal Website"
|
453
|
+
}
|
454
|
+
}
|
455
|
+
}
|