aws-cfn-dsl 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|