Class: AWSDSL::AMIBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/awsdsl/ami_builder.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stack) ⇒ AMIBuilder

Returns a new instance of AMIBuilder.



6
7
8
# File 'lib/awsdsl/ami_builder.rb', line 6

def initialize(stack)
  @stack = stack
end

Class Method Details

.build(stack) ⇒ Object



23
24
25
# File 'lib/awsdsl/ami_builder.rb', line 23

def self.build(stack)
  AMIBuilder.new(stack).build
end

.latest_amis(stack) ⇒ Object



27
28
29
# File 'lib/awsdsl/ami_builder.rb', line 27

def self.latest_amis(stack)
  AMIBuilder.new(stack).latest_amis
end

Instance Method Details

#ami_name(role) ⇒ Object



82
83
84
85
86
87
# File 'lib/awsdsl/ami_builder.rb', line 82

def ami_name(role)
  last = latest_ami(role)
  num = last.name.split('-').last.to_i + 1 if last
  num ||= 1
  "#{@stack.name}-#{role.name}-#{num}"
end

#base_ami(role) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/awsdsl/ami_builder.rb', line 74

def base_ami(role)
  base = role.base_ami || 'ubuntu'
  if BaseAMI::DISTROS.include?(base)
    base = BaseAMI.find(base)
  end
  base
end

#buildObject



10
11
12
13
14
# File 'lib/awsdsl/ami_builder.rb', line 10

def build
  @stack.roles.each do |role|
    build_ami(role)
  end
end

#build_ami(role) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/awsdsl/ami_builder.rb', line 31

def build_ami(role)
  output_ami = ami_name(role)
  # TODO(jpg): This needs to be better, also deep_merge
  json = (@stack.vars || {}).merge(role.vars || {})
  @builder = Gersberms::Gersberms.new base_ami: base_ami(role),
                                      ami_name: output_ami,
                                      json: json
  begin
    start_builder
    role.file_provisioners.each do |provisioner|
      @builder.options[:files] = provisioner
      @builder.upload_files
    end
    role.chef_provisioners.each do |provisioner|
      runlist = provisioner[:runlist]
      runlist = [runlist] unless runlist.is_a? Array
      @builder.options[:runlist] = runlist
      @builder.run_chef
    end
    shutdown_builder
    role.ami = @builder.image.id
  rescue => e
    @builder.destroy_instance
    @builder.destroy_keypair
    raise "Failed to build AMI for #{role.name}:\nError: #{e.message}\nBacktrace: #{e.backtrace.join("\n")}"
  end
end

#latest_ami(role) ⇒ Object



89
90
91
92
93
94
95
96
# File 'lib/awsdsl/ami_builder.rb', line 89

def latest_ami(role)
  ec2 = AWS::EC2.new
  amis = ec2.images.with_owner('self').select do |i|
    i.name.start_with?("#{@stack.name}-#{role.name}")
  end
  latest_num = amis.map { |i| i.name.split('-').last.to_i }.sort.last
  amis.select { |i| i.name == "#{@stack.name}-#{role.name}-#{latest_num}" }.first
end

#latest_amisObject



16
17
18
19
20
21
# File 'lib/awsdsl/ami_builder.rb', line 16

def latest_amis
  @stack.roles.each do |role|
    role.ami = latest_ami(role).id
  end
  @stack
end

#shutdown_builderObject



67
68
69
70
71
72
# File 'lib/awsdsl/ami_builder.rb', line 67

def shutdown_builder
  @builder.stop_instance
  @builder.create_ami
  @builder.destroy_instance
  @builder.destroy_keypair
end

#start_builderObject



59
60
61
62
63
64
65
# File 'lib/awsdsl/ami_builder.rb', line 59

def start_builder
  @builder.preflight
  @builder.create_keypair
  @builder.create_instance
  @builder.install_chef
  @builder.upload_cookbooks
end