chef-boneyard / chef-provisioning-aws

AWS driver and resources for Chef that uses the AWS SDK
Apache License 2.0
142 stars 122 forks source link

Extending support for aws_auto_scaling_group #333

Open robcoward opened 9 years ago

robcoward commented 9 years ago

Is anyone currently working on enhancing chef-provisioning-aws support for AutoScale groups ? We need to be able to define notifications and scaling policies on our auto-scale groups, and for now have implemented them with the following ruby_blocks.

If no one else is current working on it, I don't mind having a crack at extending the chef-provisioning-aws code and adding the support ?

  cluster = aws_auto_scaling_group "autoscale-cluster" do
    desired_capacity node['autoscale']['DesiredInstances']
    min_size node['autoscale']['MinInstances']
    max_size node['autoscale']['MaxInstances']
    launch_configuration "autoscale-config"
    load_balancers "autoscale-elb"
    options health_check_type: 'elb',
            health_check_grace_period: 900,
            default_cooldown: 60
    notifies :run, 'ruby_block[Configure Autoscale Group]', :immediately
  end

  topic = aws_sns_topic "cluster-notifications" do
  end

  # Hacky, but works for now.
  ruby_block 'Configure Autoscale Group' do
    block do
      cluster.aws_object.notification_configurations.create(
        :topic => topic.aws_object,
        :types => [
          'autoscaling:EC2_INSTANCE_LAUNCH',
          'autoscaling:EC2_INSTANCE_TERMINATE',
        ]
      )

      scale_up_policy = cluster.aws_object.scaling_policies.create("cluster-scaleup-policy",
        { :adjustment_type => 'ChangeInCapacity',
          :scaling_adjustment => 1,
          :cooldown => 60
        }
      )
      scale_down_policy = cluster.aws_object.scaling_policies.create("cluster-scaledown-policy",
        { :adjustment_type => 'ChangeInCapacity',
          :scaling_adjustment => -1,
          :cooldown => 60
        }
      )

      cw = AWS::CloudWatch.new
      cw.alarms.create("Cluster-CPU-High-Alarm", {
          :namespace => 'AWS/EC2',
          :metric_name => 'CPUUtilization',
          :dimensions => [ { :name => 'AutoScalingGroupName', 
                             :value => "autoscale-cluster" } ],
          :comparison_operator =>  'GreaterThanThreshold',
          :evaluation_periods => node['autoscale']['AlarmEvaluationPeriods'],
          :period => node['autoscale']['AlarmPeriod'],
          :statistic => 'Average',
          :threshold =>node['autoscale']['ScaleUpCPUThreshold'],
          :alarm_actions => [ scale_up_policy.arn ],
          :alarm_description => "Scale-up if CPU > #{node['autoscale']['ScaleUpCPUThreshold']}% for #{node['autoscale']['AlarmPeriod'] * node['autoscale']['AlarmEvaluationPeriods'] / 60} minutes"
        })
      cw.alarms.create("Cluster-CPU-Low-Alarm", {
          :namespace => 'AWS/EC2',
          :metric_name => 'CPUUtilization',
          :dimensions => [ { :name => 'AutoScalingGroupName', 
                             :value => "autoscale-cluster" } ],
          :comparison_operator =>  'LessThanThreshold',
          :evaluation_periods => node['autoscale']['AlarmEvaluationPeriods'],
          :period => node['autoscale']['AlarmPeriod'],
          :statistic => 'Average',
          :threshold => node['autoscale']['ScaleDownCPUThreshold'],
          :alarm_actions => [ scale_down_policy.arn ],
          :alarm_description => "Scale-up if CPU < #{node['autoscale']['ScaleDownCPUThreshold']}% for #{node['autoscale']['AlarmPeriod'] * node['autoscale']['AlarmEvaluationPeriods'] / 60} minutes"
        })
    end
    action :nothing
  end
randomcamel commented 8 years ago

No one is working on it that we know of, so please feel free!

tyler-ball commented 8 years ago

If you wanted to improve the aws_auto_scaling_group resource/provider, please feel free to do so. Looking at it now, it is pretty bare bones. Looking at your examples here it seems like we would add 2 attributes - notification_configurations and scaling_policies. I think the CloudWatch configuration would be its own new resource/provider.

aws_auto_scaling_group "autoscale-cluster" do
    desired_capacity node['autoscale']['DesiredInstances']
    min_size node['autoscale']['MinInstances']
    max_size node['autoscale']['MaxInstances']
    launch_configuration "autoscale-config"
    load_balancers "autoscale-elb"
    notification_configurations([{
      :topic => "cluster-notifications", # This should look up the id automatically if needed
      :types => [
        'autoscaling:EC2_INSTANCE_LAUNCH',
        'autoscaling:EC2_INSTANCE_TERMINATE',
      ]
    }])
    scaling_policies({
      "cluster-scaleup-policy" => {
        :adjustment_type => 'ChangeInCapacity',
        :scaling_adjustment => 1,
        :cooldown => 60
      },
      "cluster-scaledown-policy" => {
        :adjustment_type => 'ChangeInCapacity',
        :scaling_adjustment => -1,
        :cooldown => 60
      }
    })
    options health_check_type: 'elb',
            health_check_grace_period: 900,
            default_cooldown: 60
end

aws_cloud_watch_alarm "Cluster-CPU-High-Alarm" do
  namespace 'AWS/EC2'
  metric_name 'CPUUtilization'
  dimensions [ { :name => 'AutoScalingGroupName', :value => "autoscale-cluster" } ],
  comparison_operator 'GreaterThanThreshold'
  evaluation_periods node['autoscale']['AlarmEvaluationPeriods']
  period node['autoscale']['AlarmPeriod']
  statistic 'Average'
  threshold node['autoscale']['ScaleUpCPUThreshold']
  alarm_actions [ scale_up_policy.arn ]
  alarm_description "Scale-up if CPU > #{node['autoscale']['ScaleUpCPUThreshold']}% for #{node['autoscale']['AlarmPeriod'] * node['autoscale']['AlarmEvaluationPeriods'] / 60} minutes"
end

#...
rgeddis commented 8 years ago

462