Class: MinimalPipeline::Ec2

Inherits:
Object
  • Object
show all
Defined in:
lib/minimal_pipeline/ec2.rb

Overview

# For Account 1: ec2 = MinimalPipeline::Ec2.new block_device_mappings = ec2.prepare_snapshots_for_account(‘ami-id’,

'account-id')

# Promote AMI via SQS sqs = MinimalPipeline::Sqs.new sqs.send_message(‘queue-name’, block_device_mappings.to_json)

# For Account 2, after getting block_device_mappings ec2 = MinimalPipeline::Ec2.new new_mappings = ec2.copy_snapshots_in_new_account(block_device_mappings) ec2.register_ami(new_mappings, ‘ami-name’)

Instance Method Summary collapse

Constructor Details

#initializeEc2

Initializes a ‘Ec2` client Requires environment variables `AWS_REGION` or `region` to be set. Also requires `keystore_table` and `keystore_kms_id`



21
22
23
24
25
26
27
28
29
30
# File 'lib/minimal_pipeline/ec2.rb', line 21

def initialize
  raise 'You must set env variable AWS_REGION or region.' \
    if ENV['AWS_REGION'].nil? && ENV['region'].nil?
  raise 'You must set env variable keystore_kms_id.' \
    if ENV['inventory_store_key'].nil? && ENV['keystore_kms_id'].nil?

  @region = ENV['AWS_REGION'] || ENV['region']
  @kms_key_id = ENV['keystore_kms_id'] || ENV['inventory_store_key']
  @client = Aws::EC2::Client.new(region: 'us-east-1')
end

Instance Method Details

#copy_snapshot(snapshot_id, encrypted = true) ⇒ String

Create a copy of an existing snapshot

Parameters:

  • snapshot_id (String)

    The ID of the snapshot to copy

  • encrypted (Boolean) (defaults to: true)

    Whether or not the volume is encrypted

Returns:

  • (String)

    The ID of the newly created snapshot



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/minimal_pipeline/ec2.rb', line 48

def copy_snapshot(snapshot_id, encrypted = true)
  new_snapshot_id = @client.copy_snapshot(
    encrypted: encrypted,
    kms_key_id: @kms_key_id,
    source_region: @region,
    source_snapshot_id: snapshot_id
  ).snapshot_id

  puts "new snapshot ID: #{new_snapshot_id}"
  wait_for_snapshot(new_snapshot_id)

  new_snapshot_id
end

#copy_snapshots_in_new_account(block_device_mappings) ⇒ Array

Copy the snapshots from the original account into the new one

Returns:

  • (Array)

    Block device mappings with updated snapshot ids



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/minimal_pipeline/ec2.rb', line 122

def (block_device_mappings)
  new_mappings = []

  block_device_mappings.each do |mapping|
    snapshot_id = mapping['ebs']['snapshot_id']
    new_snapshot_id = copy_snapshot(snapshot_id)
    mapping['ebs']['snapshot_id'] = new_snapshot_id
    mapping['ebs'].delete('encrypted')
    new_mappings << mapping
  end

  new_mappings
end

#prepare_snapshots_for_account(ami_id, account_id) ⇒ Array

Prepare volume snapshots of an AMI for a new account

Parameters:

  • ami_id (String)

    The ID of the AMI to prepare

  • account_id (String)

    The ID of the AWS account to prepare

Returns:

  • (Array)

    Block device mappings discovered from the AMI



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/minimal_pipeline/ec2.rb', line 80

def (ami_id, )
  images = @client.describe_images(image_ids: [ami_id])
  block_device_mappings = images.images[0].block_device_mappings
  new_mappings = []

  block_device_mappings.each do |mapping|
    snapshot_id = mapping.ebs.snapshot_id
    puts "old snapshot ID: #{snapshot_id}"
    new_snapshot_id = copy_snapshot(snapshot_id)
    puts 'modifying new snapshot attribute'
    (new_snapshot_id, )
    puts "new snapshot has been modified for the #{} account"
    mapping.ebs.snapshot_id = new_snapshot_id
    new_mappings << mapping.to_hash
    puts '==========================================='
  end

  new_mappings
end

#register_ami(block_device_mappings, ami_name) ⇒ String

Register a new AMI based on block device mappings Currently only supports x86_64 HVM

Returns:

  • (String)

    The AMI ID of the newly created AMI



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/minimal_pipeline/ec2.rb', line 106

def register_ami(block_device_mappings, ami_name)
  response = @client.register_image(
    architecture: 'x86_64',
    block_device_mappings: block_device_mappings,
    name: ami_name,
    root_device_name: '/dev/sda1',
    virtualization_type: 'hvm'
  )

  response.image_id
end

#unlock_ami_for_account(snapshot_id, account_id) ⇒ Object

Update permissions to grant access to an AMI on another account

Parameters:

  • snapshot_id (String)

    The ID of the snapshot to adjust

  • account_id (String)

    The AWS account to grant access to



66
67
68
69
70
71
72
73
# File 'lib/minimal_pipeline/ec2.rb', line 66

def (snapshot_id, )
  @client.modify_snapshot_attribute(
    attribute: 'createVolumePermission',
    operation_type: 'add',
    snapshot_id: snapshot_id,
    user_ids: []
  )
end

#wait_for_snapshot(snapshot_id) ⇒ Object

Block processing until snapshot until new snapshot is ready

Parameters:

  • snapshot_id (String)

    The ID of the new snapshot



35
36
37
38
39
40
41
# File 'lib/minimal_pipeline/ec2.rb', line 35

def wait_for_snapshot(snapshot_id)
  puts "waiting on new snapshot #{snapshot_id} to be ready"
  @client.wait_until(:snapshot_completed, snapshot_ids: [snapshot_id])
  puts "New snapshot #{snapshot_id}is ready"
rescue Aws::Waiters::Errors::WaiterFailed => error
  puts "failed waiting for snapshot to be ready: #{error.message}"
end