From 60d91fda33c17da49f80a554930ee292fa14aea5 Mon Sep 17 00:00:00 2001 From: Mark Wilkinson Date: Mon, 14 Nov 2016 13:31:00 +0000 Subject: [PATCH] Add functionality to support elbv2 load balancers - Add fix for using ec2_launchconfiguration with existing configs but no block_device_mappings (defaults to []) - add termination_policies and target_group support - update README.md --- README.md | 6 +++ .../provider/ec2_autoscalinggroup/v2.rb | 44 +++++++++++++++++++ .../provider/ec2_launchconfiguration/v2.rb | 6 ++- lib/puppet/type/ec2_autoscalinggroup.rb | 18 ++++++++ lib/puppet_x/puppetlabs/aws.rb | 8 ++++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 03e2aeba..d7bd2c1b 100644 --- a/README.md +++ b/README.md @@ -597,9 +597,15 @@ back- end instances. Accepts a hash with the following keys: ##### `load_balancers` *Optional* A list of load balancer names that should be attached to this autoscaling group. +##### `target_groups` +*Optional* A list of ELBv2 Target Group names that should be attached to this autoscaling group. + ##### `subnets` *Optional* The subnets to associate with the autoscaling group. +##### `termination_policies` +*Optional* A list of termination policies to use when scaling in instances. For valid termination policies, see [Controlling Which Instances Auto Scaling Terminates During Scale In](http://docs.aws.amazon.com/autoscaling/latest/userguide/as-instance-termination.html). + #####`tags` *Optional* The tags to assign to the autoscaling group. Accepts a 'key => value' hash of tags. The tags are not propagated to launched instances. diff --git a/lib/puppet/provider/ec2_autoscalinggroup/v2.rb b/lib/puppet/provider/ec2_autoscalinggroup/v2.rb index 093b5953..d0a413ca 100644 --- a/lib/puppet/provider/ec2_autoscalinggroup/v2.rb +++ b/lib/puppet/provider/ec2_autoscalinggroup/v2.rb @@ -59,6 +59,8 @@ def self.group_to_hash(region, group) health_check_grace_period: group.health_check_grace_period, new_instances_protected_from_scale_in: group.new_instances_protected_from_scale_in, load_balancers: fetch_load_balancers(autoscaling_client(region), group.auto_scaling_group_name), + target_groups: fetch_target_groups(region, group.auto_scaling_group_name), + termination_policies: group.termination_policies, instance_count: group.instances.count, ensure: :present, subnets: subnet_names, @@ -72,6 +74,17 @@ def self.fetch_load_balancers(client, name) response.load_balancers.collect { |lb| lb.load_balancer_name } end + def self.fetch_target_groups(region, name) + response = autoscaling_client(region).describe_load_balancer_target_groups(auto_scaling_group_name: name) + response.load_balancer_target_groups.collect { |tg| fetch_target_group_name(region, tg.load_balancer_target_group_arn) }.flatten + end + + def self.fetch_target_group_name(region, value) + arn = value.is_a?(Array) ? value : [value] + response = elbv2_client(region).describe_target_groups(target_group_arns: arn) + response.target_groups.collect { |tg| tg.target_group_name } + end + def exists? Puppet.debug("Checking if auto scaling group #{name} exists in region #{target_region}") @property_hash[:ensure] == :present @@ -177,6 +190,14 @@ def subnets=(value) ) end + def termination_policies=(value) + policies = value.is_a?(Array) ? value : [value] + autoscaling_client(target_region).update_auto_scaling_group( + auto_scaling_group_name: name, + termination_policies: policies, + ) + end + def availability_zones=(value) zones = value.is_a?(Array) ? value : [value] autoscaling_client(target_region).update_auto_scaling_group( @@ -185,6 +206,29 @@ def availability_zones=(value) ) end + def target_groups=(value) + should_names = value.is_a?(Array) ? value : [value] + + response = elbv2_client(target_region).describe_target_groups(names: should_names) + should = (response.target_groups.collect { |tg| tg.target_group_arn }).to_set + + response = elbv2_client(target_region).describe_target_groups(names: target_groups) + is = (response.target_groups.collect { |tg| tg.target_group_arn }).to_set + + to_delete = is - should + to_add = should - is + + autoscaling_client(target_region).attach_load_balancer_target_groups( + auto_scaling_group_name: name, + target_group_arns: to_add, + ) + autoscaling_client(target_region).detach_load_balancer_target_groups( + auto_scaling_group_name: name, + target_group_arns: to_delete, + ) + + end + def load_balancers=(value) should = (value.is_a?(Array) ? value : [value]).to_set is = fetch_load_balancers(autoscaling_client(target_region), name).to_set diff --git a/lib/puppet/provider/ec2_launchconfiguration/v2.rb b/lib/puppet/provider/ec2_launchconfiguration/v2.rb index edb98143..f84288d8 100644 --- a/lib/puppet/provider/ec2_launchconfiguration/v2.rb +++ b/lib/puppet/provider/ec2_launchconfiguration/v2.rb @@ -62,7 +62,11 @@ def self.config_to_hash(region, config) spot_price: config.spot_price, ebs_optimized: config.ebs_optimized, } - config[:block_device_mappings] = devices unless devices.empty? + if devices.empty? + config[:block_device_mappings] = [ ] + else + config[:block_device_mappings] = devices + end config end diff --git a/lib/puppet/type/ec2_autoscalinggroup.rb b/lib/puppet/type/ec2_autoscalinggroup.rb index 44b73ce0..45cb1298 100644 --- a/lib/puppet/type/ec2_autoscalinggroup.rb +++ b/lib/puppet/type/ec2_autoscalinggroup.rb @@ -135,6 +135,24 @@ def insync?(is) end end + newproperty(:target_groups, :array_matching => :all) do + desc 'The target groups attached to this group.' + validate do |value| + fail 'target_groups cannot be blank' if value == '' + fail 'target_groups should be a String' unless value.is_a?(String) + end + def insync?(is) + is.to_set == should.to_set + end + end + + newproperty(:termination_policies, :array_matching => :all) do + desc 'The termination policies attached to this group.' + def insync?(is) + is.to_set == should.to_set + end + end + newproperty(:subnets, :array_matching => :all) do desc 'The subnets to associate the autoscaling group.' validate do |value| diff --git a/lib/puppet_x/puppetlabs/aws.rb b/lib/puppet_x/puppetlabs/aws.rb index 5b7fd9c9..184631d0 100644 --- a/lib/puppet_x/puppetlabs/aws.rb +++ b/lib/puppet_x/puppetlabs/aws.rb @@ -162,6 +162,14 @@ def elb_client(region = default_region) self.class.elb_client(region) end + def self.elbv2_client(region = default_region) + ::Aws::ElasticLoadBalancingV2::Client.new(client_config(region)) + end + + def elbv2_client(region = default_region) + self.class.elbv2_client(region) + end + def self.autoscaling_client(region = default_region) ::Aws::AutoScaling::Client.new(client_config(region)) end