aws-cfn-dsl 0.0.4 → 0.1.0
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 +5 -13
- data/Gemfile +7 -0
- data/aws-cfn-dsl.gemspec +4 -6
- data/aws-cfn-dsl.iml +9 -15
- data/bin/cfn-dsl +31 -0
- data/lib/aws/cfn/dsl.rb +6 -8
- data/lib/aws/cfn/dsl/base.rb +355 -0
- data/lib/aws/cfn/dsl/fncall.rb +21 -0
- data/lib/aws/cfn/dsl/main.rb +30 -0
- data/lib/aws/cfn/dsl/template.rb +242 -0
- data/lib/aws/cfn/dsl/version.rb +1 -1
- data/test/Mappings/AWSRegion2AMI.rb +10 -0
- data/test/Outputs/ChefSecurityGroup.rb +4 -0
- data/test/Outputs/ServerURL.rb +13 -0
- data/test/Outputs/ValidationKeyBucket.rb +4 -0
- data/test/Parameters/CookbookLocation.rb +5 -0
- data/test/Parameters/InstanceType.rb +7 -0
- data/test/Parameters/KeyName.rb +8 -0
- data/test/Parameters/RoleLocation.rb +5 -0
- data/test/Parameters/SSHLocation.rb +9 -0
- data/test/Resources/BucketPolicy.rb +28 -0
- data/test/Resources/ChefClientSecurityGroup.rb +2 -0
- data/test/Resources/ChefServer.rb +57 -0
- data/test/Resources/ChefServerSecurityGroup.rb +19 -0
- data/test/Resources/ChefServerUser.rb +18 -0
- data/test/Resources/ChefServerWaitCondition.rb +5 -0
- data/test/Resources/ChefServerWaitHandle.rb +2 -0
- data/test/Resources/HostKeys.rb +4 -0
- data/test/Resources/PrivateKeyBucket.rb +2 -0
- data/test/chef-server.json +392 -0
- data/test/chef-server.rb +40 -0
- metadata +67 -49
@@ -0,0 +1,21 @@
|
|
1
|
+
require "aws/cfn/decompiler"
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Cfn
|
5
|
+
module Dsl
|
6
|
+
class FnCall
|
7
|
+
attr_reader :name, :arguments, :multiline
|
8
|
+
|
9
|
+
def initialize(name, arguments, multiline = false)
|
10
|
+
@name = name
|
11
|
+
@arguments = arguments
|
12
|
+
@multiline = multiline
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s()
|
16
|
+
@name + "(" + @arguments.join(', ') + ")"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'slop'
|
2
|
+
require "aws/cfn/dsl/base"
|
3
|
+
|
4
|
+
module Aws
|
5
|
+
module Cfn
|
6
|
+
module Dsl
|
7
|
+
class Main < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
|
11
|
+
@opts = Slop.parse(help: true) do
|
12
|
+
on :j, :template=, 'The template to convert', as: String
|
13
|
+
on :o, :output=, 'The directory to output the DSL to.', as: String
|
14
|
+
end
|
15
|
+
|
16
|
+
unless @opts[:template]
|
17
|
+
puts @opts
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
|
21
|
+
load @opts[:template]
|
22
|
+
|
23
|
+
pprint(simplify(@items))
|
24
|
+
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'cloudformation-ruby-dsl/cfntemplate'
|
3
|
+
require 'cloudformation-ruby-dsl/table'
|
4
|
+
#require 'cloudformation-ruby-dsl/spotprice'
|
5
|
+
require 'slop'
|
6
|
+
|
7
|
+
module Aws
|
8
|
+
module Cfn
|
9
|
+
module Dsl
|
10
|
+
class Template < ::TemplateDSL
|
11
|
+
|
12
|
+
def initialize(&block)
|
13
|
+
@path = File.dirname(caller[2].split(%r'\s+').shift.split(':')[0])
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def file(b)
|
18
|
+
block = File.read File.join(@path,b)
|
19
|
+
eval block
|
20
|
+
end
|
21
|
+
|
22
|
+
def mapping(name, options=nil)
|
23
|
+
if options.nil?
|
24
|
+
file "Mappings/#{name}.rb"
|
25
|
+
else
|
26
|
+
super(name,options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# def mapping_file(p)
|
31
|
+
# file "Mappings/#{p}.rb"
|
32
|
+
# end
|
33
|
+
|
34
|
+
def parameter(name, options=nil)
|
35
|
+
if options.nil?
|
36
|
+
file "Parameters/#{name}.rb"
|
37
|
+
else
|
38
|
+
super(name,options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# def parameter_file(p)
|
43
|
+
# file "Parameters/#{p}.rb"
|
44
|
+
# end
|
45
|
+
|
46
|
+
def resource(name, options=nil)
|
47
|
+
if options.nil?
|
48
|
+
file "Resources/#{name}.rb"
|
49
|
+
else
|
50
|
+
super(name,options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# def resource_file(p)
|
55
|
+
# file "Resources/#{p}.rb"
|
56
|
+
# end
|
57
|
+
|
58
|
+
def output(name, options=nil)
|
59
|
+
if options.nil?
|
60
|
+
file "Outputs/#{name}.rb"
|
61
|
+
else
|
62
|
+
super(name,options)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# def output_file(p)
|
67
|
+
# file "Outputs/#{p}.rb"
|
68
|
+
# end
|
69
|
+
|
70
|
+
def exec!(argv=ARGV)
|
71
|
+
@opts = Slop.parse(help: true) do
|
72
|
+
banner "usage: #{$PROGRAM_NAME} <expand|diff|validate|create|update|delete>"
|
73
|
+
on :o, :output=, 'The template file to save this DSL expansion to', as: String
|
74
|
+
end
|
75
|
+
|
76
|
+
action = argv[0] || 'expand'
|
77
|
+
unless %w(expand diff validate create update delete).include? action
|
78
|
+
$stderr.puts "usage: #{$PROGRAM_NAME} <expand|diff|validate|create|update|delete>"
|
79
|
+
exit(2)
|
80
|
+
end
|
81
|
+
unless (argv & %w(--template-file --template-url)).empty?
|
82
|
+
$stderr.puts "#{File.basename($PROGRAM_NAME)}: The --template-file and --template-url command-line options are not allowed. (You are running the template itself right now ... !)"
|
83
|
+
exit(2)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Find parameters where extension attribute :Immutable is true then remove it from the
|
87
|
+
# cfn template since we can't pass it to CloudFormation.
|
88
|
+
immutable_parameters = excise_parameter_attribute!(:Immutable)
|
89
|
+
|
90
|
+
# Tag CloudFormation stacks based on :Tags defined in the template
|
91
|
+
cfn_tags = excise_tags!
|
92
|
+
# The command line string looks like: --tag "Key=key; Value=value" --tag "Key2=key2; Value2=value"
|
93
|
+
cfn_tags_options = cfn_tags.sort.map { |tag| ["--tag", "Key=%s; Value=%s" % tag.split('=')] }.flatten
|
94
|
+
|
95
|
+
# example: <template.rb> cfn-create-stack my-stack-name --parameters "Env=prod" --region eu-west-1
|
96
|
+
# Execute the AWS CLI cfn-cmd command to validate/create/update a CloudFormation stack.
|
97
|
+
if action == 'diff' or (action == 'expand' and not nopretty)
|
98
|
+
template_string = JSON.pretty_generate(self)
|
99
|
+
else
|
100
|
+
template_string = JSON.generate(self)
|
101
|
+
end
|
102
|
+
|
103
|
+
if action == 'expand'
|
104
|
+
# Write the pretty-printed JSON template to stdout and exit. [--nopretty] option writes output with minimal whitespace
|
105
|
+
# example: <template.rb> expand --parameters "Env=prod" --region eu-west-1 --nopretty
|
106
|
+
if @opts[:output]
|
107
|
+
dest = @opts[:output]
|
108
|
+
if File.directory? dest
|
109
|
+
file = File.basename $PROGRAM_NAME
|
110
|
+
file.gsub!(%r'\.rb', '.json')
|
111
|
+
dest = File.join dest, file
|
112
|
+
end
|
113
|
+
IO.write(dest, template_string)
|
114
|
+
else
|
115
|
+
puts template_string
|
116
|
+
end
|
117
|
+
exit(true)
|
118
|
+
end
|
119
|
+
|
120
|
+
temp_file = File.absolute_path("#{$PROGRAM_NAME}.expanded.json")
|
121
|
+
File.write(temp_file, template_string)
|
122
|
+
|
123
|
+
cmdline = ['cfn-cmd'] + argv + ['--template-file', temp_file] + cfn_tags_options
|
124
|
+
|
125
|
+
case action
|
126
|
+
when 'diff'
|
127
|
+
# example: <template.rb> diff my-stack-name --parameters "Env=prod" --region eu-west-1
|
128
|
+
# Diff the current template for an existing stack with the expansion of this template.
|
129
|
+
|
130
|
+
# The --parameters and --tag options were used to expand the template but we don't need them anymore. Discard.
|
131
|
+
_, cfn_options = extract_options(argv[1..-1], %w(), %w(--parameters --tag))
|
132
|
+
|
133
|
+
# Separate the remaining command-line options into options for 'cfn-cmd' and options for 'diff'.
|
134
|
+
cfn_options, diff_options = extract_options(cfn_options, %w(),
|
135
|
+
%w(--stack-name --region --parameters --connection-timeout -I --access-key-id -S --secret-key -K --ec2-private-key-file-path -U --url))
|
136
|
+
|
137
|
+
# If the first argument is a stack name then shift it from diff_options over to cfn_options.
|
138
|
+
if diff_options[0] && !(/^-/ =~ diff_options[0])
|
139
|
+
cfn_options.unshift(diff_options.shift)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Run CloudFormation commands to describe the existing stack
|
143
|
+
cfn_options_string = cfn_options.map { |arg| "'#{arg}'" }.join(' ')
|
144
|
+
old_template_raw = exec_capture_stdout("cfn-cmd cfn-get-template #{cfn_options_string}")
|
145
|
+
# ec2 template output is not valid json: TEMPLATE "<json>\n"\n
|
146
|
+
old_template_object = JSON.parse(old_template_raw[11..-3])
|
147
|
+
old_template_string = JSON.pretty_generate(old_template_object)
|
148
|
+
old_stack_attributes = exec_describe_stack(cfn_options_string)
|
149
|
+
old_tags_string = old_stack_attributes["TAGS"]
|
150
|
+
old_parameters_string = old_stack_attributes["PARAMETERS"]
|
151
|
+
|
152
|
+
# Sort the tag strings alphabetically to make them easily comparable
|
153
|
+
old_tags_string = (old_tags_string || '').split(';').sort.map { |tag| %Q(TAG "#{tag}"\n) }.join
|
154
|
+
tags_string = cfn_tags.sort.map { |tag| "TAG \"#{tag}\"\n" }.join
|
155
|
+
|
156
|
+
# Sort the parameter strings alphabetically to make them easily comparable
|
157
|
+
old_parameters_string = (old_parameters_string || '').split(';').sort.map { |param| %Q(PARAMETER "#{param}"\n) }.join
|
158
|
+
parameters_string = parameters.sort.map { |key, value| "PARAMETER \"#{key}=#{value}\"\n" }.join
|
159
|
+
|
160
|
+
# Diff the expanded template with the template from CloudFormation.
|
161
|
+
old_temp_file = File.absolute_path("#{$PROGRAM_NAME}.current.json")
|
162
|
+
new_temp_file = File.absolute_path("#{$PROGRAM_NAME}.expanded.json")
|
163
|
+
File.write(old_temp_file, old_tags_string + old_parameters_string + old_template_string)
|
164
|
+
File.write(new_temp_file, tags_string + parameters_string + template_string)
|
165
|
+
|
166
|
+
# Compare templates
|
167
|
+
system(*["diff"] + diff_options + [old_temp_file, new_temp_file])
|
168
|
+
|
169
|
+
File.delete(old_temp_file)
|
170
|
+
File.delete(new_temp_file)
|
171
|
+
|
172
|
+
exit(true)
|
173
|
+
|
174
|
+
when 'cfn-validate-template'
|
175
|
+
# The cfn-validate-template command doesn't support --parameters so remove it if it was provided for template expansion.
|
176
|
+
_, cmdline = extract_options(cmdline, %w(), %w(--parameters --tag))
|
177
|
+
|
178
|
+
when 'cfn-update-stack'
|
179
|
+
# Pick out the subset of cfn-update-stack options that apply to cfn-describe-stacks.
|
180
|
+
cfn_options, other_options = extract_options(argv[1..-1], %w(),
|
181
|
+
%w(--stack-name --region --connection-timeout -I --access-key-id -S --secret-key -K --ec2-private-key-file-path -U --url))
|
182
|
+
|
183
|
+
# If the first argument is a stack name then shift it over to cfn_options.
|
184
|
+
if other_options[0] && !(/^-/ =~ other_options[0])
|
185
|
+
cfn_options.unshift(other_options.shift)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Run CloudFormation command to describe the existing stack
|
189
|
+
cfn_options_string = cfn_options.map { |arg| "'#{arg}'" }.join(' ')
|
190
|
+
old_stack_attributes = exec_describe_stack(cfn_options_string)
|
191
|
+
|
192
|
+
# If updating a stack and some parameters are marked as immutable, fail if the new parameters don't match the old ones.
|
193
|
+
if not immutable_parameters.empty?
|
194
|
+
old_parameters_string = old_stack_attributes["PARAMETERS"]
|
195
|
+
old_parameters = Hash[(old_parameters_string || '').split(';').map { |pair| pair.split('=', 2) }]
|
196
|
+
new_parameters = parameters
|
197
|
+
|
198
|
+
immutable_parameters.sort.each do |param|
|
199
|
+
if old_parameters[param].to_s != new_parameters[param].to_s
|
200
|
+
$stderr.puts "Error: cfn-update-stack may not update immutable parameter " +
|
201
|
+
"'#{param}=#{old_parameters[param]}' to '#{param}=#{new_parameters[param]}'."
|
202
|
+
exit(false)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
# Tags are immutable in CloudFormation. The cfn-update-stack command doesn't support --tag options, so remove
|
208
|
+
# the argument (if it exists) and validate against the existing stack to ensure tags haven't changed.
|
209
|
+
# Compare the sorted arrays for an exact match
|
210
|
+
old_cfn_tags = old_stack_attributes['TAGS'].split(';').sort rescue [] # Use empty Array if .split fails
|
211
|
+
if cfn_tags != old_cfn_tags
|
212
|
+
$stderr.puts "CloudFormation stack tags do not match and cannot be updated. You must either use the same tags or create a new stack." +
|
213
|
+
"\n" + (old_cfn_tags - cfn_tags).map {|tag| "< #{tag}" }.join("\n") +
|
214
|
+
"\n" + "---" +
|
215
|
+
"\n" + (cfn_tags - old_cfn_tags).map {|tag| "> #{tag}"}.join("\n")
|
216
|
+
exit(false)
|
217
|
+
end
|
218
|
+
_, cmdline = extract_options(cmdline, %w(), %w(--tag))
|
219
|
+
end
|
220
|
+
|
221
|
+
# Execute command cmdline
|
222
|
+
unless system(*cmdline)
|
223
|
+
$stderr.puts "\nExecution of 'cfn-cmd' failed. To facilitate debugging, the generated JSON template " +
|
224
|
+
"file was not deleted. You may delete the file manually if it isn't needed: #{temp_file}"
|
225
|
+
exit(false)
|
226
|
+
end
|
227
|
+
|
228
|
+
File.delete(temp_file)
|
229
|
+
|
230
|
+
exit(true)
|
231
|
+
end
|
232
|
+
|
233
|
+
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Main entry point
|
240
|
+
def template(&block)
|
241
|
+
Aws::Cfn::Dsl::Template.new(&block)
|
242
|
+
end
|
data/lib/aws/cfn/dsl/version.rb
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
mapping 'AWSRegion2AMI',
|
2
|
+
:'us-east-1' => { :id => 'ami-83dee0ea' },
|
3
|
+
:'us-west-1' => { :id => 'ami-c45f6281' },
|
4
|
+
:'us-west-2' => { :id => 'ami-d0d8b8e0' },
|
5
|
+
:'eu-west-1' => { :id => 'ami-aa56a1dd' },
|
6
|
+
:'sa-east-1' => { :id => 'ami-d55bfbc8' },
|
7
|
+
:'ap-southeast-1' => { :id => 'ami-bc7325ee' },
|
8
|
+
:'ap-southeast-2' => { :id => 'ami-e577e9df' },
|
9
|
+
:'ap-northeast-1' => { :id => 'ami-f72e45f6' }
|
10
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
parameter 'InstanceType',
|
2
|
+
:Description => 'WebServer EC2 instance type',
|
3
|
+
:Type => 'String',
|
4
|
+
:Default => 'm1.small',
|
5
|
+
:AllowedValues => %w(t1.micro m1.small m1.medium m1.large m1.xlarge m2.xlarge m2.2xlarge m2.4xlarge m3.xlarge m3.2xlarge c1.medium c1.xlarge cc1.4xlarge cc2.8xlarge cg1.4xlarge),
|
6
|
+
:ConstraintDescription => 'must be a valid EC2 instance type.'
|
7
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
parameter 'KeyName',
|
2
|
+
:Description => 'Name of an existing EC2 KeyPair to enable SSH access to the web server',
|
3
|
+
:Type => 'String',
|
4
|
+
:MinLength => '1',
|
5
|
+
:MaxLength => '255',
|
6
|
+
:AllowedPattern => '[\\x20-\\x7E]*',
|
7
|
+
:ConstraintDescription => 'can contain only ASCII characters.'
|
8
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
parameter 'SSHLocation',
|
2
|
+
:Description => 'The IP address range that can be used to SSH to the EC2 instances',
|
3
|
+
:Type => 'String',
|
4
|
+
:MinLength => '9',
|
5
|
+
:MaxLength => '18',
|
6
|
+
:Default => '0.0.0.0/0',
|
7
|
+
:AllowedPattern => '(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})',
|
8
|
+
:ConstraintDescription => 'must be a valid IP CIDR range of the form x.x.x.x/x.'
|
9
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
resource 'BucketPolicy', :Type => 'AWS::S3::BucketPolicy', :Properties => {
|
2
|
+
:PolicyDocument => {
|
3
|
+
:Version => '2008-10-17',
|
4
|
+
:Id => 'WritePolicy',
|
5
|
+
:Statement => [
|
6
|
+
{
|
7
|
+
:Sid => 'WriteAccess',
|
8
|
+
:Action => [ 's3:PutObject' ],
|
9
|
+
:Effect => 'Allow',
|
10
|
+
:Resource => {
|
11
|
+
:'Fn::Join' => [
|
12
|
+
'',
|
13
|
+
[
|
14
|
+
'arn:aws:s3:::',
|
15
|
+
{ :Ref => 'PrivateKeyBucket' },
|
16
|
+
'/*',
|
17
|
+
],
|
18
|
+
],
|
19
|
+
},
|
20
|
+
:Principal => {
|
21
|
+
:AWS => { :'Fn::GetAtt' => [ 'ChefServerUser', 'Arn' ] },
|
22
|
+
},
|
23
|
+
},
|
24
|
+
],
|
25
|
+
},
|
26
|
+
:Bucket => { :Ref => 'PrivateKeyBucket' },
|
27
|
+
}
|
28
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
resource 'ChefServer', :Type => 'AWS::EC2::Instance', :Metadata => { :'AWS::CloudFormation::Init' => { :config => { :packages => { :apt => { :s3cmd => [] } }, :sources => { :'/home/ubuntu/chef-repo' => 'https://github.com/opscode/chef-repo/tarball/master', :'/home/ubuntu/chef-repo/cookbooks' => { :Ref => 'CookbookLocation' }, :'/home/ubuntu/chef-repo/roles' => { :Ref => 'RoleLocation' } }, :files => { :'/home/ubuntu/setup_environment' => { :source => 'https://s3.amazonaws.com/cloudformation-examples/setup-chef-server-with-knife', :mode => '000755', :owner => 'ubuntu', :group => 'ubuntu' }, :'/home/ubuntu/.s3cfg' => { :content => { :'Fn::Join' => [ '', [ "[default]\n", 'access_key = ', { :Ref => 'HostKeys' }, "\n", 'secret_key = ', { :'Fn::GetAtt' => [ 'HostKeys', 'SecretAccessKey' ] }, "\n", "use_https = True\n" ] ] }, :mode => '000644', :owner => 'ubuntu', :group => 'ubuntu' }, :'/home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb' => { :source => 'https://s3.amazonaws.com/cloudformation-examples/chef_11.10.0-1.ubuntu.12.04_amd64.deb', :mode => '000664', :owner => 'ubuntu', :group => 'ubuntu' }, :'/home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb' => { :source => 'https://s3.amazonaws.com/cloudformation-examples/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb', :mode => '000664', :owner => 'ubuntu', :group => 'ubuntu' } } } } }, :Properties => {
|
2
|
+
:SecurityGroups => [
|
3
|
+
{ :Ref => 'ChefServerSecurityGroup' },
|
4
|
+
],
|
5
|
+
:ImageId => {
|
6
|
+
:'Fn::FindInMap' => [
|
7
|
+
'AWSRegion2AMI',
|
8
|
+
{ :Ref => 'AWS::Region' },
|
9
|
+
'id',
|
10
|
+
],
|
11
|
+
},
|
12
|
+
:UserData => {
|
13
|
+
:'Fn::Base64' => {
|
14
|
+
:'Fn::Join' => [
|
15
|
+
'',
|
16
|
+
[
|
17
|
+
"#!/bin/bash\n",
|
18
|
+
"function error_exit\n",
|
19
|
+
"{\n",
|
20
|
+
' cfn-signal -e 1 -r "$1" \'',
|
21
|
+
{ :Ref => 'ChefServerWaitHandle' },
|
22
|
+
"'\n",
|
23
|
+
" exit 1\n",
|
24
|
+
"}\n",
|
25
|
+
"apt-get -y install python-setuptools\n",
|
26
|
+
"easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
|
27
|
+
'cfn-init --region ',
|
28
|
+
{ :Ref => 'AWS::Region' },
|
29
|
+
' -s ',
|
30
|
+
{ :Ref => 'AWS::StackId' },
|
31
|
+
' -r ChefServer ',
|
32
|
+
"|| error_exit 'Failed to run cfn-init'\n",
|
33
|
+
"# Bootstrap chef\n",
|
34
|
+
"dpkg -i /home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb > /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef client tools'\n",
|
35
|
+
"dpkg -i /home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb >> /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef server'\n",
|
36
|
+
"sleep 5\n",
|
37
|
+
"sudo /usr/bin/chef-server-ctl reconfigure > /tmp/chef_configure.log 2>&1 || error_exit 'Failed to configure chef server'\n",
|
38
|
+
"sleep 5\n",
|
39
|
+
"sudo chef-server-ctl start\n",
|
40
|
+
"# Setup development environment in ubuntu user\n",
|
41
|
+
"sudo -u ubuntu /home/ubuntu/setup_environment > /tmp/setup_environment.log 2>&1 || error_exit 'Failed to bootstrap chef server'\n",
|
42
|
+
"# copy validation key to S3 bucket\n",
|
43
|
+
's3cmd -c /home/ubuntu/.s3cfg put /etc/chef-server/validation.pem s3://',
|
44
|
+
{ :Ref => 'PrivateKeyBucket' },
|
45
|
+
"/validation.pem > /tmp/put_validation_key.log 2>&1 || error_exit 'Failed to put Chef Server validation key'\n",
|
46
|
+
"# If all went well, signal success\n",
|
47
|
+
'cfn-signal -e $? -r \'Chef Server configuration\' \'',
|
48
|
+
{ :Ref => 'ChefServerWaitHandle' },
|
49
|
+
"'\n",
|
50
|
+
],
|
51
|
+
],
|
52
|
+
},
|
53
|
+
},
|
54
|
+
:KeyName => { :Ref => 'KeyName' },
|
55
|
+
:InstanceType => { :Ref => 'InstanceType' },
|
56
|
+
}
|
57
|
+
|