Commit 11136786 authored by Daisuke Fujita's avatar Daisuke Fujita

Merge pull request #102 from dtan4/ec2-block-device

Modify EC2 block devices
parents 1e7ead21 78f6f68d
......@@ -22,21 +22,22 @@ module Terraforming
def tfstate(tfstate_base)
resources = instances.inject({}) do |result, instance|
in_vpc = in_vpc?(instance)
block_devices = block_devices_of(instance)
attributes = {
"ami"=> instance.image_id,
"associate_public_ip_address"=> "true",
"availability_zone"=> instance.placement.availability_zone,
"ebs_block_device.#"=> instance.block_device_mappings.length.to_s,
"ebs_block_device.#"=> ebs_block_devices_in(block_devices, instance).length.to_s,
"ebs_optimized"=> instance.ebs_optimized.to_s,
"ephemeral_block_device.#"=> "0",
"ephemeral_block_device.#" => "0", # Terraform 0.6.1 cannot fetch this field from AWS
"id"=> instance.instance_id,
"instance_type"=> instance.instance_type,
"private_dns"=> instance.private_dns_name,
"private_ip"=> instance.private_ip_address,
"public_dns"=> instance.public_dns_name,
"public_ip"=> instance.public_ip_address,
"root_block_device.#"=> instance.root_device_name ? "1" : "0",
"root_block_device.#"=> root_block_devices_in(block_devices, instance).length.to_s,
"security_groups.#"=> in_vpc ? "0" : instance.security_groups.length.to_s,
"source_dest_check"=> instance.source_dest_check.to_s,
"tenancy"=> instance.placement.tenancy,
......@@ -64,6 +65,24 @@ module Terraforming
private
def block_device_ids_of(instance)
instance.block_device_mappings.map { |bdm| bdm.ebs.volume_id }
end
def block_devices_of(instance)
@client.describe_volumes(volume_ids: block_device_ids_of(instance)).volumes
end
def block_device_mapping_of(instance, volume_id)
instance.block_device_mappings.select { |bdm| bdm.ebs.volume_id == volume_id }[0]
end
def ebs_block_devices_in(block_devices, instance)
block_devices.reject do |bd|
root_block_device?(block_device_mapping_of(instance, bd.volume_id), instance)
end
end
#
# NOTE(dtan4):
# Original logic is here:
......@@ -75,13 +94,21 @@ module Terraforming
end
def instances
@client.describe_instances.reservations.map(&:instances).flatten
@client.describe_instances.reservations.map(&:instances).flatten.reject { |instance| instance.state.name == "terminated" }
end
def module_name_of(instance)
normalize_module_name(name_from_tag(instance, instance.instance_id))
end
def root_block_device?(block_device_mapping, instance)
block_device_mapping.device_name == instance.root_device_name
end
def root_block_devices_in(block_devices, instance)
block_devices.select { |bd| root_block_device?(block_device_mapping_of(instance, bd.volume_id), instance) }
end
def vpc_security_groups_of(instance)
instance.security_groups.select { |security_group| /\Asg-/ =~ security_group.group_id }
end
......
......@@ -15,10 +15,25 @@ resource "aws_instance" "<%= module_name_of(instance) %>" {
private_ip = "<%= instance.private_ip_address %>"
source_dest_check = <%= instance.source_dest_check %>
<% instance.block_device_mappings.each do |block_device| -%>
<% block_devices_of(instance).each do |block_device| -%>
<%- mapping = block_device_mapping_of(instance, block_device.volume_id) -%>
<%- if root_block_device?(mapping, instance) -%>
root_block_device {
volume_type = "<%= block_device.volume_type %>"
volume_size = <%= block_device.size %>
iops = <%= block_device.iops %>
delete_on_termination = <%= mapping.ebs.delete_on_termination %>
}
<%- else -%>
ebs_block_device {
device_name = "<%= block_device.device_name %>"
device_name = "<%= mapping.device_name %>"
snapshot_id = "<%= block_device.snapshot_id %>"
volume_type = "<%= block_device.volume_type %>"
volume_size = <%= block_device.size %>
iops = <%= block_device.iops %>
delete_on_termination = <%= mapping.ebs.delete_on_termination %>
}
<% end -%>
<% end -%>
tags {
......
......@@ -115,7 +115,7 @@ module Terraforming
root_device_name: "/dev/sda1",
block_device_mappings: [
{
device_name: "/dev/sda1",
device_name: "/dev/sda2",
ebs: {
volume_id: "vol-5678efgh", status: "attached",
attach_time: Time.parse("2015-03-12 01:23:45 UTC"), delete_on_termination: true
......@@ -186,8 +186,61 @@ module Terraforming
]
end
let(:hoge_volumes) do
[
{
volume_id: "vol-1234abcd",
size: 8,
snapshot_id: "snap-1234abcd",
availability_zone: "ap-northeast-1c",
state: "in-use",
create_time: Time.parse("2015-07-29 15:28:02 UTC"),
attachments: [
{
volume_id: "vol-1234abcd",
instance_id: "i-1234abcd",
device: "/dev/sda1",
state: "attached",
attach_time: Time.parse("2015-03-12 12:34:56 UTC"),
delete_on_termination: true
}
],
volume_type: "gp2",
iops: 24,
encrypted: false
}
]
end
let(:fuga_volumes) do
[
{
volume_id: "vol-5678efgh",
size: 8,
snapshot_id: "snap-5678efgh",
availability_zone: "ap-northeast-1c",
state: "in-use",
create_time: Time.parse("2015-07-29 15:28:02 UTC"),
attachments: [
{
volume_id: "vol-5678efgh",
instance_id: "i-5678efgh",
device: "/dev/sda2",
state: "attached",
attach_time: Time.parse("2015-03-12 12:34:56 UTC"),
delete_on_termination: true
}
],
volume_type: "gp2",
iops: 24,
encrypted: false
}
]
end
before do
client.stub_responses(:describe_instances, reservations: reservations)
client.stub_responses(:describe_volumes, [{ volumes: hoge_volumes }, { volumes: fuga_volumes }])
end
describe ".tf" do
......@@ -205,8 +258,11 @@ resource "aws_instance" "hoge" {
private_ip = "10.0.0.100"
source_dest_check = true
ebs_block_device {
device_name = "/dev/sda1"
root_block_device {
volume_type = "gp2"
volume_size = 8
iops = 24
delete_on_termination = true
}
tags {
......@@ -226,7 +282,12 @@ resource "aws_instance" "i-5678efgh" {
source_dest_check = true
ebs_block_device {
device_name = "/dev/sda1"
device_name = "/dev/sda2"
snapshot_id = "snap-5678efgh"
volume_type = "gp2"
volume_size = 8
iops = 24
delete_on_termination = true
}
tags {
......@@ -250,60 +311,60 @@ resource "aws_instance" "i-5678efgh" {
],
"outputs" => {},
"resources" => {
"aws_instance.hoge"=> {
"type"=> "aws_instance",
"primary"=> {
"id"=> "i-1234abcd",
"attributes"=> {
"ami"=> "ami-1234abcd",
"associate_public_ip_address"=> "true",
"availability_zone"=> "ap-northeast-1b",
"ebs_block_device.#"=> "1",
"ebs_optimized"=> "false",
"ephemeral_block_device.#"=> "0",
"id"=> "i-1234abcd",
"instance_type"=> "t2.micro",
"private_dns"=> "ip-10-0-0-100.ap-northeast-1.compute.internal",
"private_ip"=> "10.0.0.100",
"public_dns"=> "ec2-54-12-0-0.ap-northeast-1.compute.amazonaws.com",
"public_ip"=> "54.12.0.0",
"root_block_device.#"=> "1",
"security_groups.#"=> "0",
"source_dest_check"=> "true",
"tenancy"=> "default",
"vpc_security_group_ids.#"=> "1",
"subnet_id"=> "subnet-1234abcd",
"aws_instance.hoge" => {
"type" => "aws_instance",
"primary" => {
"id" => "i-1234abcd",
"attributes" => {
"ami" => "ami-1234abcd",
"associate_public_ip_address" => "true",
"availability_zone" => "ap-northeast-1b",
"ebs_block_device.#" => "0",
"ebs_optimized" => "false",
"ephemeral_block_device.#" => "0",
"id" => "i-1234abcd",
"instance_type" => "t2.micro",
"private_dns" => "ip-10-0-0-100.ap-northeast-1.compute.internal",
"private_ip" => "10.0.0.100",
"public_dns" => "ec2-54-12-0-0.ap-northeast-1.compute.amazonaws.com",
"public_ip" => "54.12.0.0",
"root_block_device.#" => "1",
"security_groups.#" => "0",
"source_dest_check" => "true",
"tenancy" => "default",
"vpc_security_group_ids.#" => "1",
"subnet_id" => "subnet-1234abcd",
},
"meta"=> {
"schema_version"=> "1"
"meta" => {
"schema_version" => "1"
}
}
},
"aws_instance.i-5678efgh"=> {
"type"=> "aws_instance",
"primary"=> {
"id"=> "i-5678efgh",
"attributes"=> {
"ami"=> "ami-5678efgh",
"associate_public_ip_address"=> "true",
"availability_zone"=> "ap-northeast-1b",
"ebs_block_device.#"=> "1",
"ebs_optimized"=> "false",
"ephemeral_block_device.#"=> "0",
"id"=> "i-5678efgh",
"instance_type"=> "t2.micro",
"private_dns"=> "ip-10-0-0-101.ap-northeast-1.compute.internal",
"private_ip"=> "10.0.0.101",
"public_dns"=> "ec2-54-12-0-1.ap-northeast-1.compute.amazonaws.com",
"public_ip"=> "54.12.0.1",
"root_block_device.#"=> "1",
"security_groups.#"=> "1",
"source_dest_check"=> "true",
"tenancy"=> "default",
"vpc_security_group_ids.#"=> "0",
"aws_instance.i-5678efgh" => {
"type" => "aws_instance",
"primary" => {
"id" => "i-5678efgh",
"attributes" => {
"ami" => "ami-5678efgh",
"associate_public_ip_address" => "true",
"availability_zone" => "ap-northeast-1b",
"ebs_block_device.#" => "1",
"ebs_optimized" => "false",
"ephemeral_block_device.#" => "0",
"id" => "i-5678efgh",
"instance_type" => "t2.micro",
"private_dns" => "ip-10-0-0-101.ap-northeast-1.compute.internal",
"private_ip" => "10.0.0.101",
"public_dns" => "ec2-54-12-0-1.ap-northeast-1.compute.amazonaws.com",
"public_ip" => "54.12.0.1",
"root_block_device.#" => "0",
"security_groups.#" => "1",
"source_dest_check" => "true",
"tenancy" => "default",
"vpc_security_group_ids.#" => "0",
},
"meta"=> {
"schema_version"=> "1"
"meta" => {
"schema_version" => "1"
}
}
}
......@@ -350,60 +411,60 @@ resource "aws_instance" "i-5678efgh" {
}
}
},
"aws_instance.hoge"=> {
"type"=> "aws_instance",
"primary"=> {
"id"=> "i-1234abcd",
"attributes"=> {
"ami"=> "ami-1234abcd",
"associate_public_ip_address"=> "true",
"availability_zone"=> "ap-northeast-1b",
"ebs_block_device.#"=> "1",
"ebs_optimized"=> "false",
"ephemeral_block_device.#"=> "0",
"id"=> "i-1234abcd",
"instance_type"=> "t2.micro",
"private_dns"=> "ip-10-0-0-100.ap-northeast-1.compute.internal",
"private_ip"=> "10.0.0.100",
"public_dns"=> "ec2-54-12-0-0.ap-northeast-1.compute.amazonaws.com",
"public_ip"=> "54.12.0.0",
"root_block_device.#"=> "1",
"security_groups.#"=> "0",
"source_dest_check"=> "true",
"tenancy"=> "default",
"vpc_security_group_ids.#"=> "1",
"subnet_id"=> "subnet-1234abcd",
"aws_instance.hoge" => {
"type" => "aws_instance",
"primary" => {
"id" => "i-1234abcd",
"attributes" => {
"ami" => "ami-1234abcd",
"associate_public_ip_address" => "true",
"availability_zone" => "ap-northeast-1b",
"ebs_block_device.#" => "0",
"ebs_optimized" => "false",
"ephemeral_block_device.#" => "0",
"id" => "i-1234abcd",
"instance_type" => "t2.micro",
"private_dns" => "ip-10-0-0-100.ap-northeast-1.compute.internal",
"private_ip" => "10.0.0.100",
"public_dns" => "ec2-54-12-0-0.ap-northeast-1.compute.amazonaws.com",
"public_ip" => "54.12.0.0",
"root_block_device.#" => "1",
"security_groups.#" => "0",
"source_dest_check" => "true",
"tenancy" => "default",
"vpc_security_group_ids.#" => "1",
"subnet_id" => "subnet-1234abcd",
},
"meta"=> {
"schema_version"=> "1"
"meta" => {
"schema_version" => "1"
}
}
},
"aws_instance.i-5678efgh"=> {
"type"=> "aws_instance",
"primary"=> {
"id"=> "i-5678efgh",
"attributes"=> {
"ami"=> "ami-5678efgh",
"associate_public_ip_address"=> "true",
"availability_zone"=> "ap-northeast-1b",
"ebs_block_device.#"=> "1",
"ebs_optimized"=> "false",
"ephemeral_block_device.#"=> "0",
"id"=> "i-5678efgh",
"instance_type"=> "t2.micro",
"private_dns"=> "ip-10-0-0-101.ap-northeast-1.compute.internal",
"private_ip"=> "10.0.0.101",
"public_dns"=> "ec2-54-12-0-1.ap-northeast-1.compute.amazonaws.com",
"public_ip"=> "54.12.0.1",
"root_block_device.#"=> "1",
"security_groups.#"=> "1",
"source_dest_check"=> "true",
"tenancy"=> "default",
"vpc_security_group_ids.#"=> "0",
"aws_instance.i-5678efgh" => {
"type" => "aws_instance",
"primary" => {
"id" => "i-5678efgh",
"attributes" => {
"ami" => "ami-5678efgh",
"associate_public_ip_address" => "true",
"availability_zone" => "ap-northeast-1b",
"ebs_block_device.#" => "1",
"ebs_optimized" => "false",
"ephemeral_block_device.#" => "0",
"id" => "i-5678efgh",
"instance_type" => "t2.micro",
"private_dns" => "ip-10-0-0-101.ap-northeast-1.compute.internal",
"private_ip" => "10.0.0.101",
"public_dns" => "ec2-54-12-0-1.ap-northeast-1.compute.amazonaws.com",
"public_ip" => "54.12.0.1",
"root_block_device.#" => "0",
"security_groups.#" => "1",
"source_dest_check" => "true",
"tenancy" => "default",
"vpc_security_group_ids.#" => "0",
},
"meta"=> {
"schema_version"=> "1"
"meta" => {
"schema_version" => "1"
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment