builderator 1.2.3.pre.beta.1 → 1.3.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 +4 -4
- data/README.md +1 -1
- data/lib/builderator/config/file.rb +4 -0
- data/lib/builderator/interface/packer.rb +20 -0
- data/lib/builderator/patch/thor-actions.rb +6 -0
- data/lib/builderator/tasks/packer.rb +28 -26
- data/lib/builderator/tasks/version.rb +1 -1
- data/lib/builderator/util.rb +46 -0
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 710962f091dbc4e8bdb78702764f537c5205d7bb
|
4
|
+
data.tar.gz: fb314bfd5f1aa4b35bb2204cb6def699ccc5030f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 338681e36782e334d7e08bf6f463fafda8f186f11679b2d81dfdff03423a79d36094279b5987c28b270f16d1f18ec4276797bfd5368dd6c87e21fd824cef4070
|
7
|
+
data.tar.gz: 436d1936dccd2f2902aa8a2fbfe9ac564c07424df435314464575a082d4364d695c40c725e55b9c7b2c87c3a71de2bf84d3a89fc3de2fbaa8585a39630e58868
|
data/README.md
CHANGED
@@ -262,6 +262,10 @@ module Builderator
|
|
262
262
|
attribute :ami_users, :type => :list
|
263
263
|
attribute :ami_regions, :type => :list
|
264
264
|
|
265
|
+
# Tagging
|
266
|
+
attribute :run_tags, :type => :hash
|
267
|
+
attribute :run_volume_tags, :type => :hash
|
268
|
+
|
265
269
|
## Assumable role for tagging AMIs in remote accounts
|
266
270
|
attribute :tagging_role
|
267
271
|
end
|
@@ -15,6 +15,7 @@ module Builderator
|
|
15
15
|
class Packer < Interface
|
16
16
|
command 'packer'
|
17
17
|
attr_reader :packerfile
|
18
|
+
attr_reader :security_group_id
|
18
19
|
|
19
20
|
def initialize(*_)
|
20
21
|
super
|
@@ -60,6 +61,25 @@ module Builderator
|
|
60
61
|
# This is not directly supported by Packer
|
61
62
|
build_hash.delete(:tagging_role)
|
62
63
|
|
64
|
+
# Use a security group that doesn't suck if user didn't specify.
|
65
|
+
# Note that @security_group_id in this class will only ever be the one created here,
|
66
|
+
# and will be nil if the user specified their own
|
67
|
+
if build_hash.key?(:security_group_ids)
|
68
|
+
puts "Using SecurityGroups #{build_hash[:security_group_ids]}"
|
69
|
+
elsif build_hash.key?(:security_group_id)
|
70
|
+
puts "Using SecurityGroup #{build_hash[:security_group_id]}"
|
71
|
+
else
|
72
|
+
@security_group_id = Util.get_security_group_id(build_hash[:region])
|
73
|
+
build_hash[:security_group_id] = @security_group_id
|
74
|
+
|
75
|
+
# Delete the security group created above when on builderator exit.
|
76
|
+
# Note that for an unclean exit in which the instance was NOT terminated,
|
77
|
+
# Amazon will refuse to delete the security group, as it is still attached
|
78
|
+
# to an existing instance. This is unfortunate, but is equivalent to packer's
|
79
|
+
# default behavior except that now you'll get an exception from aws-sdk.
|
80
|
+
at_exit { Util.remove_security_group(build_hash[:region], @security_group_id) }
|
81
|
+
end
|
82
|
+
|
63
83
|
json[:builders] << build_hash
|
64
84
|
end
|
65
85
|
|
@@ -82,6 +82,12 @@ class Thor
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
alias_method :thor_run, :run
|
86
|
+
def run(command, config = {})
|
87
|
+
thor_run(command, config)
|
88
|
+
fail "Command failed: #{command}" if $?.exitstatus != 0
|
89
|
+
end
|
90
|
+
|
85
91
|
##
|
86
92
|
# Make `template` load from a sane path and render in the context of Config
|
87
93
|
##
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'aws-sdk'
|
2
2
|
require 'thor'
|
3
|
+
require 'retryable'
|
3
4
|
|
4
5
|
require_relative '../control/data'
|
5
6
|
require_relative '../interface/packer'
|
@@ -47,7 +48,7 @@ module Builderator
|
|
47
48
|
|
48
49
|
build.ami_regions.each do |region|
|
49
50
|
say_status :copy, "image #{image_name} (#{image.image_id}) from #{Config.aws.region} to #{region}"
|
50
|
-
|
51
|
+
copy_image(region, parameters)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
@@ -61,11 +62,6 @@ module Builderator
|
|
61
62
|
invoke :configure, [profile], options
|
62
63
|
|
63
64
|
images.each do |image_name, (image, build)|
|
64
|
-
filters = [{
|
65
|
-
:name => 'name',
|
66
|
-
:values => [image_name]
|
67
|
-
}]
|
68
|
-
|
69
65
|
## Add some additional tags about the regional source
|
70
66
|
image.tags << {
|
71
67
|
:key => 'source_region',
|
@@ -77,7 +73,7 @@ module Builderator
|
|
77
73
|
}
|
78
74
|
|
79
75
|
build.ami_regions.each do |region|
|
80
|
-
regional_image =
|
76
|
+
regional_image = find_image(region, image_name)
|
81
77
|
|
82
78
|
say_status :tag, "AMI #{image_name} (#{regional_image.image_id}) in #{region}"
|
83
79
|
Util.ec2(region).create_tags(:resources => [regional_image.image_id], :tags => image.tags)
|
@@ -99,13 +95,8 @@ module Builderator
|
|
99
95
|
waiting = false
|
100
96
|
|
101
97
|
images.each do |image_name, (image, build)|
|
102
|
-
filters = [{
|
103
|
-
:name => 'name',
|
104
|
-
:values => [image_name]
|
105
|
-
}]
|
106
|
-
|
107
98
|
build.ami_regions.each do |region|
|
108
|
-
regional_image =
|
99
|
+
regional_image = find_image(region, image_name)
|
109
100
|
|
110
101
|
## It takes a few seconds for the new AMI to show up in the `describe_images` response-set
|
111
102
|
state = regional_image.nil? ? 'unknown' : regional_image.state
|
@@ -123,7 +114,7 @@ module Builderator
|
|
123
114
|
end
|
124
115
|
|
125
116
|
## If waiting == false, loop immediately to break
|
126
|
-
sleep(
|
117
|
+
sleep(20) if waiting
|
127
118
|
end
|
128
119
|
|
129
120
|
say_status :complete, 'All copied images are available'
|
@@ -143,17 +134,12 @@ module Builderator
|
|
143
134
|
|
144
135
|
sts_client = Aws::STS::Client.new(region: region)
|
145
136
|
|
146
|
-
filters = [{
|
147
|
-
:name => 'name',
|
148
|
-
:values => [image_name]
|
149
|
-
}]
|
150
|
-
|
151
137
|
if build.tagging_role.nil?
|
152
138
|
say_status :complete, 'No remote tagging to be performed as no IAM role is defined'
|
153
139
|
return
|
154
140
|
end
|
155
141
|
|
156
|
-
regional_image =
|
142
|
+
regional_image = find_image(region, image_name)
|
157
143
|
|
158
144
|
build.ami_users.each do |account|
|
159
145
|
role_arn = "arn:aws:iam::#{account}:role/#{build.tagging_role}"
|
@@ -187,12 +173,7 @@ module Builderator
|
|
187
173
|
build.ami_users.each do |user|
|
188
174
|
shared = true
|
189
175
|
|
190
|
-
|
191
|
-
:name => 'name',
|
192
|
-
:values => [image_name]
|
193
|
-
}]
|
194
|
-
|
195
|
-
regional_image = Util.ec2(region).describe_images(:filters => filters).images.first
|
176
|
+
regional_image = find_image(region, image_name)
|
196
177
|
|
197
178
|
say_status :share, "image #{image_name} (#{regional_image.image_id}) with #{user}"
|
198
179
|
|
@@ -222,6 +203,27 @@ module Builderator
|
|
222
203
|
memo[build.ami_name] = [Control::Data.lookup(:image, :name => build.ami_name).first, build]
|
223
204
|
end
|
224
205
|
end
|
206
|
+
|
207
|
+
def copy_image(region, params)
|
208
|
+
Retryable.retryable(:sleep => lambda { |n| 4**n }, :tries => 4, :on => [Aws::EC2::Errors::ServiceError]) do |retries, _|
|
209
|
+
say_status :error, 'Error copying image', :red if retries.positive?
|
210
|
+
Util.ec2(region).copy_image(params)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def find_image(region, image_name)
|
215
|
+
filters = [{
|
216
|
+
:name => 'name',
|
217
|
+
:values => [image_name]
|
218
|
+
}]
|
219
|
+
|
220
|
+
image = nil
|
221
|
+
Retryable.retryable(:sleep => lambda { |n| 4**n }, :tries => 4, :on => [Aws::EC2::Errors::ServiceError]) do |retries, _|
|
222
|
+
say_status :error, 'Error finding image', :red if retries.positive?
|
223
|
+
image = Util.ec2(region).describe_images(:filters => filters).images.first
|
224
|
+
end
|
225
|
+
image
|
226
|
+
end
|
225
227
|
end
|
226
228
|
end
|
227
229
|
end
|
@@ -19,7 +19,7 @@ module Builderator
|
|
19
19
|
desc 'current', 'Print the current version and write it to file'
|
20
20
|
def current
|
21
21
|
unless Config.autoversion.search_tags
|
22
|
-
say_status :disabled, 'Automatically detecting version
|
22
|
+
say_status :disabled, 'Automatically detecting version information '\
|
23
23
|
'from SCM tags is disabled', :red
|
24
24
|
return
|
25
25
|
end
|
data/lib/builderator/util.rb
CHANGED
@@ -79,6 +79,52 @@ module Builderator
|
|
79
79
|
clients["asg-#{region}"] ||= Aws::AutoScaling::Client.new(:region => region)
|
80
80
|
end
|
81
81
|
|
82
|
+
def remove_security_group(region = Config.aws.region, group_id = nil)
|
83
|
+
if region.nil?
|
84
|
+
puts "Dry-run; skipping delete of group_id #{group_id}"
|
85
|
+
return
|
86
|
+
end
|
87
|
+
if group_id.nil?
|
88
|
+
puts "Not removing security group"
|
89
|
+
return
|
90
|
+
end
|
91
|
+
ec2 = ec2(region)
|
92
|
+
resp = ec2.delete_security_group(group_id: group_id)
|
93
|
+
puts "Deleted SecurityGroup #{group_id}"
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_security_group_id(region = Config.aws.region)
|
97
|
+
group_id = nil
|
98
|
+
if region.nil?
|
99
|
+
group_id = 'sg-DRYRUNSG'
|
100
|
+
puts "Dry-run; skipping create and returning #{group_id}"
|
101
|
+
return group_id
|
102
|
+
end
|
103
|
+
ec2 = ec2(region)
|
104
|
+
group = nil
|
105
|
+
require 'open-uri'
|
106
|
+
external_ip = open('http://checkip.amazonaws.com').read.strip
|
107
|
+
cidr_ip = external_ip + '/32'
|
108
|
+
|
109
|
+
# Create a security group
|
110
|
+
resp = ec2.create_security_group(group_name: "BuilderatorSecurityGroupSSHOnly-#{Time.now.to_i}",
|
111
|
+
description: "Created by Builderator at #{Time.now}")
|
112
|
+
group_id = resp[:group_id]
|
113
|
+
|
114
|
+
resp = ec2.describe_security_groups(group_ids: [group_id])
|
115
|
+
groups = resp[:security_groups]
|
116
|
+
group = groups.first
|
117
|
+
|
118
|
+
# Ensure the group_id has the right permissions
|
119
|
+
resp = ec2.authorize_security_group_ingress(group_id: group_id,
|
120
|
+
ip_protocol: 'tcp',
|
121
|
+
from_port: 22,
|
122
|
+
to_port: 22,
|
123
|
+
cidr_ip: cidr_ip)
|
124
|
+
puts "Created SecurityGroup #{group_id}"
|
125
|
+
group_id
|
126
|
+
end
|
127
|
+
|
82
128
|
private
|
83
129
|
|
84
130
|
def clients
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: builderator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Manero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -178,6 +178,20 @@ dependencies:
|
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: 0.19.0
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: retryable
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 2.0.4
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 2.0.4
|
181
195
|
description: Builderator automates many of the common steps required to build VMs
|
182
196
|
and images with Chef. It provides a common configuration layer for Chef, Berkshelf,
|
183
197
|
Vagrant, and Packer, and tasks to orchestrate the usage of each. https://github.com/rapid7/builderator
|
@@ -260,9 +274,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
260
274
|
version: '0'
|
261
275
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
262
276
|
requirements:
|
263
|
-
- - "
|
277
|
+
- - ">="
|
264
278
|
- !ruby/object:Gem::Version
|
265
|
-
version:
|
279
|
+
version: '0'
|
266
280
|
requirements: []
|
267
281
|
rubyforge_project:
|
268
282
|
rubygems_version: 2.5.2
|