formatron 0.1.14 → 0.1.15
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 +4 -4
- data/formatron.gemspec +2 -1
- data/lib/formatron.rb +23 -10
- data/lib/formatron/aws.rb +26 -13
- data/lib/formatron/chef.rb +53 -9
- data/lib/formatron/chef/berkshelf.rb +15 -11
- data/lib/formatron/chef/keys.rb +5 -9
- data/lib/formatron/chef/knife.rb +39 -30
- data/lib/formatron/chef/ssh.rb +4 -1
- data/lib/formatron/chef/winrm.rb +37 -0
- data/lib/formatron/chef_clients.rb +6 -4
- data/lib/formatron/cli/generators/credentials.rb +1 -1
- data/lib/formatron/cloud_formation/resources/ec2.rb +58 -57
- data/lib/formatron/cloud_formation/scripts.rb +75 -3
- data/lib/formatron/cloud_formation/template.rb +6 -0
- data/lib/formatron/cloud_formation/template/vpc.rb +8 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet.rb +8 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/bastion.rb +12 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/chef_server.rb +12 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance.rb +13 -2
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/security_group.rb +47 -2
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/setup.rb +92 -27
- data/lib/formatron/cloud_formation/template/vpc/subnet/nat.rb +12 -0
- data/lib/formatron/dsl/formatron/global.rb +2 -0
- data/lib/formatron/dsl/formatron/global/windows.rb +17 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance.rb +1 -0
- data/lib/formatron/external/dsl.rb +19 -0
- data/lib/formatron/util/winrm.rb +40 -0
- data/lib/formatron/version.rb +1 -1
- metadata +33 -16
data/lib/formatron/chef/keys.rb
CHANGED
@@ -5,19 +5,18 @@ class Formatron
|
|
5
5
|
# Download the Chef Server keys
|
6
6
|
class Keys
|
7
7
|
# rubocop:disable Metrics/ParameterLists
|
8
|
-
def initialize(aws:, bucket:, name:, target:, guid:, ec2_key:)
|
8
|
+
def initialize(directory:, aws:, bucket:, name:, target:, guid:, ec2_key:)
|
9
9
|
@aws = aws
|
10
10
|
@bucket = bucket
|
11
11
|
@name = name
|
12
12
|
@target = target
|
13
13
|
@guid = guid
|
14
14
|
@ec2_key = ec2_key
|
15
|
+
@directory = directory
|
15
16
|
end
|
16
17
|
# rubocop:enable Metrics/ParameterLists
|
17
18
|
|
18
|
-
# rubocop:disable Metrics/MethodLength
|
19
19
|
def init
|
20
|
-
@directory = Dir.mktmpdir 'formatron-chef-server-keys-'
|
21
20
|
S3::ChefServerKeys.get(
|
22
21
|
aws: @aws,
|
23
22
|
bucket: @bucket,
|
@@ -29,23 +28,20 @@ class Formatron
|
|
29
28
|
File.write ec2_key, @ec2_key
|
30
29
|
File.chmod 0600, ec2_key
|
31
30
|
end
|
32
|
-
# rubocop:enable Metrics/MethodLength
|
33
31
|
|
34
32
|
def user_key
|
35
33
|
S3::ChefServerKeys.user_pem_path directory: @directory
|
36
34
|
end
|
37
35
|
|
38
36
|
def organization_key
|
39
|
-
S3::ChefServerKeys.organization_pem_path
|
37
|
+
S3::ChefServerKeys.organization_pem_path(
|
38
|
+
directory: @directory
|
39
|
+
)
|
40
40
|
end
|
41
41
|
|
42
42
|
def ec2_key
|
43
43
|
File.join @directory, 'ec2_key'
|
44
44
|
end
|
45
|
-
|
46
|
-
def unlink
|
47
|
-
FileUtils.rm_rf @directory unless @directory.nil?
|
48
|
-
end
|
49
45
|
end
|
50
46
|
end
|
51
47
|
end
|
data/lib/formatron/chef/knife.rb
CHANGED
@@ -7,10 +7,18 @@ class Formatron
|
|
7
7
|
# Wrapper for the knife cli
|
8
8
|
# rubocop:disable Metrics/ClassLength
|
9
9
|
class Knife
|
10
|
+
CONFIG_FILE = 'knife.rb'
|
11
|
+
DATABAG_SECRET_FILE = 'databag_secret'
|
12
|
+
DATABAG_DIRECTORY = 'databag'
|
13
|
+
DATABAG_ITEM_SUFFIX = '.json'
|
14
|
+
|
10
15
|
# rubocop:disable Metrics/MethodLength
|
11
16
|
# rubocop:disable Metrics/ParameterLists
|
12
17
|
def initialize(
|
18
|
+
directory:,
|
13
19
|
keys:,
|
20
|
+
administrator_name:,
|
21
|
+
administrator_password:,
|
14
22
|
chef_server_url:,
|
15
23
|
username:,
|
16
24
|
organization:,
|
@@ -18,7 +26,12 @@ class Formatron
|
|
18
26
|
databag_secret:,
|
19
27
|
configuration:
|
20
28
|
)
|
29
|
+
@knife_file = File.join directory, CONFIG_FILE
|
30
|
+
@databag_secret_file = File.join directory, DATABAG_SECRET_FILE
|
31
|
+
@databag_directory = File.join directory, DATABAG_DIRECTORY
|
21
32
|
@keys = keys
|
33
|
+
@administrator_name = administrator_name
|
34
|
+
@administrator_password = administrator_password
|
22
35
|
@chef_server_url = chef_server_url
|
23
36
|
@username = username
|
24
37
|
@organization = organization
|
@@ -31,8 +44,7 @@ class Formatron
|
|
31
44
|
|
32
45
|
# rubocop:disable Metrics/MethodLength
|
33
46
|
def init
|
34
|
-
@knife_file
|
35
|
-
@knife_file.write <<-EOH.gsub(/^ {10}/, '')
|
47
|
+
File.write @knife_file, <<-EOH.gsub(/^ {10}/, '')
|
36
48
|
chef_server_url '#{@chef_server_url}'
|
37
49
|
validation_client_name '#{@organization}-validator'
|
38
50
|
validation_key '#{@keys.organization_key}'
|
@@ -41,28 +53,25 @@ class Formatron
|
|
41
53
|
verify_api_cert #{@ssl_verify}
|
42
54
|
ssl_verify_mode #{@ssl_verify ? ':verify_peer' : ':verify_none'}
|
43
55
|
EOH
|
44
|
-
@
|
45
|
-
|
46
|
-
@databag_secret_file.write @databag_secret
|
47
|
-
@databag_secret_file.close
|
56
|
+
File.write @databag_secret_file, @databag_secret
|
57
|
+
FileUtils.mkdir_p @databag_directory
|
48
58
|
end
|
49
59
|
# rubocop:enable Metrics/MethodLength
|
50
60
|
|
51
61
|
def deploy_databag(name:)
|
52
|
-
databag_file =
|
53
|
-
|
54
|
-
|
62
|
+
databag_file = File.join(
|
63
|
+
@databag_directory, "#{name}#{DATABAG_ITEM_SUFFIX}"
|
64
|
+
)
|
65
|
+
File.write databag_file, @configuration.merge(id: name).to_json
|
55
66
|
_attempt_to_create_databag unless _databag_exists
|
56
67
|
_attempt_to_create_databag_item(
|
57
68
|
name: name,
|
58
69
|
databag_file: databag_file
|
59
70
|
)
|
60
|
-
ensure
|
61
|
-
databag_file.unlink unless databag_file.nil?
|
62
71
|
end
|
63
72
|
|
64
73
|
def _databag_exists
|
65
|
-
Util::Shell.exec "knife data bag show formatron -c #{@knife_file
|
74
|
+
Util::Shell.exec "knife data bag show formatron -c #{@knife_file}"
|
66
75
|
end
|
67
76
|
|
68
77
|
def _attempt_to_create_databag
|
@@ -70,9 +79,7 @@ class Formatron
|
|
70
79
|
end
|
71
80
|
|
72
81
|
def _create_databag
|
73
|
-
|
74
|
-
Util::Shell.exec "knife data bag create formatron -c #{@knife_file.path}"
|
75
|
-
# rubocop:enable Metrics/LineLength
|
82
|
+
Util::Shell.exec "knife data bag create formatron -c #{@knife_file}"
|
76
83
|
end
|
77
84
|
|
78
85
|
def _attempt_to_create_databag_item(name:, databag_file:)
|
@@ -83,7 +90,7 @@ class Formatron
|
|
83
90
|
|
84
91
|
def _create_databag_item(databag_file:)
|
85
92
|
# rubocop:disable Metrics/LineLength
|
86
|
-
Util::Shell.exec "knife data bag from file formatron #{databag_file
|
93
|
+
Util::Shell.exec "knife data bag from file formatron #{databag_file} --secret-file #{@databag_secret_file} -c #{@knife_file}"
|
87
94
|
# rubocop:enable Metrics/LineLength
|
88
95
|
end
|
89
96
|
|
@@ -95,7 +102,7 @@ class Formatron
|
|
95
102
|
|
96
103
|
def _environment_exists(environment)
|
97
104
|
# rubocop:disable Metrics/LineLength
|
98
|
-
Util::Shell.exec "knife environment show #{environment} -c #{@knife_file
|
105
|
+
Util::Shell.exec "knife environment show #{environment} -c #{@knife_file}"
|
99
106
|
# rubocop:enable Metrics/LineLength
|
100
107
|
end
|
101
108
|
|
@@ -107,59 +114,61 @@ class Formatron
|
|
107
114
|
|
108
115
|
def _create_environment(environment)
|
109
116
|
# rubocop:disable Metrics/LineLength
|
110
|
-
Util::Shell.exec "knife environment create #{environment} -c #{@knife_file
|
117
|
+
Util::Shell.exec "knife environment create #{environment} -c #{@knife_file} -d '#{environment} environment created by formatron'"
|
111
118
|
# rubocop:enable Metrics/LineLength
|
112
119
|
end
|
113
120
|
|
121
|
+
# rubocop:disable Metrics/MethodLength
|
114
122
|
def bootstrap(
|
123
|
+
os:,
|
115
124
|
guid:,
|
116
125
|
bastion_hostname:,
|
117
126
|
cookbook:,
|
118
127
|
hostname:
|
119
128
|
)
|
120
129
|
# rubocop:disable Metrics/LineLength
|
121
|
-
|
122
|
-
|
130
|
+
if os.eql? 'windows'
|
131
|
+
command = "knife bootstrap windows winrm #{hostname} -x #{@administrator_name} -P '#{@administrator_password}' -E #{guid} -r #{cookbook} -N #{guid} -c #{@knife_file} --secret-file #{@databag_secret_file}"
|
132
|
+
else
|
133
|
+
command = "knife bootstrap #{hostname} --sudo -x ubuntu -i #{@keys.ec2_key} -E #{guid} -r #{cookbook} -N #{guid} -c #{@knife_file}#{@ssl_verify ? '' : ' --node-ssl-verify-mode none'} --secret-file #{@databag_secret_file}"
|
134
|
+
command = "#{command} -G ubuntu@#{bastion_hostname}" unless bastion_hostname.eql? hostname
|
135
|
+
end
|
123
136
|
fail "failed to bootstrap instance: #{guid}" unless Util::Shell.exec command
|
124
137
|
# rubocop:enable Metrics/LineLength
|
125
138
|
end
|
139
|
+
# rubocop:enable Metrics/MethodLength
|
126
140
|
|
127
141
|
def delete_databag(name:)
|
128
142
|
# rubocop:disable Metrics/LineLength
|
129
|
-
command = "knife data bag delete formatron #{name} -y -c #{@knife_file
|
143
|
+
command = "knife data bag delete formatron #{name} -y -c #{@knife_file}"
|
130
144
|
fail "failed to delete data bag item: #{name}" unless Util::Shell.exec command
|
131
145
|
# rubocop:enable Metrics/LineLength
|
132
146
|
end
|
133
147
|
|
134
148
|
def delete_node(node:)
|
135
|
-
command = "knife node delete #{node} -y -c #{@knife_file
|
149
|
+
command = "knife node delete #{node} -y -c #{@knife_file}"
|
136
150
|
fail "failed to delete node: #{node}" unless Util::Shell.exec command
|
137
151
|
end
|
138
152
|
|
139
153
|
def delete_client(client:)
|
140
154
|
# rubocop:disable Metrics/LineLength
|
141
|
-
command = "knife client delete #{client} -y -c #{@knife_file
|
155
|
+
command = "knife client delete #{client} -y -c #{@knife_file}"
|
142
156
|
fail "failed to delete client: #{client}" unless Util::Shell.exec command
|
143
157
|
# rubocop:enable Metrics/LineLength
|
144
158
|
end
|
145
159
|
|
146
160
|
def delete_environment(environment:)
|
147
161
|
# rubocop:disable Metrics/LineLength
|
148
|
-
command = "knife environment delete #{environment} -y -c #{@knife_file
|
162
|
+
command = "knife environment delete #{environment} -y -c #{@knife_file}"
|
149
163
|
fail "failed to delete environment: #{environment}" unless Util::Shell.exec command
|
150
164
|
# rubocop:enable Metrics/LineLength
|
151
165
|
end
|
152
166
|
|
153
167
|
def node_exists?(guid:)
|
154
|
-
command = "knife node show #{guid} -c #{@knife_file
|
168
|
+
command = "knife node show #{guid} -c #{@knife_file}"
|
155
169
|
Util::Shell.exec command
|
156
170
|
end
|
157
171
|
|
158
|
-
def unlink
|
159
|
-
@knife_file.unlink unless @knife_file.nil?
|
160
|
-
@databag_secret_file.unlink unless @databag_secret_file.nil?
|
161
|
-
end
|
162
|
-
|
163
172
|
private(
|
164
173
|
:_create_databag,
|
165
174
|
:_create_databag_item,
|
data/lib/formatron/chef/ssh.rb
CHANGED
@@ -11,12 +11,15 @@ class Formatron
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def run_chef_client(hostname:, bastion_hostname:)
|
14
|
+
# use the first-boot.json to ensure the runlist is correct
|
15
|
+
# if the node fails to converge the first time (in which case
|
16
|
+
# the server will show an empty run list for the node)
|
14
17
|
Formatron::Util::SSH.exec(
|
15
18
|
hostname: hostname,
|
16
19
|
bastion_hostname: bastion_hostname,
|
17
20
|
user: SSH_USER,
|
18
21
|
key: @keys.ec2_key,
|
19
|
-
command: 'sudo chef-client'
|
22
|
+
command: 'sudo chef-client -j /etc/chef/first-boot.json'
|
20
23
|
)
|
21
24
|
end
|
22
25
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'formatron/util/winrm'
|
2
|
+
|
3
|
+
class Formatron
|
4
|
+
class Chef
|
5
|
+
# Perform commands on chef nodes over WinRM
|
6
|
+
class WinRM
|
7
|
+
def initialize(administrator_name:, administrator_password:)
|
8
|
+
@administrator_name = administrator_name
|
9
|
+
@administrator_password = administrator_password
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_chef_client(hostname:)
|
13
|
+
# use the first-boot.json to ensure the runlist is correct
|
14
|
+
# if the node fails to converge the first time (in which case
|
15
|
+
# the server will show an empty run list for the node)
|
16
|
+
Formatron::Util::WinRM.exec(
|
17
|
+
hostname: hostname,
|
18
|
+
administrator_name: @administrator_name,
|
19
|
+
administrator_password: @administrator_password,
|
20
|
+
command: 'chef-client -j C:\chef\first-boot.json'
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def bootstrapped?(hostname:)
|
25
|
+
Formatron::Util::WinRM.exec(
|
26
|
+
hostname: hostname,
|
27
|
+
administrator_name: @administrator_name,
|
28
|
+
administrator_password: @administrator_password,
|
29
|
+
command: 'if (-not (Test-Path C:\chef\client.pem)) { exit 1 }'
|
30
|
+
)
|
31
|
+
true
|
32
|
+
rescue
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -5,11 +5,14 @@ class Formatron
|
|
5
5
|
# rubocop:disable Metrics/AbcSize
|
6
6
|
# rubocop:disable Metrics/MethodLength
|
7
7
|
def initialize(
|
8
|
+
directory:,
|
8
9
|
aws:,
|
9
10
|
bucket:,
|
10
11
|
name:,
|
11
12
|
target:,
|
12
13
|
ec2_key:,
|
14
|
+
administrator_name:,
|
15
|
+
administrator_password:,
|
13
16
|
hosted_zone_name:,
|
14
17
|
vpc:,
|
15
18
|
external:,
|
@@ -27,6 +30,7 @@ class Formatron
|
|
27
30
|
bastions = Hash[bastions.map { |k, v| [k, v.sub_domain] }]
|
28
31
|
chef_servers.each do |key, chef_server|
|
29
32
|
@chef_clients[key] = Chef.new(
|
33
|
+
directory: directory,
|
30
34
|
aws: aws,
|
31
35
|
bucket: bucket,
|
32
36
|
name: name,
|
@@ -36,6 +40,8 @@ class Formatron
|
|
36
40
|
ssl_verify: chef_server.ssl_verify,
|
37
41
|
chef_sub_domain: chef_server.sub_domain,
|
38
42
|
ec2_key: ec2_key,
|
43
|
+
administrator_name: administrator_name,
|
44
|
+
administrator_password: administrator_password,
|
39
45
|
bastions: bastions,
|
40
46
|
hosted_zone_name: hosted_zone_name,
|
41
47
|
server_stack: chef_server.stack || name,
|
@@ -57,9 +63,5 @@ class Formatron
|
|
57
63
|
def init
|
58
64
|
@chef_clients.values.each(&:init)
|
59
65
|
end
|
60
|
-
|
61
|
-
def unlink
|
62
|
-
@chef_clients.values.each(&:unlink)
|
63
|
-
end
|
64
66
|
end
|
65
67
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative '../template'
|
2
|
+
require_relative '../scripts'
|
2
3
|
|
3
4
|
class Formatron
|
4
5
|
module CloudFormation
|
@@ -274,49 +275,72 @@ class Formatron
|
|
274
275
|
# rubocop:disable Metrics/ParameterLists
|
275
276
|
# rubocop:disable Metrics/AbcSize
|
276
277
|
def self.instance(
|
277
|
-
scripts: nil,
|
278
|
-
script_variables: nil,
|
279
|
-
files: nil,
|
280
278
|
instance_profile:,
|
281
279
|
availability_zone:,
|
282
280
|
instance_type:,
|
283
281
|
key_name:,
|
282
|
+
administrator_name:,
|
283
|
+
administrator_password:,
|
284
284
|
subnet:,
|
285
285
|
name:,
|
286
286
|
wait_condition_handle:,
|
287
287
|
security_group:,
|
288
288
|
logical_id:,
|
289
|
-
source_dest_check
|
289
|
+
source_dest_check:,
|
290
|
+
os:
|
290
291
|
)
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
292
|
+
if os.eql? 'windows'
|
293
|
+
user_data = Template.base_64(
|
294
|
+
Template.join(
|
295
|
+
# rubocop:disable Metrics/LineLength
|
296
|
+
"<powershell>\n",
|
297
|
+
"try\n",
|
298
|
+
"{\n",
|
299
|
+
Scripts.windows_administrator(
|
300
|
+
name: administrator_name,
|
301
|
+
password: administrator_password
|
302
|
+
),
|
303
|
+
'winrm quickconfig -q', "\n",
|
304
|
+
"winrm set winrm/config/winrs '@{MaxMemoryPerShellMB=\"1024\"}'", "\n",
|
305
|
+
"winrm set winrm/config '@{MaxTimeoutms=\"1800000\"}'", "\n",
|
306
|
+
"winrm set winrm/config/service '@{AllowUnencrypted=\"true\"}'", "\n",
|
307
|
+
"winrm set winrm/config/service/auth '@{Basic=\"true\"}'", "\n",
|
308
|
+
'netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow', "\n",
|
309
|
+
'netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow', "\n",
|
310
|
+
'Stop-Service winrm', "\n",
|
311
|
+
'Set-Service winrm -startuptype "automatic"', "\n",
|
312
|
+
'Start-Service winrm', "\n",
|
313
|
+
'cfn-init.exe -v -s ', Template.ref('AWS::StackName'),
|
314
|
+
" -r #{logical_id}",
|
315
|
+
' --region ', Template.ref('AWS::Region'), "\n",
|
316
|
+
"}\n",
|
317
|
+
"catch\n",
|
318
|
+
"{\n",
|
319
|
+
'cfn-signal.exe -e 1 ',
|
320
|
+
Template.base_64(Template.ref(wait_condition_handle)), "\n",
|
321
|
+
"}\n",
|
322
|
+
'</powershell>'
|
323
|
+
# rubocop:enable Metrics/LineLength
|
324
|
+
)
|
325
|
+
)
|
326
|
+
else
|
327
|
+
user_data = Template.base_64(
|
328
|
+
Template.join(
|
329
|
+
# rubocop:disable Metrics/LineLength
|
330
|
+
"#!/bin/bash -v\n",
|
331
|
+
"apt-get -y update\n",
|
332
|
+
"apt-get -y install python-setuptools\n",
|
333
|
+
"easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
|
334
|
+
"export PATH=$PATH:/opt/aws/bin\n",
|
335
|
+
'cfn-init --region ', Template.ref('AWS::Region'),
|
336
|
+
' -v -s ', Template.ref('AWS::StackName'), " -r #{logical_id}\n",
|
337
|
+
"cfn-signal -e $? -r 'Formatron instance configuration complete' '", Template.ref(wait_condition_handle), "'\n"
|
338
|
+
# rubocop:enable Metrics/LineLength
|
339
|
+
)
|
340
|
+
)
|
341
|
+
end
|
310
342
|
{
|
311
343
|
Type: 'AWS::EC2::Instance',
|
312
|
-
Metadata: {
|
313
|
-
Comment1: 'Create setup scripts',
|
314
|
-
'AWS::CloudFormation::Init' => {
|
315
|
-
config: {
|
316
|
-
files: files
|
317
|
-
}
|
318
|
-
}
|
319
|
-
},
|
320
344
|
Properties: {
|
321
345
|
IamInstanceProfile: Template.ref(instance_profile),
|
322
346
|
AvailabilityZone: Template.join(
|
@@ -326,7 +350,7 @@ class Formatron
|
|
326
350
|
ImageId: Template.find_in_map(
|
327
351
|
Template::REGION_MAP,
|
328
352
|
Template.ref('AWS::Region'),
|
329
|
-
|
353
|
+
os
|
330
354
|
),
|
331
355
|
SourceDestCheck: source_dest_check,
|
332
356
|
InstanceType: instance_type,
|
@@ -337,36 +361,13 @@ class Formatron
|
|
337
361
|
Key: 'Name',
|
338
362
|
Value: name
|
339
363
|
}],
|
340
|
-
UserData:
|
341
|
-
Template.join(
|
342
|
-
# rubocop:disable Metrics/LineLength
|
343
|
-
"#!/bin/bash -v\n",
|
344
|
-
"function error_exit\n",
|
345
|
-
"{\n",
|
346
|
-
" cfn-signal -e 1 -r \"$1\" '", Template.ref(wait_condition_handle), "'\n",
|
347
|
-
" exit 1\n",
|
348
|
-
"}\n",
|
349
|
-
"apt-get -y update\n",
|
350
|
-
"apt-get -y install python-setuptools\n",
|
351
|
-
"easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
|
352
|
-
"export PATH=$PATH:/opt/aws/bin\n",
|
353
|
-
'cfn-init --region ', Template.ref('AWS::Region'),
|
354
|
-
' -v -s ', Template.ref('AWS::StackName'), " -r #{logical_id} ",
|
355
|
-
" || error_exit 'Failed to run cfn-init'\n",
|
356
|
-
"for file in /tmp/formatron/script-*.sh; do\n",
|
357
|
-
" $file || error_exit \"failed to run Formatron setup script: $file\"\n",
|
358
|
-
"done\n",
|
359
|
-
"# If all went well, signal success\n",
|
360
|
-
"cfn-signal -e $? -r 'Formatron instance configuration complete' '", Template.ref(wait_condition_handle), "'\n"
|
361
|
-
# rubocop:enable Metrics/LineLength
|
362
|
-
)
|
363
|
-
)
|
364
|
+
UserData: user_data
|
364
365
|
}
|
365
366
|
}
|
366
367
|
end
|
367
|
-
# rubocop:enable Metrics/AbcSize
|
368
368
|
# rubocop:enable Metrics/ParameterLists
|
369
369
|
# rubocop:enable Metrics/MethodLength
|
370
|
+
# rubocop:enable Metrics/AbcSize
|
370
371
|
end
|
371
372
|
# rubocop:enable Metrics/ModuleLength
|
372
373
|
end
|