Class: CfnGuardian::Stacks::Resources

Inherits:
Object
  • Object
show all
Includes:
CfnDsl::CloudFormation
Defined in:
lib/cfnguardian/stacks/resources.rb

Instance Method Summary collapse

Constructor Details

#initialize(template) ⇒ Resources

Returns a new instance of Resources.



10
11
12
# File 'lib/cfnguardian/stacks/resources.rb', line 10

def initialize(template)
  @template = template
end

Instance Method Details

#add_alarm(alarm) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/cfnguardian/stacks/resources.rb', line 33

def add_alarm(alarm)
  actions = alarm.alarm_action.kind_of?(Array) ? alarm.alarm_action.map{|action| Ref(action)} : [Ref(alarm.alarm_action)]
  actions.concat alarm.maintenance_groups.map {|mg| Ref(mg)} if alarm.maintenance_groups.any?
  use_search = alarm.search_expression.is_a?(String) && !alarm.search_expression.strip.empty?

  @template.declare do
    CloudWatch_Alarm("#{alarm.resource_hash}#{alarm.group}#{alarm.name.gsub(/[^0-9a-zA-Z]/i, '')}#{alarm.type}"[0..255]) do
      ActionsEnabled true
      AlarmDescription "Guardian alarm #{alarm.name} for the resource #{alarm.resource_id} in alarm group #{alarm.group}"
      AlarmName CfnGuardian::CloudWatch.get_alarm_name(alarm)
      ComparisonOperator alarm.comparison_operator
      EvaluationPeriods alarm.evaluation_periods
      Threshold alarm.threshold
      AlarmActions actions
      OKActions actions unless alarm.ok_action_disabled
      TreatMissingData alarm.treat_missing_data unless alarm.treat_missing_data.nil?
      DatapointsToAlarm alarm.datapoints_to_alarm unless alarm.datapoints_to_alarm.nil?

      if use_search
        aggregation = alarm.search_aggregation || 'MAX'
        Metrics [
          {
            Id: 'search_expression',
            Expression: alarm.search_expression,
            ReturnData: false
          },
          {
            Id: 'aggregate',
            Expression: "#{aggregation}(search_expression)",
            ReturnData: true
          }
        ]
      else
        Dimensions alarm.dimensions.map {|k,v| {Name: k, Value: v}} unless alarm.dimensions.nil?
        Statistic alarm.statistic if alarm.extended_statistic.nil?
        Period alarm.period
        MetricName alarm.metric_name
        Namespace alarm.namespace
        ExtendedStatistic alarm.extended_statistic unless alarm.extended_statistic.nil?
        EvaluateLowSampleCountPercentile alarm.evaluate_low_sample_count_percentile unless alarm.evaluate_low_sample_count_percentile.nil?
        Unit alarm.unit unless alarm.unit.nil?
      end
    end
  end
end

#add_composite_alarm(alarm) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/cfnguardian/stacks/resources.rb', line 96

def add_composite_alarm(alarm)
  @template.declare do
    CloudWatch_CompositeAlarm(alarm.name.gsub(/[^0-9a-zA-Z]/i, '')) do
      
      AlarmDescription alarm.description
      AlarmName "guardian-#{alarm.name}"
      AlarmRule alarm.rule
      
      unless alarm.alarm_action.nil?
        ActionsEnabled true
        AlarmActions [Ref(alarm.alarm_action)]
        InsufficientDataActions [Ref(alarm.alarm_action)]
        OKActions [Ref(alarm.alarm_action)]
      end
      
    end
  end
end

#add_event(event) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/cfnguardian/stacks/resources.rb', line 79

def add_event(event)
  @template.declare do          
    Events_Rule("#{event.group}#{event.type}#{event.hash}"[0..255]) do
      State 'ENABLED'
      Description "Guardian scheduled #{event.group} #{event.type}"
      ScheduleExpression "cron(#{event.cron})"
      Targets([
        { 
          Arn: FnGetAtt(event.target, :Arn),
          Id: event.hash,
          Input: FnSub(event.payload)
        }
      ])
    end
  end
end

#add_event_subscription(subscription) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/cfnguardian/stacks/resources.rb', line 131

def add_event_subscription(subscription)
  event_pattern = {}
  event_pattern['detail-type'] = [subscription.detail_type] unless subscription.detail_type.empty?
  event_pattern['source'] = [subscription.source]
  event_pattern['resources'] = [subscription.resource_arn] unless subscription.resource_arn.empty?
  event_pattern['detail'] = subscription.detail unless subscription.detail.empty?

  @template.declare do
    Events_Rule("#{subscription.group}#{subscription.name}#{subscription.hash}"[0..255]) do
      State subscription.enabled ? 'ENABLED' : 'DISABLED'
      Description "Guardian event subscription #{subscription.group} #{subscription.name} for resource #{subscription.resource_id}"
      EventPattern FnSub(event_pattern.to_json)
      Targets [
        {
          Arn: Ref(subscription.topic),
          Id: "#{subscription.topic}Notifier"
        }
      ]
    end
  end
end

#add_metric_filter(filter) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/cfnguardian/stacks/resources.rb', line 115

def add_metric_filter(filter)
  @template.declare do
    Logs_MetricFilter("#{filter.name.gsub(/[^0-9a-zA-Z]/i, '')}#{filter.type}") do
      LogGroupName filter.log_group
      FilterPattern filter.pattern
      MetricTransformations([
        {
          MetricValue: filter.metric_value,
          MetricName: filter.metric_name,
          MetricNamespace: filter.metric_namespace
        }
      ])
    end
  end
end

#build_template(resources) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/cfnguardian/stacks/resources.rb', line 14

def build_template(resources)
  resources.each do |resource|
    case resource.type
    when 'Alarm'
      add_alarm(resource)
    when 'Event'
      add_event(resource)
    when 'Composite'
      add_composite_alarm(resource)
    when 'MetricFilter'
      add_metric_filter(resource)
    when 'EventSubscription'
      add_event_subscription(resource)
    else
      puts "Warn: #{resource.type} is a unsuported resource type"
    end
  end
end