Commit d0a646d8 authored by Daisuke Fujita's avatar Daisuke Fujita Committed by GitHub

Merge pull request #291 from dtan4/alb

Support ALB (Application Load Balancer)
parents 13b7f339 f73ebb88
......@@ -8,6 +8,7 @@ require "terraforming/util"
require "terraforming/version"
require "terraforming/cli"
require "terraforming/resource/alb"
require "terraforming/resource/auto_scaling_group"
require "terraforming/resource/cloud_watch_alarm"
require "terraforming/resource/db_parameter_group"
......
......@@ -9,6 +9,11 @@ module Terraforming
type: :boolean,
desc: "Use the bundled CA certificate from AWS SDK"
desc "alb", "ALB"
def alb
execute(Terraforming::Resource::ALB, options)
end
desc "asg", "AutoScaling Group"
def asg
execute(Terraforming::Resource::AutoScalingGroup, options)
......
module Terraforming
module Resource
class ALB
include Terraforming::Util
def self.tf(client: Aws::ElasticLoadBalancingV2::Client.new)
self.new(client).tf
end
def self.tfstate(client: Aws::ElasticLoadBalancingV2::Client.new)
self.new(client).tfstate
end
def initialize(client)
@client = client
end
def tf
apply_template(@client, "tf/alb")
end
def tfstate
load_balancers.inject({}) do |resources, load_balancer|
load_balancer_attributes = load_balancer_attributes_of(load_balancer)
attributes = {
"dns_name" => load_balancer.dns_name,
"enable_deletion_protection" => load_balancer_attributes["deletion_protection.enabled"].to_s,
"id" => load_balancer.load_balancer_arn,
"idle_timeout" => load_balancer_attributes["idle_timeout.timeout_seconds"].to_s,
"internal" => internal?(load_balancer).to_s,
"name" => load_balancer.load_balancer_name,
"security_groups.#" => load_balancer.security_groups.length.to_s,
"subnets.#" => load_balancer.availability_zones.length.to_s,
"zone_id" => load_balancer.canonical_hosted_zone_id,
}
attributes.merge!(access_logs_attributes_of(load_balancer_attributes))
attributes.merge!(tag_attributes_of(load_balancer))
resources["aws_alb.#{module_name_of(load_balancer)}"] = {
"type" => "aws_alb",
"primary" => {
"id" => load_balancer.load_balancer_arn,
"attributes" => attributes
}
}
resources
end
end
private
def access_logs_attributes_of(load_balancer_attributes)
{
"access_logs.#" => "1",
"access_logs.0.bucket" => load_balancer_attributes["access_logs.s3.bucket"],
"access_logs.0.enabled" => load_balancer_attributes["access_logs.s3.enabled"].to_s,
"access_logs.0.prefix" => load_balancer_attributes["access_logs.s3.prefix"],
}
end
def internal?(load_balancer)
load_balancer.scheme == "internal"
end
def load_balancers
@client.describe_load_balancers.load_balancers
end
def load_balancer_attributes_of(load_balancer)
@client.describe_load_balancer_attributes(load_balancer_arn: load_balancer.load_balancer_arn).attributes.inject({}) do |result, attribute|
result[attribute.key] = attribute.value
result
end
end
def module_name_of(load_balancer)
normalize_module_name(load_balancer.load_balancer_name)
end
def tag_attributes_of(load_balancer)
tags = tags_of(load_balancer)
attributes = { "tags.%" => tags.length.to_s }
tags.each do |tag|
attributes["tags.#{tag.key}"] = tag.value
end
attributes
end
def tags_of(load_balancer)
@client.describe_tags(resource_arns: [load_balancer.load_balancer_arn]).tag_descriptions.first.tags
end
end
end
end
<% load_balancers.each do |load_balancer| -%>
<%- load_balancer_attributes = load_balancer_attributes_of(load_balancer) -%>
<%- tags = tags_of(load_balancer) -%>
resource "aws_alb" "<%= module_name_of(load_balancer) %>" {
idle_timeout = <%= load_balancer_attributes["idle_timeout.timeout_seconds"] %>
internal = <%= internal?(load_balancer).to_s %>
name = "<%= load_balancer.load_balancer_name %>"
security_groups = <%= load_balancer.security_groups.inspect %>
subnets = <%= load_balancer.availability_zones.map { |az| az.subnet_id }.inspect %>
enable_deletion_protection = <%= load_balancer_attributes["deletion_protection.enabled"].to_s %>
<%- if load_balancer_attributes["access_logs.s3.enabled"] == "true" -%>
access_logs {
bucket = "<%= load_balancer_attributes["access_logs.s3.bucket"] %>"
enabled = <%= load_balancer_attributes["access_logs.s3.enabled"] %>
prefix = "<%= load_balancer_attributes["access_logs.s3.prefix"] %>"
}
<%- end -%>
tags {
<% tags.each do |tag| -%>
"<%= tag.key %>" = "<%= tag.value %>"
<% end -%>
}
}
<% end -%>
......@@ -32,6 +32,13 @@ module Terraforming
allow(klass).to receive(:tfstate).and_return({})
end
describe "asg" do
let(:klass) { Terraforming::Resource::ALB }
let(:command) { :alb }
it_behaves_like "CLI examples"
end
describe "asg" do
let(:klass) { Terraforming::Resource::AutoScalingGroup }
let(:command) { :asg }
......
require "spec_helper"
module Terraforming
module Resource
describe ALB do
let(:client) do
Aws::ElasticLoadBalancingV2::Client.new(stub_responses: true)
end
let(:load_balancers) do
[
{
load_balancer_arn: "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/hoge/1234abcd1234abcd",
dns_name: "hoge-123456789.ap-northeast-1.elb.amazonaws.com",
canonical_hosted_zone_id: "12345678ABCDEF",
created_time: Time.parse("2016-08-19 00:39:01 UTC"),
load_balancer_name: "hoge",
scheme: "internet-facing",
vpc_id: "vpc-1234abcd",
state: { code: "active" },
type: "application",
availability_zones: [
{ zone_name: "ap-northeast-1c", subnet_id: "subnet-1234abcd" },
{ zone_name: "ap-northeast-1b", subnet_id: "subnet-5678efgh" }
],
security_groups: ["sg-1234abcd", "sg-5678efgh"]
},
{
load_balancer_arn: "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/fuga/5678efgh5678efgh",
dns_name: "fuga-567891234.ap-northeast-1.elb.amazonaws.com",
canonical_hosted_zone_id: "12345678ABCDEF",
created_time: Time.parse("2016-08-31 06:23:57 UTC"),
load_balancer_name: "fuga",
scheme: "internal",
vpc_id: "vpc-5678efgh",
state: { code: "active" },
type: "application",
availability_zones: [
{ zone_name: "ap-northeast-1c", subnet_id: "subnet-1234abcd" },
{ zone_name: "ap-northeast-1b", subnet_id: "subnet-9012ijkl" }
],
security_groups: ["sg-1234abcd"]
},
]
end
let(:hoge_attributes) do
[
{ key: "access_logs.s3.enabled", value: "true" },
{ key: "idle_timeout.timeout_seconds", value: "600" },
{ key: "access_logs.s3.prefix", value: "hoge" },
{ key: "deletion_protection.enabled", value: "false" },
{ key: "access_logs.s3.bucket", value: "my-elb-logs" },
]
end
let(:fuga_attributes) do
[
{ key: "access_logs.s3.enabled", value: "false" },
{ key: "idle_timeout.timeout_seconds", value: "60" },
{ key: "access_logs.s3.prefix", value: "fuga" },
{ key: "deletion_protection.enabled", value: "true" },
{ key: "access_logs.s3.bucket", value: "my-elb-logs" },
]
end
let(:hoge_tag_descriptions) do
[
{
resource_arn: "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/hoge/1234abcd1234abcd",
tags: [
{ key: "Environment", value: "Production" }
]
}
]
end
let(:fuga_tag_descriptions) do
[
{
resource_arn: "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/fuga/5678efgh5678efgh",
tags: []
}
]
end
before do
client.stub_responses(:describe_load_balancers, load_balancers: load_balancers)
client.stub_responses(:describe_load_balancer_attributes, [
{ attributes: hoge_attributes },
{ attributes: fuga_attributes },
])
client.stub_responses(:describe_tags, [
{ tag_descriptions: hoge_tag_descriptions },
{ tag_descriptions: fuga_tag_descriptions },
])
end
describe ".tf" do
it "should generate tf" do
expect(described_class.tf(client: client)).to eq <<-EOS
resource "aws_alb" "hoge" {
idle_timeout = 600
internal = false
name = "hoge"
security_groups = ["sg-1234abcd", "sg-5678efgh"]
subnets = ["subnet-1234abcd", "subnet-5678efgh"]
enable_deletion_protection = false
access_logs {
bucket = "my-elb-logs"
enabled = true
prefix = "hoge"
}
tags {
"Environment" = "Production"
}
}
resource "aws_alb" "fuga" {
idle_timeout = 60
internal = true
name = "fuga"
security_groups = ["sg-1234abcd"]
subnets = ["subnet-1234abcd", "subnet-9012ijkl"]
enable_deletion_protection = true
tags {
}
}
EOS
end
end
describe ".tfstate" do
it "should generate tfstate" do
expect(described_class.tfstate(client: client)).to eq({
"aws_alb.hoge" => {
"type" => "aws_alb",
"primary" => {
"id" => "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/hoge/1234abcd1234abcd",
"attributes" => {
"access_logs.#" => "1",
"access_logs.0.bucket" => "my-elb-logs",
"access_logs.0.prefix" => "hoge",
"access_logs.0.enabled" => "true",
"dns_name" => "hoge-123456789.ap-northeast-1.elb.amazonaws.com",
"enable_deletion_protection" => "false",
"id" => "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/hoge/1234abcd1234abcd",
"idle_timeout" => "600",
"internal" => "false",
"name" => "hoge",
"security_groups.#" => "2",
"subnets.#" => "2",
"tags.%" => "1",
"tags.Environment" => "Production",
"zone_id" => "12345678ABCDEF",
}
}
},
"aws_alb.fuga" => {
"type" => "aws_alb",
"primary" => {
"id" => "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/fuga/5678efgh5678efgh",
"attributes" => {
"access_logs.#" => "1",
"access_logs.0.bucket" => "my-elb-logs",
"access_logs.0.prefix" => "fuga",
"access_logs.0.enabled" => "false",
"dns_name" => "fuga-567891234.ap-northeast-1.elb.amazonaws.com",
"enable_deletion_protection" => "true",
"id" => "arn:aws:elasticloadbalancing:ap-northeast-1:012345678901:loadbalancer/app/fuga/5678efgh5678efgh",
"idle_timeout" => "60",
"internal" => "true",
"name" => "fuga",
"security_groups.#" => "1",
"subnets.#" => "2",
"tags.%" => "0",
"zone_id" => "12345678ABCDEF",
}
}
}
})
end
end
end
end
end
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