zabbix_export:
  version: '7.0'
  template_groups:
    - uuid: c2c162144c2d4c5491c8801193af4945
      name: Templates/Cloud
  templates:
    - uuid: 7af6d68b223a43d4bf8526cc5dc3fe2e
      template: 'AWS EC2 by HTTP'
      name: 'AWS EC2 by HTTP'
      description: |
        Get AWS EC2 and attached AWS EBS volumes metrics and uses the script item to make HTTP requests to the CloudWatch API.
        Don't forget to read the README.md for the correct setup of the template.
        
        You can discuss this template or leave feedback on our forum https://www.zabbix.com/forum/zabbix-suggestions-and-feedback
        
        Generated by official Zabbix template tool "Templator"
      vendor:
        name: Zabbix
        version: 7.0-0
      groups:
        - name: Templates/Cloud
      items:
        - uuid: 22b61bf7ebba43e8aef544385448d18c
          name: 'Get alarms check'
          type: DEPENDENT
          key: aws.ec2.alarms.check
          value_type: CHAR
          description: 'Check result of the alarm data has been got correctly.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.error
              error_handler: CUSTOM_VALUE
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 3h
          master_item:
            key: aws.ec2.get_alarms
          tags:
            - tag: component
              value: status
          triggers:
            - uuid: 1d017a1213fb4bc9896add10a2b97dd6
              expression: 'length(last(/AWS EC2 by HTTP/aws.ec2.alarms.check))>0'
              name: 'Failed to get alarms data'
              priority: WARNING
              tags:
                - tag: scope
                  value: availability
        - uuid: 0384bacca1e14994a5c38dc55b73e8bb
          name: 'Credit CPU: Balance'
          type: DEPENDENT
          key: aws.ec2.cpu.credit_balance
          value_type: FLOAT
          description: |
            The number of earned CPU credits that an instance has accrued since it was launched or started. For T2 Standard, the CPUCreditBalance also includes the number of launch credits that have been accrued.
            Credits are accrued in the credit balance after they are earned, and removed from the credit balance when they are spent. The credit balance has a maximum limit, determined by the instance size. After the limit is reached, any new credits that are earned are discarded. For T2 Standard, launch credits do not count towards the limit.
            The credits in the CPUCreditBalance are available for the instance to spend to burst beyond its baseline CPU utilization.
            When an instance is running, credits in the CPUCreditBalance do not expire. When a T3 or T3a instance stops, the CPUCreditBalance value persists for seven days. Thereafter, all accrued credits are lost. When a T2 instance stops, the CPUCreditBalance value does not persist, and all accrued credits are lost.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "CPUCreditBalance")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: cpu
            - tag: component
              value: credit
          triggers:
            - uuid: 4e67cac1f58a478fb0e47c52b402fd92
              expression: 'max(/AWS EC2 by HTTP/aws.ec2.cpu.credit_balance,5m)<{$AWS.EC2.CPU.CREDIT.BALANCE.MIN.WARN}'
              name: 'Instance CPU Credit balance is too low'
              event_name: 'Instance CPU Credit balance is too low (less {$AWS.EC2.CPU.CREDIT.BALANCE.MIN.WARN} for 5m)'
              opdata: 'Current value: {ITEM.LASTVALUE1}'
              priority: WARNING
              description: 'The number of earned CPU credits has been less than {$AWS.EC2.CPU.CREDIT.BALANCE.MIN.WARN} in the last 5 minutes.'
              tags:
                - tag: scope
                  value: capacity
        - uuid: b445a56de3194f6f9b4bf9dd85fcbe52
          name: 'Credit CPU: Usage'
          type: DEPENDENT
          key: aws.ec2.cpu.credit_usage
          value_type: FLOAT
          description: |
            The number of CPU credits spent by the instance for CPU utilization.
            One CPU credit equals one vCPU running at 100% utilization for one minute or an equivalent combination of vCPUs, utilization, and time (for example, one vCPU running at 50% utilization for two minutes or two vCPUs running at 25% utilization for two minutes).
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "CPUCreditUsage")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: cpu
            - tag: component
              value: credit
        - uuid: 285ec6451412450c963e3a24d2aa74e1
          name: 'Credit CPU: Surplus balance'
          type: DEPENDENT
          key: aws.ec2.cpu.surplus_credit_balance
          value_type: FLOAT
          description: |
            The number of surplus credits that have been spent by an unlimited instance when its CPUCreditBalance value is zero.
            The CPUSurplusCreditBalance value is paid down by earned CPU credits. If the number of surplus credits exceeds the maximum number of credits that the instance can earn in a 24-hour period, the spent surplus credits above the maximum incur an additional charge.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "CPUSurplusCreditBalance")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: cpu
            - tag: component
              value: credit
        - uuid: 77a32118a77e4836a945c7b0954ef64a
          name: 'Credit CPU: Surplus charged'
          type: DEPENDENT
          key: aws.ec2.cpu.surplus_credit_charged
          value_type: FLOAT
          description: |
            The number of spent surplus credits that are not paid down by earned CPU credits, and which thus incur an additional charge.
            
            Spent surplus credits are charged when any of the following occurs:
            - The spent surplus credits exceed the maximum number of credits that the instance can earn in a 24-hour period. Spent surplus credits above the maximum are charged at the end of the hour;
            - The instance is stopped or terminated;
            - The instance is switched from unlimited to standard.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "CPUSurplusCreditsCharged")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: cpu
            - tag: component
              value: credit
          triggers:
            - uuid: 644ace5510164f329d9af65bd0ed4f34
              expression: 'last(/AWS EC2 by HTTP/aws.ec2.cpu.surplus_credit_charged)>{$AWS.EC2.CPU.CREDIT.SURPLUS.BALANCE.MAX.WARN}'
              name: 'Instance has spent too many CPU surplus credits'
              event_name: 'Instance has spent too many CPU surplus credits (over {$AWS.EC2.CPU.CREDIT.SURPLUS.BALANCE.MAX.WARN} for 15m)'''
              opdata: 'Current value: {ITEM.LASTVALUE1}'
              priority: WARNING
              description: 'The number of spent surplus credits that are not paid down and which thus incur an additional charge is over {$AWS.EC2.CPU.CREDIT.SURPLUS.BALANCE.MAX.WARN}.'
              tags:
                - tag: scope
                  value: capacity
        - uuid: 7fd871e7eed54845ad069c3e7d3cad56
          name: 'CPU: Utilization'
          type: DEPENDENT
          key: aws.ec2.cpu_utilization
          value_type: FLOAT
          units: '%'
          description: |
            The percentage of allocated EC2 compute units that are currently in use on the instance. This metric identifies the processing power required to run an application on a selected instance.
            Depending on the instance type, tools in your operating system can show a lower percentage than CloudWatch when the instance is not allocated a full processor core.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "CPUUtilization")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: cpu
          triggers:
            - uuid: ea74d00067874b609e4846847033058f
              expression: 'min(/AWS EC2 by HTTP/aws.ec2.cpu_utilization,15m)>{$AWS.EC2.CPU.UTIL.WARN.MAX}'
              name: 'High CPU utilization'
              event_name: 'High CPU utilization (over {$AWS.EC2.CPU.UTIL.WARN.MAX}% for 15m)'
              opdata: 'Current utilization: {ITEM.LASTVALUE1}'
              priority: WARNING
              description: 'The CPU utilization is too high. The system might be slow to respond.'
              tags:
                - tag: scope
                  value: capacity
                - tag: scope
                  value: performance
        - uuid: 49aecab5c7df407b9cbfe80ad8790492
          name: 'Disk: Read bytes, rate'
          type: DEPENDENT
          key: aws.ec2.disk.read_bytes.rate
          value_type: FLOAT
          units: Bps
          description: |
            Bytes read from all instance store volumes available to the instance.
            This metric is used to determine the volume of the data the application reads from the hard disk of the instance.
            This can be used to determine the speed of the application.
            If there are no instance store volumes, either the value is 0 or the metric is not reported.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "DiskReadBytes")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: disk
        - uuid: d6bb726f9f1b4d5b889ede0ae2c73613
          name: 'Disk: Read, rate'
          type: DEPENDENT
          key: aws.ec2.disk.read_ops.rate
          value_type: FLOAT
          units: Ops
          description: |
            Completed read operations from all instance store volumes available to the instance in a specified period of time.
            If there are no instance store volumes, either the value is 0 or the metric is not reported.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "DiskReadOps")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: disk
        - uuid: 95bcfd522147498688555e2cab5c00e2
          name: 'Disk: Write bytes, rate'
          type: DEPENDENT
          key: aws.ec2.disk_write_bytes.rate
          value_type: FLOAT
          units: Bps
          description: |
            Bytes written to all instance store volumes available to the instance.
            This metric is used to determine the volume of the data the application writes onto the hard disk of the instance.
            This can be used to determine the speed of the application.
            If there are no instance store volumes, either the value is 0 or the metric is not reported.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "DiskWriteBytes")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: disk
        - uuid: 28496d5aa03742feb85ae000deb616d1
          name: 'Disk: Write ops, rate'
          type: DEPENDENT
          key: aws.ec2.disk_write_ops.rate
          value_type: FLOAT
          units: Ops
          description: |
            Completed write operations to all instance store volumes available to the instance in a specified period of time.
            If there are no instance store volumes, either the value is 0 or the metric is not reported.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "DiskWriteOps")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: disk
        - uuid: 64180ec5dae84f588006bb1dd0ce6980
          name: 'EBS: Byte balance'
          type: DEPENDENT
          key: aws.ec2.ebs.byte_balance
          value_type: FLOAT
          units: '%'
          description: 'Percentage of throughput credits remaining in the burst bucket for Nitro-based instances.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "EBSByteBalance%")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: ebs
          triggers:
            - uuid: 27f3b00e295d4aeb9a2d0519e95da4e0
              expression: 'max(/AWS EC2 by HTTP/aws.ec2.ebs.byte_balance,5m)<{$AWS.EBS.BYTE.CREDIT.BALANCE.MIN.WARN}'
              name: 'Byte Credit balance is too low'
              event_name: 'Byte Credit balance is too low (less {$AWS.EBS.BYTE.CREDIT.BALANCE.MIN.WARN}% for 5m)'
              opdata: 'Current value: {ITEM.LASTVALUE1}'
              priority: WARNING
              tags:
                - tag: scope
                  value: capacity
        - uuid: 7b8a2b6941d04cde8edc511752755c8f
          name: 'EBS: IO balance'
          type: DEPENDENT
          key: aws.ec2.ebs.io_balance
          value_type: FLOAT
          units: '%'
          description: 'Percentage of I/O credits remaining in the burst bucket for Nitro-based instances.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "EBSIOBalance%")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: ebs
          triggers:
            - uuid: f4b9c2238b5443eab31255422bc22d7d
              expression: 'max(/AWS EC2 by HTTP/aws.ec2.ebs.io_balance,5m)<{$AWS.EBS.IO.CREDIT.BALANCE.MIN.WARN}'
              name: 'I/O Credit balance is too low'
              event_name: 'I/O Credit balance is too low (less {$AWS.EBS.IO.CREDIT.BALANCE.MIN.WARN}% for 5m)'
              opdata: 'Current value: {ITEM.LASTVALUE1}'
              priority: WARNING
              tags:
                - tag: scope
                  value: capacity
        - uuid: 251c9a3b0afd4930b822f7310f3fda43
          name: 'EBS: Read bytes, rate'
          type: DEPENDENT
          key: aws.ec2.ebs.read_bytes.rate
          value_type: FLOAT
          units: Bps
          description: 'Bytes read from all EBS volumes attached to the instance for Nitro-based instances.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "EBSReadBytes")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: ebs
        - uuid: 29eff02b7c464605bc6d69a963d232b5
          name: 'EBS: Read, rate'
          type: DEPENDENT
          key: aws.ec2.ebs.read_ops.rate
          value_type: FLOAT
          units: Ops
          description: 'Completed read operations from all Amazon EBS volumes attached to the instance for Nitro-based instances.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "EBSReadOps")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: ebs
        - uuid: 9dafe0bcfb214d46975f570e2836e9cd
          name: 'EBS: Write bytes, rate'
          type: DEPENDENT
          key: aws.ec2.ebs.write_bytes.rate
          value_type: FLOAT
          units: Bps
          description: 'Bytes written to all EBS volumes attached to the instance for Nitro-based instances.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "EBSWriteBytes")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: ebs
        - uuid: 2da28e61261746d6b94b244b8f0cf2a8
          name: 'EBS: Write, rate'
          type: DEPENDENT
          key: aws.ec2.ebs.write_ops.rate
          value_type: FLOAT
          description: 'Completed write operations to all EBS volumes attached to the instance in a specified period of time.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "EBSWriteOps")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: ebs
        - uuid: 4e0b2ed29500487092148b14245839d4
          name: 'Get instance alarms data'
          type: SCRIPT
          key: aws.ec2.get_alarms
          delay: 0s;m/1
          history: '0'
          value_type: TEXT
          params: |
            var AWS = {
            	params: {},
            	metadata: 'http://169.254.169.254/latest/meta-data/iam/security-credentials',
            
            	getField: function (data, path, val) {
            		var steps = path.split('.');
            		for (var i = 0; i < steps.length; i++) {
            			var step = steps[i];
            			if (typeof data !== 'object' || data === null || typeof data[step] === 'undefined') {
            				if (typeof val === 'undefined') {
            					throw 'Required field was not found: ' + path;
            				}
            				return val
            			}
            
            			data = data[step];
            		}
            
            		return data;
            	},
            
            	setParams: function (params) {
            		AWS.params['proxy'] = params.proxy;
            		switch (AWS.getField(params, 'auth_type')) {
            			case 'role_base':
            				AWS.params['auth_type'] = 'role_base';
            				var request = new HttpRequest();
            				if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
            					request.setProxy(AWS.params.proxy);
            				}
            				var IamRoleName = request.get(AWS.metadata);
            
            				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '') {
            					throw 'Error getting security credentials from instance metadata. Role not found.';
            				}
            
            				credentials = request.get(AWS.metadata + '/' + encodeURI(IamRoleName));
            
            				if (request.getStatus() !== 200 || credentials === null || credentials === '') {
            					throw 'Error getting security credentials from instance metadata.';
            				}
            
            				try {
            					credentials = JSON.parse(credentials);
            				}
            				catch (error) {
            					throw 'Failed to parse response received from instance metadata. Check debug log for more information.';
            				}
            
            				['AccessKeyId', 'SecretAccessKey', 'Token'].forEach(function (field) {
            					if (typeof credentials !== 'object' || typeof credentials[field] === 'undefined' || credentials[field] === '') {
            						throw 'Required credentials is not set: "' + field + '".';
            					};
            					AWS.params[field] = credentials[field];
            				});
            				break;
            			case 'access_key':
            			default:
            				AWS.params['auth_type'] = 'access_key';
            				['AccessKeyId', 'SecretAccessKey'].forEach(function (field) {
            					if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
            						throw 'Required param is not set: "' + field + '".';
            					}
            					AWS.params[field] = params[field];
            				});
            		}
            		['region', 'instance_id'].forEach(function (field) {
            			if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
            				throw 'Required param is not set: "' + field + '".';
            			}
            			AWS.params[field] = params[field];
            		});
            	},
            
            	sign: function (key, message) {
            		var hex = hmac('sha256', key, message);
            
            		if ((hex.length % 2) === 1) {
            			throw 'Invalid length of a hex string!';
            		}
            
            		var result = new Int8Array(hex.length / 2);
            		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
            			result[b] = parseInt(hex.substring(i, i + 2), 16);
            		}
            
            		return result;
            	},
            
            	prepareParams: function (params) {
            		var result = [];
            
            		Object.keys(params).sort().forEach(function (key) {
            			if (typeof params[key] !== 'object') {
            				result.push(key + '=' + encodeURIComponent(params[key]));
            			}
            			else {
            				result.push(prepareObject(key, params[key]));
            			}
            		});
            
            		return result.join('&');
            	},
            
            	request: function (method, region, service, params, data) {
            		if (typeof data === 'undefined' || data === null) {
            			data = '';
            		}
            
            		var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''),
            			date = amzdate.replace(/T\d+Z/, ''),
            			host = service + '.' + region + '.amazonaws.com',
            			canonical_uri = '/',
            			canonical_headers = 'content-encoding:amz-1.0\n' + 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n',
            			signed_headers = 'content-encoding;host;x-amz-date',
            			canonical_request = method + '\n' + canonical_uri + '\n' + params + '\n' + canonical_headers + '\n' + signed_headers + '\n' + sha256(data),
            			credential_scope = date + '/' + region + '/' + service + '/' + 'aws4_request',
            			request_string = 'AWS4-HMAC-SHA256' + '\n' + amzdate + '\n' + credential_scope + '\n' + sha256(canonical_request),
            			key = AWS.sign('AWS4' + AWS.params.SecretAccessKey, date);
            
            		key = AWS.sign(key, region);
            		key = AWS.sign(key, service);
            		key = AWS.sign(key, 'aws4_request');
            
            		var request = new HttpRequest(),
            			url = 'https://' + host + canonical_uri + '?' + params;
            
            		if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
            			request.setProxy(AWS.params.proxy);
            		}
            		request.addHeader('x-amz-date: ' + amzdate);
            		request.addHeader('Accept: application/json');
            		request.addHeader('Content-Type: application/json');
            		request.addHeader('Content-Encoding: amz-1.0');
            		request.addHeader('Authorization: ' + 'AWS4-HMAC-SHA256 Credential=' + AWS.params.AccessKeyId + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
            		if (AWS.params.auth_type === 'role_base')
            			request.addHeader('X-Amz-Security-Token: ' + AWS.params.Token);
            
            		Zabbix.log(4, '[ AWS EC2  ] Sending request: ' + url);
            
            		response = request.get(url);
            
            		Zabbix.log(4, '[ AWS EC2 ] Received response with status code ' + request.getStatus() + ': ' + response);
            
            		if (request.getStatus() !== 200) {
            			throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
            		}
            
            		if (response[0] === '<') {
            			try {
            				response = XML.toJson(response);
            			}
            			catch (error) {
            				throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
            			}
            		}
            
            		if (response !== null) {
            			try {
            				response = JSON.parse(response);
            			}
            			catch (error) {
            				throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
            			}
            		}
            
            		return response;
            	},
            
            	getVolumes: function () {
            		var payload = {
            			'Action': 'DescribeVolumes',
            			'Version': '2016-11-15',
            			'MaxResults': 100,
            			'Filter.1.Name': 'attachment.instance-id',
            			'Filter.1.Value': AWS.params.instance_id
            		},
            			value = [],
            			volumes = [],
            			volumes_list = [];
            
            		while (payload.NextToken !== '') {
            			var result = AWS.getField(AWS.request('GET', AWS.params.region, 'ec2', AWS.prepareParams(payload)), 'DescribeVolumesResponse');
            			payload.NextToken = result.nextToken || '';
            			volumes = AWS.getField(result, 'volumeSet.item', value);
            			volumes_list.push(Array.isArray(volumes) ? volumes : [volumes])
            
            		}
            		var flattenedData = volumes_list.reduce(function (acc, val) {
            			return acc.concat(val);
            		}, []);
            		return flattenedData;
            	},
            
            	getAlarms: function () {
            		var payload = {
            			'Action': 'DescribeAlarms',
            			'Version': '2010-08-01',
            			'MaxRecords': 100
            		},
            			result = [],
            			volumes = AWS.getVolumes()
            
            		while (payload.NextToken !== '') {
            			var alarms = AWS.getField(AWS.request('GET', AWS.params.region, 'monitoring', AWS.prepareParams(payload)), 'DescribeAlarmsResponse.DescribeAlarmsResult');
            			payload.NextToken = alarms.NextToken || '';
            			alarms_list = AWS.getField(alarms, 'MetricAlarms');
            
            			if (!Array.isArray(alarms_list))
            				alarms_list = [alarms_list]
            			alarms_list.forEach(function (alarm) {
            				var dimensions = alarm.Dimensions;
            
            				if (Array.isArray(alarm.Metrics)) {
            					alarm.Metrics.forEach(function (metric) {
            						if (typeof metric.MetricStat === 'object' && metric.MetricStat !== null
            							&& typeof metric.MetricStat.Metric === 'object' && metric.MetricStat.Metric !== null
            							&& Array.isArray(metric.MetricStat.Metric.Dimensions)) {
            							dimensions = dimensions.concat(metric.MetricStat.Metric.Dimensions);
            						}
            					});
            				}
            				for (var i in dimensions) {
            					if (dimensions[i].Name === 'InstanceId' && dimensions[i].Value === AWS.params.instance_id) {
            						result.push(alarm);
            						break;
            					}
            					if (dimensions[i].Name === 'VolumeId' && volumes.indexOf(dimensions[i].Value)) {
            						result.push(alarm);
            						break;
            					}
            				}
            			});
            		}
            
            		return result;
            	}
            }
            
            try {
            	AWS.setParams(JSON.parse(value));
            
            	return JSON.stringify(AWS.getAlarms());
            }
            catch (error) {
            	error += (String(error).endsWith('.')) ? '' : '.';
            	Zabbix.log(3, '[ AWS EC2 ] ERROR: ' + error);
            
            	return JSON.stringify({ 'error': error });
            }
          description: 'DescribeAlarms API method: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DescribeAlarms.html'
          preprocessing:
            - type: CHECK_NOT_SUPPORTED
              parameters:
                - '-1'
          timeout: 15s
          parameters:
            - name: AccessKeyId
              value: '{$AWS.ACCESS.KEY.ID}'
            - name: auth_type
              value: '{$AWS.AUTH_TYPE}'
            - name: instance_id
              value: '{$AWS.EC2.INSTANCE.ID}'
            - name: proxy
              value: '{$AWS.PROXY}'
            - name: region
              value: '{$AWS.REGION}'
            - name: SecretAccessKey
              value: '{$AWS.SECRET.ACCESS.KEY}'
          tags:
            - tag: component
              value: raw
        - uuid: 63ab011505f24885b843a9ac48b36a84
          name: 'Get metrics data'
          type: SCRIPT
          key: aws.ec2.get_metrics
          delay: 0s;m/5
          history: '0'
          value_type: TEXT
          params: |
            var AWS = {
            	params: {},
            	request_period: 600,
            	metadata: 'http://169.254.169.254/latest/meta-data/iam/security-credentials',
            
            	getField: function (data, path) {
            		var steps = path.split('.');
            		for (var i = 0; i < steps.length; i++) {
            			var step = steps[i];
            			if (typeof data !== 'object' || typeof data[step] === 'undefined') {
            				throw 'Required field was not found: ' + path;
            			}
            
            			data = data[step];
            		}
            
            		return data;
            	},
            
            	setParams: function (params) {
            		AWS.params['proxy'] = params.proxy;
            		switch (AWS.getField(params, 'auth_type')) {
            			case 'role_base':
            				AWS.params['auth_type'] = 'role_base';
            				var request = new HttpRequest();
            				if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
            					request.setProxy(AWS.params.proxy);
            				}
            				var IamRoleName = request.get(AWS.metadata);
            
            				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '') {
            					throw 'Error getting security credentials from instance metadata. Role not found.';
            				}
            
            				credentials = request.get(AWS.metadata + '/' + encodeURI(IamRoleName));
            
            				if (request.getStatus() !== 200 || credentials === null || credentials === '') {
            					throw 'Error getting security credentials from instance metadata.';
            				}
            
            				try {
            					credentials = JSON.parse(credentials);
            				}
            				catch (error) {
            					throw 'Failed to parse response received from instance metadata. Check debug log for more information.';
            				}
            
            				['AccessKeyId', 'SecretAccessKey', 'Token'].forEach(function (field) {
            					if (typeof credentials !== 'object' || typeof credentials[field] === 'undefined' || credentials[field] === '') {
            						throw 'Required credentials is not set: "' + field + '".';
            					};
            					AWS.params[field] = credentials[field];
            				});
            				break;
            			case 'access_key':
            			default:
            				AWS.params['auth_type'] = 'access_key';
            				['AccessKeyId', 'SecretAccessKey'].forEach(function (field) {
            					if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
            						throw 'Required param is not set: "' + field + '".';
            					}
            					AWS.params[field] = params[field];
            				});
            		}
            		['region', 'instance_id'].forEach(function (field) {
            			if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
            				throw 'Required param is not set: "' + field + '".';
            			}
            			AWS.params[field] = params[field];
            		});
            	},
            
            	sign: function (key, message) {
            		var hex = hmac('sha256', key, message);
            
            		if ((hex.length % 2) === 1) {
            			throw 'Invalid length of a hex string!';
            		}
            
            		var result = new Int8Array(hex.length / 2);
            		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
            			result[b] = parseInt(hex.substring(i, i + 2), 16);
            		}
            
            		return result;
            	},
            
            	prepareRecursive: function (prefix, param) {
            		var result = {};
            
            		if (typeof param === 'object') {
            			if (Array.isArray(param)) {
            				param.forEach(function (value, index) {
            					var nested = AWS.prepareRecursive(prefix + '.member.' + (index + 1), value);
            					Object.keys(nested).forEach(function (key) {
            						result[key] = nested[key];
            					});
            				});
            			}
            			else {
            				Object.keys(param).forEach(function (k) {
            					var nested = AWS.prepareRecursive(prefix + '.' + k, param[k]);
            					Object.keys(nested).forEach(function (key) {
            						result[key] = nested[key];
            					});
            				});
            			}
            		}
            		else {
            			result[prefix] = param;
            		}
            
            		return result;
            	},
            
            	renderPayload: function (period, instance_id) {
            		var metrics_list = [
            			'StatusCheckFailed:Count',
            			'StatusCheckFailed_Instance:Count',
            			'StatusCheckFailed_System:Count',
            			'CPUUtilization:Percent',
            			'NetworkIn:Bytes',
            			'NetworkOut:Bytes',
            			'NetworkPacketsIn:Count',
            			'NetworkPacketsOut:Count',
            			'DiskReadOps:Count',
            			'DiskWriteOps:Count',
            			'DiskReadBytes:Bytes',
            			'DiskWriteBytes:Bytes',
            			'MetadataNoToken:Count',
            			'CPUCreditUsage:Count',
            			'CPUCreditBalance:Count',
            			'CPUSurplusCreditBalance:Count',
            			'CPUSurplusCreditsCharged:Count',
            			'EBSReadOps:Count',
            			'EBSWriteOps:Count',
            			'EBSReadBytes:Bytes',
            			'EBSWriteBytes:Bytes',
            			'EBSIOBalance %:Percent',
            			'EBSByteBalance %:Percent'
            		];
            
            		var metric_payload = [];
            		metrics_list.forEach(function (metric) {
            			var parts = metric.split(':', 2);
            			var name = parts[0].replace(/[^a-zA-Z0-9]/g, '');
            			metric_payload.push({
            				'Id': name.charAt(0).toLowerCase() + name.slice(1),
            				'MetricStat': {
            					'Metric': {
            						'MetricName': parts[0],
            						'Namespace': 'AWS/EC2',
            						'Dimensions': [
            							{
            								'Name': 'InstanceId',
            								'Value': instance_id
            							}
            						]
            					},
            					'Period': period,
            					'Stat': 'Average',
            					'Unit': parts[1]
            				}
            			});
            		});
            
            		return metric_payload;
            	},
            
            	prepareParams: function (params) {
            		var result = [];
            
            		Object.keys(params).sort().forEach(function (key) {
            			if (typeof params[key] !== 'object') {
            				result.push(key + '=' + encodeURIComponent(params[key]));
            			}
            			else {
            				result.push(prepareObject(key, params[key]));
            			}
            		});
            
            		return result.join('&');
            	},
            
            	request: function (method, region, service, params, data) {
            		if (typeof data === 'undefined' || data === null) {
            			data = '';
            		}
            
            		var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''),
            			date = amzdate.replace(/T\d+Z/, ''),
            			host = service + '.' + region + '.amazonaws.com',
            			canonical_uri = '/',
            			canonical_headers = 'content-encoding:amz-1.0\n' + 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n',
            			signed_headers = 'content-encoding;host;x-amz-date',
            			canonical_request = method + '\n' + canonical_uri + '\n' + params + '\n' + canonical_headers + '\n' + signed_headers + '\n' + sha256(data),
            			credential_scope = date + '/' + region + '/' + service + '/' + 'aws4_request',
            			request_string = 'AWS4-HMAC-SHA256' + '\n' + amzdate + '\n' + credential_scope + '\n' + sha256(canonical_request),
            			key = AWS.sign('AWS4' + AWS.params.SecretAccessKey, date);
            
            		key = AWS.sign(key, region);
            		key = AWS.sign(key, service);
            		key = AWS.sign(key, 'aws4_request');
            
            		var request = new HttpRequest(),
            			url = 'https://' + host + canonical_uri + '?' + params;
            
            		if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
            			request.setProxy(AWS.params.proxy);
            		}
            		request.addHeader('x-amz-date: ' + amzdate);
            		request.addHeader('Accept: application/json');
            		request.addHeader('Content-Type: application/json');
            		request.addHeader('Content-Encoding: amz-1.0');
            		request.addHeader('Authorization: ' + 'AWS4-HMAC-SHA256 Credential=' + AWS.params.AccessKeyId + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
            		if (AWS.params.auth_type === 'role_base')
            			request.addHeader('X-Amz-Security-Token: ' + AWS.params.Token);
            
            		Zabbix.log(4, '[ AWS EC2  ] Sending request: ' + url);
            
            		response = request.get(url);
            
            		Zabbix.log(4, '[ AWS EC2 ] Received response with status code ' + request.getStatus() + ': ' + response);
            
            		if (request.getStatus() !== 200) {
            			throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
            		}
            
            		if (response !== null) {
            			try {
            				response = JSON.parse(response);
            			}
            			catch (error) {
            				throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
            			}
            		}
            
            		return response;
            	},
            
            	getMetricsData: function () {
            		var timestamp = new Date().getTime(),
            			end_time = new Date(timestamp).toISOString().replace(/\.\d+Z/, 'Z'),
            			start_time = new Date(timestamp - AWS.request_period * 1000).toISOString().replace(/\.\d+Z/, 'Z'),
            			payload = AWS.prepareRecursive('MetricDataQueries', AWS.renderPayload(AWS.request_period, AWS.params.instance_id));
            
            		payload['Action'] = 'GetMetricData';
            		payload['Version'] = '2010-08-01';
            		payload['StartTime'] = start_time;
            		payload['EndTime'] = end_time;
            		payload['ScanBy'] = 'TimestampDescending';
            
            		result = AWS.request('GET', AWS.params.region, 'monitoring', AWS.prepareParams(payload));
            
            		if (typeof result !== 'object'
            			|| typeof result.GetMetricDataResponse !== 'object'
            			|| typeof result.GetMetricDataResponse.GetMetricDataResult !== 'object'
            			|| typeof result.GetMetricDataResponse.GetMetricDataResult.MetricDataResults !== 'object') {
            			throw 'Cannot get metrics data from AWS CloudWatch API. Check debug log for more information.';
            		}
            
            		return result.GetMetricDataResponse.GetMetricDataResult.MetricDataResults;
            	}
            };
            
            try {
            	AWS.setParams(JSON.parse(value));
            
            	return JSON.stringify(AWS.getMetricsData());
            }
            catch (error) {
            	error += (String(error).endsWith('.')) ? '' : '.';
            	Zabbix.log(3, '[ AWS EC2 ] ERROR: ' + error);
            
            	return JSON.stringify({ 'error': error });
            }
          description: |
            Get instance metrics.
            Full metrics list related to EC2: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html
          preprocessing:
            - type: CHECK_NOT_SUPPORTED
              parameters:
                - '-1'
          timeout: 15s
          parameters:
            - name: AccessKeyId
              value: '{$AWS.ACCESS.KEY.ID}'
            - name: auth_type
              value: '{$AWS.AUTH_TYPE}'
            - name: instance_id
              value: '{$AWS.EC2.INSTANCE.ID}'
            - name: proxy
              value: '{$AWS.PROXY}'
            - name: region
              value: '{$AWS.REGION}'
            - name: SecretAccessKey
              value: '{$AWS.SECRET.ACCESS.KEY}'
          tags:
            - tag: component
              value: raw
        - uuid: 9ec4650b564c41bca9893eca279a8cc7
          name: 'Get volumes data'
          type: SCRIPT
          key: aws.ec2.get_volumes
          delay: 5m
          history: '0'
          value_type: TEXT
          params: |
            var AWS = {
            	params: {},
            	request_period: 600,
            	metadata: 'http://169.254.169.254/latest/meta-data/iam/security-credentials',
            
            	getField: function (data, path, val) {
            		var steps = path.split('.');
            		for (var i = 0; i < steps.length; i++) {
            			var step = steps[i];
            			if (typeof data !== 'object' || data === null || typeof data[step] === 'undefined') {
            				if (typeof val === 'undefined') {
            					throw 'Required field was not found: ' + path;
            				}
            				return val
            			}
            			data = data[step];
            		}
            
            		return data;
            	},
            
            	setParams: function (params) {
            		AWS.params['proxy'] = params.proxy;
            		switch (AWS.getField(params, 'auth_type')) {
            			case 'role_base':
            				AWS.params['auth_type'] = 'role_base';
            				var request = new HttpRequest();
            				if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
            					request.setProxy(AWS.params.proxy);
            				}
            				var IamRoleName = request.get(AWS.metadata);
            
            				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '') {
            					throw 'Error getting security credentials from instance metadata. Role not found.';
            				}
            
            				credentials = request.get(AWS.metadata + '/' + encodeURI(IamRoleName));
            
            				if (request.getStatus() !== 200 || credentials === null || credentials === '') {
            					throw 'Error getting security credentials from instance metadata.';
            				}
            
            				try {
            					credentials = JSON.parse(credentials);
            				}
            				catch (error) {
            					throw 'Failed to parse response received from instance metadata. Check debug log for more information.';
            				}
            
            				['AccessKeyId', 'SecretAccessKey', 'Token'].forEach(function (field) {
            					if (typeof credentials !== 'object' || typeof credentials[field] === 'undefined' || credentials[field] === '') {
            						throw 'Required credentials is not set: "' + field + '".';
            					};
            					AWS.params[field] = credentials[field];
            				});
            				break;
            			case 'access_key':
            			default:
            				AWS.params['auth_type'] = 'access_key';
            				['AccessKeyId', 'SecretAccessKey'].forEach(function (field) {
            					if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
            						throw 'Required param is not set: "' + field + '".';
            					}
            					AWS.params[field] = params[field];
            				});
            		}
            		['region', 'instance_id'].forEach(function (field) {
            			if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
            				throw 'Required param is not set: "' + field + '".';
            			}
            			AWS.params[field] = params[field];
            		});
            	},
            
            	sign: function (key, message) {
            		var hex = hmac('sha256', key, message);
            
            		if ((hex.length % 2) === 1) {
            			throw 'Invalid length of a hex string!';
            		}
            
            		var result = new Int8Array(hex.length / 2);
            		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
            			result[b] = parseInt(hex.substring(i, i + 2), 16);
            		}
            
            		return result;
            	},
            
            	prepareParams: function (params) {
            		var result = [];
            
            		Object.keys(params).sort().forEach(function (key) {
            			if (typeof params[key] !== 'object') {
            				result.push(key + '=' + encodeURIComponent(params[key]));
            			}
            			else {
            				result.push(prepareObject(key, params[key]));
            			}
            		});
            
            		return result.join('&');
            	},
            
            	request: function (method, region, service, params, data) {
            		if (typeof data === 'undefined' || data === null) {
            			data = '';
            		}
            
            		var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''),
            			date = amzdate.replace(/T\d+Z/, ''),
            			host = service + '.' + region + '.amazonaws.com',
            			canonical_uri = '/',
            			canonical_headers = 'content-encoding:amz-1.0\n' + 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n',
            			signed_headers = 'content-encoding;host;x-amz-date',
            			canonical_request = method + '\n' + canonical_uri + '\n' + params + '\n' + canonical_headers + '\n' + signed_headers + '\n' + sha256(data),
            			credential_scope = date + '/' + region + '/' + service + '/' + 'aws4_request',
            			request_string = 'AWS4-HMAC-SHA256' + '\n' + amzdate + '\n' + credential_scope + '\n' + sha256(canonical_request),
            			key = AWS.sign('AWS4' + AWS.params.SecretAccessKey, date);
            
            		key = AWS.sign(key, region);
            		key = AWS.sign(key, service);
            		key = AWS.sign(key, 'aws4_request');
            
            		var request = new HttpRequest(),
            			url = 'https://' + host + canonical_uri + '?' + params;
            
            		if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
            			request.setProxy(AWS.params.proxy);
            		}
            		request.addHeader('x-amz-date: ' + amzdate);
            		request.addHeader('Accept: application/json');
            		request.addHeader('Content-Type: application/json');
            		request.addHeader('Content-Encoding: amz-1.0');
            		request.addHeader('Authorization: ' + 'AWS4-HMAC-SHA256 Credential=' + AWS.params.AccessKeyId + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
            		if (AWS.params.auth_type === 'role_base')
            			request.addHeader('X-Amz-Security-Token: ' + AWS.params.Token);
            
            		Zabbix.log(4, '[ AWS EBS ] Sending request: ' + url);
            
            		response = request.get(url);
            
            		Zabbix.log(4, '[ AWS EBS ] Received response with status code ' + request.getStatus() + ': ' + response);
            
            		if (request.getStatus() !== 200) {
            			throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
            		}
            
            		if (response !== null) {
            			try {
            				response = XML.toJson(response);
            			}
            			catch (error) {
            				throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
            			}
            		}
            		response = JSON.parse(response)
            
            		return response;
            	},
            
            	getVolumesData: function () {
            		var payload = {
            			'Action': 'DescribeVolumes',
            			'Version': '2016-11-15',
            			'Filter.1.Name': 'attachment.instance-id',
            			'Filter.1.Value': AWS.params.instance_id,
            			'MaxResults': 100
            		},
            			value = [],
            			volumes_list = [];
            
            		while (payload.NextToken !== '') {
            			var result = AWS.getField(AWS.request('GET', AWS.params.region, 'ec2', AWS.prepareParams(payload)), 'DescribeVolumesResponse'),
            				volumes_set = AWS.getField(result, 'volumeSet'),
            				volumes = AWS.getField(volumes_set, 'item', value);
            			volumes_list.push(Array.isArray(volumes) ? volumes : [volumes]);
            			payload.NextToken = result.nextToken || '';
            		}
            		var flattenedData = volumes_list.reduce(function (acc, val) {
            			return acc.concat(val);
            		}, []);
            		return flattenedData;
            	}
            };
            
            try {
            	AWS.setParams(JSON.parse(value));
            
            	return JSON.stringify(AWS.getVolumesData());
            }
            catch (error) {
            	error += (String(error).endsWith('.')) ? '' : '.';
            	Zabbix.log(3, '[ AWS EBS ] ERROR: ' + error);
            
            	return JSON.stringify({ 'error': error });
            }
          description: |
            Get volumes attached to instance.
            DescribeVolumes API method: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVolumes.html
          preprocessing:
            - type: CHECK_NOT_SUPPORTED
              parameters:
                - '-1'
          timeout: 15s
          parameters:
            - name: AccessKeyId
              value: '{$AWS.ACCESS.KEY.ID}'
            - name: auth_type
              value: '{$AWS.AUTH_TYPE}'
            - name: instance_id
              value: '{$AWS.EC2.INSTANCE.ID}'
            - name: proxy
              value: '{$AWS.PROXY}'
            - name: region
              value: '{$AWS.REGION}'
            - name: SecretAccessKey
              value: '{$AWS.SECRET.ACCESS.KEY}'
          tags:
            - tag: component
              value: raw
        - uuid: adbe9cd98ffa41dda981c7f4e27a0d3b
          name: 'Metadata: No token'
          type: DEPENDENT
          key: aws.ec2.metadata.no_token
          value_type: FLOAT
          description: |
            The number of times the instance metadata service was successfully accessed using a method that does not use a token.
            This metric is used to determine if there are any processes accessing instance metadata that are using Instance Metadata Service Version 1, which does not use a token.
            If all requests use token-backed sessions, i.e., Instance Metadata Service Version 2, the value is 0.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "MetadataNoToken")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: metadata
        - uuid: 7c264d8d5d934f898f7c745acd429d25
          name: 'Get metrics check'
          type: DEPENDENT
          key: aws.ec2.metrics.check
          value_type: CHAR
          description: 'Check result of the instance metric data has been got correctly.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.error
              error_handler: CUSTOM_VALUE
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 3h
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: status
          triggers:
            - uuid: c2cf3f875aa14416a108dd05df7b053a
              expression: 'length(last(/AWS EC2 by HTTP/aws.ec2.metrics.check))>0'
              name: 'Failed to get metrics data'
              priority: WARNING
              tags:
                - tag: scope
                  value: availability
        - uuid: 2b16d3c6457842d892d06249a5fcd670
          name: 'Network: Bytes in, rate'
          type: DEPENDENT
          key: aws.ec2.network_in.rate
          value_type: FLOAT
          units: Bps
          description: |
            The number of bytes received on all network interfaces by the instance.
            This metric identifies the volume of incoming network traffic to a single instance.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "NetworkIn")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: network
        - uuid: 87fb8b61f115487696f02e50d98996ac
          name: 'Network: Bytes out, rate'
          type: DEPENDENT
          key: aws.ec2.network_out.rate
          value_type: FLOAT
          units: Bps
          description: |
            The number of bytes sent out on all network interfaces by the instance. 
            This metric identifies the volume of outgoing network traffic from a single instance.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "NetworkOut")].Values.first().first()'
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: network
        - uuid: a6b74493528b486782c4b73e080019e1
          name: 'Network: Packets in, rate'
          type: DEPENDENT
          key: aws.ec2.packets_in.rate
          value_type: FLOAT
          description: |
            The number of packets received on all network interfaces by the instance.
            This metric identifies the volume of incoming traffic in terms of the number of packets on a single instance.
            This metric is available for basic monitoring only.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "NetworkPacketsIn")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: network
        - uuid: 5d998e1680af4410b34fa9071bb7db78
          name: 'Network: Packets out, rate'
          type: DEPENDENT
          key: aws.ec2.packets_out.rate
          value_type: FLOAT
          description: |
            The number of packets sent out on all network interfaces by the instance.
            This metric identifies the volume of outgoing traffic in terms of the number of packets on a single instance.
            This metric is available for basic monitoring only.
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "NetworkPacketsOut")].Values.first().first()'
              error_handler: DISCARD_VALUE
            - type: JAVASCRIPT
              parameters:
                - 'return value / 300;'
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: network
        - uuid: 30156f76599147eaa5bcd4ca39816bbb
          name: 'Status: Check failed'
          type: DEPENDENT
          key: aws.ec2.status_check_failed
          description: |
            Reports whether the instance has passed both the instance status check and the system status check in the last minute.
            This metric can be either 0 (passed) or 1 (failed).
          valuemap:
            name: 'Status check'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "StatusCheckFailed")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: instance
        - uuid: b373f0994e784caf8f5f39da20d2f5c8
          name: 'Status: Check failed, instance'
          type: DEPENDENT
          key: aws.ec2.status_check_failed_instance
          description: |
            Reports whether the instance has passed the instance status check in the last minute.
            This metric can be either 0 (passed) or 1 (failed).
          valuemap:
            name: 'Status check'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "StatusCheckFailed_Instance")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: instance
          triggers:
            - uuid: 0fdd6b02eea948d3a6c958af7f195dc3
              expression: 'last(/AWS EC2 by HTTP/aws.ec2.status_check_failed_instance)=1'
              name: 'Instance status check failed'
              priority: AVERAGE
              description: |
                These checks detect problems that require your involvement to repair.
                The following are examples of problems that can cause instance status checks to fail:
                
                Failed system status checks
                Incorrect networking or startup configuration
                Exhausted memory
                Corrupted file system
                Incompatible kernel
              tags:
                - tag: scope
                  value: availability
        - uuid: c7063824e3a74e6fa55ba21ecba35ca1
          name: 'Status: Check failed, system'
          type: DEPENDENT
          key: aws.ec2.status_check_failed_system
          description: |
            Reports whether the instance has passed the system status check in the last minute.
            This metric can be either 0 (passed) or 1 (failed).
          valuemap:
            name: 'Status check'
          preprocessing:
            - type: JSONPATH
              parameters:
                - '$.[?(@.Label == "StatusCheckFailed_System")].Values.first().first()'
              error_handler: DISCARD_VALUE
          master_item:
            key: aws.ec2.get_metrics
          tags:
            - tag: component
              value: instance
          triggers:
            - uuid: 723a254ffd72404ea0cc2366ff186c1c
              expression: 'last(/AWS EC2 by HTTP/aws.ec2.status_check_failed_system)=1'
              name: 'System status check failed'
              priority: AVERAGE
              description: |
                These checks detect underlying problems with your instance that require AWS involvement to repair.
                The following are examples of problems that can cause system status checks to fail:
                
                Loss of network connectivity
                Loss of system power
                Software issues on the physical host
                Hardware issues on the physical host that impact network reachability
              tags:
                - tag: scope
                  value: availability
        - uuid: 3c819ed899c044ae8455266292f65632
          name: 'Get volumes info check'
          type: DEPENDENT
          key: aws.ec2.volumes.check
          value_type: CHAR
          description: 'Check result of the volume information has been got correctly.'
          preprocessing:
            - type: JSONPATH
              parameters:
                - $.error
              error_handler: CUSTOM_VALUE
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 3h
          master_item:
            key: aws.ec2.get_volumes
          tags:
            - tag: component
              value: status
          triggers:
            - uuid: 844fb22685804fe7894af7c64b420824
              expression: 'length(last(/AWS EC2 by HTTP/aws.ec2.volumes.check))>0'
              name: 'Failed to get volumes info'
              priority: WARNING
              tags:
                - tag: scope
                  value: availability
      discovery_rules:
        - uuid: 318c50196d2b442e9b702f63e70c0820
          name: 'Instance Alarms discovery'
          type: DEPENDENT
          key: aws.ec2.alarms.discovery
          filter:
            evaltype: AND
            conditions:
              - macro: '{#ALARM_NAME}'
                value: '{$AWS.EC2.LLD.FILTER.ALARM_NAME.MATCHES}'
              - macro: '{#ALARM_NAME}'
                value: '{$AWS.EC2.LLD.FILTER.ALARM_NAME.NOT_MATCHES}'
                operator: NOT_MATCHES_REGEX
              - macro: '{#ALARM_SERVICE_NAMESPACE}'
                value: '{$AWS.EC2.LLD.FILTER.ALARM_SERVICE_NAMESPACE.MATCHES}'
              - macro: '{#ALARM_SERVICE_NAMESPACE}'
                value: '{$AWS.EC2.LLD.FILTER.ALARM_SERVICE_NAMESPACE.NOT_MATCHES}'
                operator: NOT_MATCHES_REGEX
          description: 'Discovery instance and attached EBS volumes alarms.'
          item_prototypes:
            - uuid: 6294e05dc170431bb3af2caf1ccf6d40
              name: '[{#ALARM_NAME}]: Get metrics'
              type: DEPENDENT
              key: 'aws.ec2.alarm.get_metrics["{#ALARM_NAME}"]'
              history: '0'
              value_type: TEXT
              description: 'Get alarm metrics about the state and its reason.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.AlarmName == "{#ALARM_NAME}")].first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: aws.ec2.get_alarms
              tags:
                - tag: component
                  value: raw
            - uuid: 87a163166aed40b786785b64122ab365
              name: '[{#ALARM_NAME}]: State'
              type: DEPENDENT
              key: 'aws.ec2.alarm.state["{#ALARM_NAME}"]'
              description: |
                The state value for the alarm. Possible values: 0 (OK), 1 (INSUFFICIENT_DATA), 2 (ALARM).
                Alarm description:
                {#ALARM_DESCRIPTION}
              valuemap:
                name: 'Alarm state'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.StateValue
                  error_handler: CUSTOM_VALUE
                  error_handler_params: '3'
                - type: JAVASCRIPT
                  parameters:
                    - |
                      var state = ['OK', 'INSUFFICIENT_DATA', 'ALARM'];
                      
                      return state.indexOf(value.trim()) === -1 ? 255 : state.indexOf(value.trim());
              master_item:
                key: 'aws.ec2.alarm.get_metrics["{#ALARM_NAME}"]'
              tags:
                - tag: component
                  value: alarms
              trigger_prototypes:
                - uuid: be1301d97b5a47cc81dd6c2b76349f5d
                  expression: 'last(/AWS EC2 by HTTP/aws.ec2.alarm.state["{#ALARM_NAME}"])=1'
                  name: '[{#ALARM_NAME}] has ''Insufficient data'' state'
                  priority: INFO
                  tags:
                    - tag: scope
                      value: notice
            - uuid: 92a33b49f010464db7e6c7ef586240e9
              name: '[{#ALARM_NAME}]: State reason'
              type: DEPENDENT
              key: 'aws.ec2.alarm.state_reason["{#ALARM_NAME}"]'
              value_type: TEXT
              description: |
                An explanation for the alarm state, in text format.
                Alarm description:
                {#ALARM_DESCRIPTION}
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.StateReason
                  error_handler: DISCARD_VALUE
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 3h
              master_item:
                key: 'aws.ec2.alarm.get_metrics["{#ALARM_NAME}"]'
              tags:
                - tag: component
                  value: alarms
          trigger_prototypes:
            - uuid: 93813bd6aaf14fcb84068cb2c2e5d47e
              expression: 'last(/AWS EC2 by HTTP/aws.ec2.alarm.state["{#ALARM_NAME}"])=2 and length(last(/AWS EC2 by HTTP/aws.ec2.alarm.state_reason["{#ALARM_NAME}"]))>0'
              name: '[{#ALARM_NAME}] has ''Alarm'' state'
              priority: AVERAGE
              description: |
                Alarm "{#ALARM_NAME}" has 'Alarm' state. 
                Reason: {ITEM.LASTVALUE2}
              tags:
                - tag: scope
                  value: availability
          master_item:
            key: aws.ec2.get_alarms
          preprocessing:
            - type: JAVASCRIPT
              parameters:
                - |
                  var result = [];
                  var alarms = JSON.parse(value);
                  
                  alarms.forEach(function(alarm) {
                  
                   result.push({
                  '{#ALARM_DESCRIPTION}': alarm.AlarmDescription !== null ? alarm.AlarmDescription : 'None' ,
                  '{#ALARM_NAME}': alarm.AlarmName,
                  '{#ALARM_PERIOD}': alarm.Period,
                  '{#METRIC_NAME}': alarm.MetricName,
                  '{#ALARM_SERVICE_NAMESPACE}': alarm.Namespace !== null ? alarm.Namespace : 'None'
                    });
                  });
                  
                  return JSON.stringify(result);
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 3h
        - uuid: 6cf7fc98fea44b0789a5aaa837042699
          name: 'Instance Volumes discovery'
          type: DEPENDENT
          key: aws.ec2.volumes.discovery
          filter:
            evaltype: AND
            conditions:
              - macro: '{#VOLUME_TYPE}'
                value: '{$AWS.EC2.LLD.FILTER.VOLUME_TYPE.MATCHES}'
              - macro: '{#VOLUME_TYPE}'
                value: '{$AWS.EC2.LLD.FILTER.VOLUME_TYPE.NOT_MATCHES}'
                operator: NOT_MATCHES_REGEX
          description: 'Discovery attached EBS volumes.'
          item_prototypes:
            - uuid: cc0ece769d954bb590fb1a1a3d20e559
              name: '[{#VOLUME_ID}]: Attachment state'
              type: DEPENDENT
              key: 'aws.ec2.ebs.attachment_status["{#VOLUME_ID}"]'
              description: 'The attachment state of the volume. Possible values: 0 (attaching), 1 (attached), 2 (detaching).'
              valuemap:
                name: 'Volume attachment state'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.attachmentSet..[?(@.instanceId == "{$AWS.EC2.INSTANCE.ID}")].status.first()'
                  error_handler: DISCARD_VALUE
                - type: JAVASCRIPT
                  parameters:
                    - |
                      var state = ['attaching', 'attached', 'detaching'];
                      
                      return state.indexOf(value.trim()) === -1 ? 255 : state.indexOf(value.trim());
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 3h
              master_item:
                key: 'aws.ec2.ebs.get_volume["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 639e7ddcac6345239fa27549ad35e799
              name: '[{#VOLUME_ID}]: Attachment time'
              type: DEPENDENT
              key: 'aws.ec2.ebs.attachment_time["{#VOLUME_ID}"]'
              value_type: CHAR
              description: 'The time stamp when the attachment initiated.'
              valuemap:
                name: 'Volume attachment state'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.attachmentSet..[?(@.instanceId == "{$AWS.EC2.INSTANCE.ID}")].attachTime.first()'
                  error_handler: DISCARD_VALUE
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 3h
              master_item:
                key: 'aws.ec2.ebs.get_volume["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 2df96e6c726e40c6a257c00ae26e8902
              name: '[{#VOLUME_ID}]: Create time'
              type: DEPENDENT
              key: 'aws.ec2.ebs.create_time["{#VOLUME_ID}"]'
              value_type: CHAR
              description: 'The time stamp when volume creation was initiated.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.createTime
                  error_handler: DISCARD_VALUE
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 3h
              master_item:
                key: 'aws.ec2.ebs.get_volume["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 141205eac3e4437d824794f8e6c76e90
              name: '[{#VOLUME_ID}]: Device'
              type: DEPENDENT
              key: 'aws.ec2.ebs.device["{#VOLUME_ID}"]'
              value_type: CHAR
              description: 'The device name specified in the block device mapping (for example, /dev/sda1).'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.attachmentSet..[?(@.instanceId == "{$AWS.EC2.INSTANCE.ID}")].device.first()'
                  error_handler: DISCARD_VALUE
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 3h
              master_item:
                key: 'aws.ec2.ebs.get_volume["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 6145bf692ea0469eb5583485b6622a59
              name: '[{#VOLUME_ID}]: Get volume data'
              type: DEPENDENT
              key: 'aws.ec2.ebs.get_volume["{#VOLUME_ID}"]'
              history: '0'
              value_type: TEXT
              description: 'Get data of the "{#VOLUME_ID}" volume.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.volumeId == "{#VOLUME_ID}")].first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: aws.ec2.get_volumes
              tags:
                - tag: component
                  value: raw
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 95add92252e24ab8b596c539d8090f3d
              name: '[{#VOLUME_ID}]: Status'
              type: DEPENDENT
              key: 'aws.ec2.ebs.status["{#VOLUME_ID}"]'
              description: |
                The state of the volume.
                Possible values: 0 (creating), 1 (available), 2 (in-use), 3 (deleting), 4 (deleted), 5 (error).
              valuemap:
                name: 'Volume status'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - $.status
                  error_handler: DISCARD_VALUE
                - type: JAVASCRIPT
                  parameters:
                    - |
                      var state = ['creating', 'available', 'in-use', 'deleting', 'deleted', 'error'];
                      
                      return state.indexOf(value.trim()) === -1 ? 255 : state.indexOf(value.trim());
                - type: DISCARD_UNCHANGED_HEARTBEAT
                  parameters:
                    - 3h
              master_item:
                key: 'aws.ec2.ebs.get_volume["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
              trigger_prototypes:
                - uuid: 2d4de438bdaa49b2930496ce6ddbe52d
                  expression: 'last(/AWS EC2 by HTTP/aws.ec2.ebs.status["{#VOLUME_ID}"])=5'
                  name: 'Volume [{#VOLUME_ID}] has ''error'' state'
                  priority: WARNING
                  tags:
                    - tag: scope
                      value: availability
            - uuid: fd10966f674e430a9dd70b148dcfa002
              name: '[{#VOLUME_ID}]: Burst balance'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.burst_balance["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: '%'
              description: |
                Used with General Purpose SSD (gp2), Throughput Optimized HDD (st1), and Cold HDD (sc1) volumes only.
                Provides information about the percentage of I/O credits (for gp2) or throughput credits (for st1 and sc1) remaining in the burst bucket. 
                Data is reported to CloudWatch only when the volume is active. If the volume is not attached, no data is reported.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "BurstBalance")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
              trigger_prototypes:
                - uuid: 9b2f5687020c4a5987c1b1b35a57d8b9
                  expression: 'max(/AWS EC2 by HTTP/aws.ec2.ebs.volume.burst_balance["{#VOLUME_ID}"],5m)<{$AWS.EBS.BURST.CREDIT.BALANCE.MIN.WARN}'
                  name: 'Burst balance is too low'
                  event_name: 'Burst balance is too low (less {$AWS.EBS.BURST.CREDIT.BALANCE.MIN.WARN}% for 5m)'
                  opdata: 'Current value: {ITEM.LASTVALUE1}'
                  priority: WARNING
                  tags:
                    - tag: scope
                      value: capacity
            - uuid: 8b936cef38294799a6826764eae68850
              name: '[{#VOLUME_ID}]: Consumed Read/Write, ops'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.consumed_read_write_ops["{#VOLUME_ID}"]'
              value_type: FLOAT
              description: |
                Used with Provisioned IOPS SSD volumes only.
                The total amount of read and write operations (normalized to 256K capacity units) consumed in a specified period of time.
                I/O operations that are smaller than 256K each count as 1 consumed IOPS. I/O operations that are larger than 256K are counted in 256K capacity units. 
                For example, a 1024K I/O would count as 4 consumed IOPS.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeConsumedReadWriteOps")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 5476d32c036d49588238cb2d2a4d652f
              name: '[{#VOLUME_ID}]: Idle time'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.idle_time["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: s
              description: |
                This metric is not supported with Multi-Attach enabled volumes.
                The total number of seconds in a specified period of time when no read or write operations were submitted.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeIdleTime")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 4dbb00e53cd84b9f88c44c765e73bd85
              name: '[{#VOLUME_ID}]: Queue length'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.queue_length["{#VOLUME_ID}"]'
              value_type: FLOAT
              description: 'The number of read and write operation requests waiting to be completed in a specified period of time.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeQueueLength")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 7313a503be27469ea82733ed965b57e4
              name: '[{#VOLUME_ID}]: Read, bytes'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.read_bytes["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: Bps
              description: |
                Provides information on the read operations in a specified period of time.
                The average size of each read operation during the period, except on volumes attached to a Nitro-based instance, where the average represents the average over the specified period.
                For Xen instances, data is reported only when there is read activity on the volume.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeReadBytes")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 13d3dce70956402c945421c87e8eb784
              name: '[{#VOLUME_ID}]: Read, ops'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.read_ops["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: Ops
              description: 'The total number of read operations in a specified period of time. Note: read operations are counted on completion.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeReadOps")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 8d0b610ac0e3479a921720ef623ef896
              name: '[{#VOLUME_ID}]: Throughput, pct'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.throughput_percentage["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: '%'
              description: |
                This metric is not supported with Multi-Attach enabled volumes.
                Used with Provisioned IOPS SSD volumes only. The percentage of I/O operations per second (IOPS) delivered of the total IOPS provisioned for an Amazon EBS volume.
                Provisioned IOPS SSD volumes deliver their provisioned performance 99.9 percent of the time.
                During a write, if there are no other pending I/O requests in a minute, the metric value will be 100 percent.
                Also, a volume's I/O performance may become degraded temporarily due to an action you have taken (for example, creating a snapshot of a volume during peak usage, running the volume on a non-EBS-optimized instance, or accessing data on the volume for the first time).
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeThroughputPercentage")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 58163c98e1b943ceae5fcb52ff85dcfd
              name: '[{#VOLUME_ID}]: Read time, total'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.total_read_time["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: s
              description: |
                This metric is not supported with Multi-Attach enabled volumes.
                The total number of seconds spent by all read operations that completed in a specified period of time.
                If multiple requests are submitted at the same time, this total could be greater than the length of the period. 
                For example, for a period of 1 minutes (60 seconds): if 150 operations completed during that period, and each operation took 1 second, the value would be 150 seconds. 
                For Xen instances, data is reported only when there is read activity on the volume.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeTotalReadTime")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 264a8f7df9e64d219082d5239b90cdf3
              name: '[{#VOLUME_ID}]: Write time, total'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.total_write_time["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: s
              description: |
                This metric is not supported with Multi-Attach enabled volumes.
                The total number of seconds spent by all write operations that completed in a specified period of time.
                If multiple requests are submitted at the same time, this total could be greater than the length of the period.
                For example, for a period of 1 minute (60 seconds): if 150 operations completed during that period, and each operation took 1 second, the value would be 150 seconds. 
                For Xen instances, data is reported only when there is write activity on the volume.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeTotalWriteTime")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 459900740e784ca9ba7a8baf5b95734e
              name: '[{#VOLUME_ID}]: Write, bytes'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.write_bytes["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: Bps
              description: |
                Provides information on the write operations in a specified period of time.
                The average size of each write operation during the period, except on volumes attached to a Nitro-based instance, where the average represents the average over the specified period.
                For Xen instances, data is reported only when there is write activity on the volume.
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeWriteBytes")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 7216494987dc45f59fc3a4b9100e4159
              name: '[{#VOLUME_ID}]: Write, ops'
              type: DEPENDENT
              key: 'aws.ec2.ebs.volume.write_ops["{#VOLUME_ID}"]'
              value_type: FLOAT
              units: Ops
              description: 'The total number of write operations in a specified period of time. Note: write operations are counted on completion.'
              preprocessing:
                - type: JSONPATH
                  parameters:
                    - '$.[?(@.Label == "VolumeWriteOps")].Values.first().first()'
                  error_handler: DISCARD_VALUE
              master_item:
                key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              tags:
                - tag: component
                  value: volumes
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
            - uuid: 8b3b008f7f65408fbd49e46186b01cfb
              name: '[{#VOLUME_ID}]: Get metrics'
              type: SCRIPT
              key: 'aws.ec2.get_ebs_metrics["{#VOLUME_ID}"]'
              delay: 0s;m/5
              history: '0'
              value_type: TEXT
              params: |
                var AWS = {
                	params: {},
                	request_period: 600,
                	metadata: 'http://169.254.169.254/latest/meta-data/iam/security-credentials',
                
                	getField: function (data, path) {
                		var steps = path.split('.');
                		for (var i = 0; i < steps.length; i++) {
                			var step = steps[i];
                			if (typeof data !== 'object' || typeof data[step] === 'undefined') {
                				throw 'Required field was not found: ' + path;
                			}
                
                			data = data[step];
                		}
                
                		return data;
                	},
                
                	setParams: function (params) {
                		AWS.params['proxy'] = params.proxy;
                		switch (AWS.getField(params, 'auth_type')) {
                			case 'role_base':
                				AWS.params['auth_type'] = 'role_base';
                				var request = new HttpRequest();
                				if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
                					request.setProxy(AWS.params.proxy);
                				}
                				var IamRoleName = request.get(AWS.metadata);
                
                				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '') {
                					throw 'Error getting security credentials from instance metadata. Role not found.';
                				}
                
                				credentials = request.get(AWS.metadata + '/' + encodeURI(IamRoleName));
                
                				if (request.getStatus() !== 200 || credentials === null || credentials === '') {
                					throw 'Error getting security credentials from instance metadata.';
                				}
                
                				try {
                					credentials = JSON.parse(credentials);
                				}
                				catch (error) {
                					throw 'Failed to parse response received from instance metadata. Check debug log for more information.';
                				}
                
                				['AccessKeyId', 'SecretAccessKey', 'Token'].forEach(function (field) {
                					if (typeof credentials !== 'object' || typeof credentials[field] === 'undefined' || credentials[field] === '') {
                						throw 'Required credentials is not set: "' + field + '".';
                					};
                					AWS.params[field] = credentials[field];
                				});
                				break;
                			case 'access_key':
                			default:
                				AWS.params['auth_type'] = 'access_key';
                				['AccessKeyId', 'SecretAccessKey'].forEach(function (field) {
                					if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
                						throw 'Required param is not set: "' + field + '".';
                					}
                					AWS.params[field] = params[field];
                				});
                		}
                		['region', 'volume_id'].forEach(function (field) {
                			if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
                				throw 'Required param is not set: "' + field + '".';
                			}
                			AWS.params[field] = params[field];
                		});
                	},
                
                
                	sign: function (key, message) {
                		var hex = hmac('sha256', key, message);
                
                		if ((hex.length % 2) === 1) {
                			throw 'Invalid length of a hex string!';
                		}
                
                		var result = new Int8Array(hex.length / 2);
                		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
                			result[b] = parseInt(hex.substring(i, i + 2), 16);
                		}
                
                		return result;
                	},
                
                	prepareRecursive: function (prefix, param) {
                		var result = {};
                
                		if (typeof param === 'object') {
                			if (Array.isArray(param)) {
                				param.forEach(function (value, index) {
                					var nested = AWS.prepareRecursive(prefix + '.member.' + (index + 1), value);
                					Object.keys(nested).forEach(function (key) {
                						result[key] = nested[key];
                					});
                				});
                			}
                			else {
                				Object.keys(param).forEach(function (k) {
                					var nested = AWS.prepareRecursive(prefix + '.' + k, param[k]);
                					Object.keys(nested).forEach(function (key) {
                						result[key] = nested[key];
                					});
                				});
                			}
                		}
                		else {
                			result[prefix] = param;
                		}
                
                		return result;
                	},
                
                	renderPayload: function (period, volume_id) {
                		var metrics_list = [
                			'VolumeReadBytes:Bytes',
                			'VolumeWriteBytes:Bytes',
                			'VolumeReadOps:Count',
                			'VolumeWriteOps:Count',
                			'VolumeTotalReadTime:Seconds',
                			'VolumeTotalWriteTime:Seconds',
                			'VolumeIdleTime:Seconds',
                			'VolumeQueueLength:Count',
                			'VolumeThroughputPercentage:Percent',
                			'VolumeConsumedReadWriteOps:Count',
                			'BurstBalance:Percent'
                		];
                
                		var metric_payload = [];
                		metrics_list.forEach(function (metric) {
                			var parts = metric.split(':', 2);
                			var name = parts[0].replace(/[^a-zA-Z0-9]/g, '');
                			metric_payload.push({
                				'Id': name.charAt(0).toLowerCase() + name.slice(1),
                				'MetricStat': {
                					'Metric': {
                						'MetricName': parts[0],
                						'Namespace': 'AWS/EBS',
                						'Dimensions': [
                							{
                								'Name': 'VolumeId',
                								'Value': volume_id
                							}
                						]
                					},
                					'Period': period,
                					'Stat': 'Average',
                					'Unit': parts[1]
                				}
                			});
                		});
                
                		return metric_payload;
                	},
                
                	prepareParams: function (params) {
                		var result = [];
                
                		Object.keys(params).sort().forEach(function (key) {
                			if (typeof params[key] !== 'object') {
                				result.push(key + '=' + encodeURIComponent(params[key]));
                			}
                			else {
                				result.push(prepareObject(key, params[key]));
                			}
                		});
                
                		return result.join('&');
                	},
                
                	request: function (method, region, service, params, data) {
                		if (typeof data === 'undefined' || data === null) {
                			data = '';
                		}
                
                		var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''),
                			date = amzdate.replace(/T\d+Z/, ''),
                			host = service + '.' + region + '.amazonaws.com',
                			canonical_uri = '/',
                			canonical_headers = 'content-encoding:amz-1.0\n' + 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n',
                			signed_headers = 'content-encoding;host;x-amz-date',
                			canonical_request = method + '\n' + canonical_uri + '\n' + params + '\n' + canonical_headers + '\n' + signed_headers + '\n' + sha256(data),
                			credential_scope = date + '/' + region + '/' + service + '/' + 'aws4_request',
                			request_string = 'AWS4-HMAC-SHA256' + '\n' + amzdate + '\n' + credential_scope + '\n' + sha256(canonical_request),
                			key = AWS.sign('AWS4' + AWS.params.SecretAccessKey, date);
                
                		key = AWS.sign(key, region);
                		key = AWS.sign(key, service);
                		key = AWS.sign(key, 'aws4_request');
                
                		var request = new HttpRequest(),
                			url = 'https://' + host + canonical_uri + '?' + params;
                
                		if (typeof AWS.params.proxy !== 'undefined' && AWS.params.proxy !== '') {
                			request.setProxy(AWS.params.proxy);
                		}
                		request.addHeader('x-amz-date: ' + amzdate);
                		request.addHeader('Accept: application/json');
                		request.addHeader('Content-Type: application/json');
                		request.addHeader('Content-Encoding: amz-1.0');
                		request.addHeader('Authorization: ' + 'AWS4-HMAC-SHA256 Credential=' + AWS.params.AccessKeyId + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
                		if (AWS.params.auth_type === 'role_base')
                			request.addHeader('X-Amz-Security-Token: ' + AWS.params.Token);
                
                		Zabbix.log(4, '[ AWS EBS ] Sending request: ' + url);
                
                		response = request.get(url);
                
                		Zabbix.log(4, '[ AWS EBS ] Received response with status code ' + request.getStatus() + ': ' + response);
                
                		if (request.getStatus() !== 200) {
                			throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
                		}
                
                		if (response !== null) {
                			try {
                				response = JSON.parse(response);
                			}
                			catch (error) {
                				throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
                			}
                		}
                
                		return response;
                	},
                
                	getMetricsData: function () {
                		var timestamp = new Date().getTime(),
                			end_time = new Date(timestamp).toISOString().replace(/\.\d+Z/, 'Z'),
                			start_time = new Date(timestamp - AWS.request_period * 1000).toISOString().replace(/\.\d+Z/, 'Z'),
                			payload = AWS.prepareRecursive('MetricDataQueries', AWS.renderPayload(AWS.request_period, AWS.params.volume_id));
                
                		payload['Action'] = 'GetMetricData';
                		payload['Version'] = '2010-08-01';
                		payload['StartTime'] = start_time;
                		payload['EndTime'] = end_time;
                		payload['ScanBy'] = 'TimestampDescending';
                
                		result = AWS.request('GET', AWS.params.region, 'monitoring', AWS.prepareParams(payload));
                
                		if (typeof result !== 'object'
                				|| typeof result.GetMetricDataResponse !== 'object'
                				|| typeof result.GetMetricDataResponse.GetMetricDataResult !== 'object'
                				|| typeof result.GetMetricDataResponse.GetMetricDataResult.MetricDataResults !== 'object') {
                			throw 'Cannot get metrics data from AWS CloudWatch API. Check debug log for more information.';
                		}
                
                		return result.GetMetricDataResponse.GetMetricDataResult.MetricDataResults;
                	}
                };
                
                try {
                	AWS.setParams(JSON.parse(value));
                
                	return JSON.stringify(AWS.getMetricsData());
                }
                catch (error) {
                	error += (String(error).endsWith('.')) ? '' : '.';
                	Zabbix.log(3, '[ AWS EBS ] ERROR: ' + error);
                
                	return JSON.stringify({'error': error});
                }
              description: |
                Get metrics of EBS volume.
                Full metrics list related to EBS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using_cloudwatch_ebs.html
              preprocessing:
                - type: CHECK_NOT_SUPPORTED
                  parameters:
                    - '-1'
              timeout: 15s
              parameters:
                - name: AccessKeyId
                  value: '{$AWS.ACCESS.KEY.ID}'
                - name: auth_type
                  value: '{$AWS.AUTH_TYPE}'
                - name: proxy
                  value: '{$AWS.PROXY}'
                - name: region
                  value: '{$AWS.REGION}'
                - name: SecretAccessKey
                  value: '{$AWS.SECRET.ACCESS.KEY}'
                - name: volume_id
                  value: '{#VOLUME_ID}'
              tags:
                - tag: component
                  value: raw
                - tag: type
                  value: '{#VOLUME_TYPE}'
                - tag: volume
                  value: '{#VOLUME_ID}'
          graph_prototypes:
            - uuid: dbf87c66b9034e1ab40f3a2d4adb1a5a
              name: 'AWS EBS: [{#VOLUME_ID}]: Volume read/write bytes'
              graph_items:
                - color: 199C0D
                  item:
                    host: 'AWS EC2 by HTTP'
                    key: 'aws.ec2.ebs.volume.write_bytes["{#VOLUME_ID}"]'
                - sortorder: '1'
                  color: F63100
                  item:
                    host: 'AWS EC2 by HTTP'
                    key: 'aws.ec2.ebs.volume.read_bytes["{#VOLUME_ID}"]'
            - uuid: 97faf8177efd46f2b90a7078e532f623
              name: 'AWS EBS: [{#VOLUME_ID}]: Volume read/write ops'
              graph_items:
                - color: 199C0D
                  item:
                    host: 'AWS EC2 by HTTP'
                    key: 'aws.ec2.ebs.volume.write_ops["{#VOLUME_ID}"]'
                - sortorder: '1'
                  color: F63100
                  item:
                    host: 'AWS EC2 by HTTP'
                    key: 'aws.ec2.ebs.volume.read_ops["{#VOLUME_ID}"]'
            - uuid: c27e794ff80a4335874ae9b58c8ce6b8
              name: 'AWS EBS: [{#VOLUME_ID}]: Volume read/write time'
              graph_items:
                - color: 199C0D
                  item:
                    host: 'AWS EC2 by HTTP'
                    key: 'aws.ec2.ebs.volume.total_write_time["{#VOLUME_ID}"]'
                - sortorder: '1'
                  color: F63100
                  item:
                    host: 'AWS EC2 by HTTP'
                    key: 'aws.ec2.ebs.volume.total_read_time["{#VOLUME_ID}"]'
          master_item:
            key: aws.ec2.get_volumes
          preprocessing:
            - type: JAVASCRIPT
              parameters:
                - |
                  var result = [];
                  var volumes = JSON.parse(value);
                  
                  volumes.forEach(function(volume) {
                  
                   result.push({
                  '{#VOLUME_ID}': volume.volumeId,
                  '{#VOLUME_TYPE}': volume.volumeType,
                    });
                  });
                  
                  return JSON.stringify(result);
            - type: DISCARD_UNCHANGED_HEARTBEAT
              parameters:
                - 3h
      tags:
        - tag: class
          value: software
        - tag: target
          value: aws
        - tag: target
          value: ec2
      macros:
        - macro: '{$AWS.ACCESS.KEY.ID}'
          description: 'Access key ID.'
        - macro: '{$AWS.AUTH_TYPE}'
          value: access_key
          description: 'Authorization method. Possible values: role_base, access_key.'
        - macro: '{$AWS.EBS.BURST.CREDIT.BALANCE.MIN.WARN}'
          value: '20'
          description: 'Minimum percentage of Byte credits remaining for trigger expression.'
        - macro: '{$AWS.EBS.BYTE.CREDIT.BALANCE.MIN.WARN}'
          value: '20'
          description: 'Minimum percentage of Byte credits remaining for trigger expression.'
        - macro: '{$AWS.EBS.IO.CREDIT.BALANCE.MIN.WARN}'
          value: '20'
          description: 'Minimum percentage of I/O credits remaining for trigger expression.'
        - macro: '{$AWS.EC2.CPU.CREDIT.BALANCE.MIN.WARN}'
          value: '50'
          description: 'Minimum number of free earned CPU credits for trigger expression.'
        - macro: '{$AWS.EC2.CPU.CREDIT.SURPLUS.BALANCE.MAX.WARN}'
          value: '100'
          description: 'Maximum number of spent CPU Surplus credits for trigger expression.'
        - macro: '{$AWS.EC2.CPU.UTIL.WARN.MAX}'
          value: '85'
          description: 'The warning threshold of the CPU utilization expressed in %.'
        - macro: '{$AWS.EC2.INSTANCE.ID}'
          description: 'EC2 instance ID.'
        - macro: '{$AWS.EC2.LLD.FILTER.ALARM_NAME.MATCHES}'
          value: '.*'
          description: 'Filter of discoverable alarms by name.'
        - macro: '{$AWS.EC2.LLD.FILTER.ALARM_NAME.NOT_MATCHES}'
          value: CHANGE_IF_NEEDED
          description: 'Filter to exclude discovered alarms by name.'
        - macro: '{$AWS.EC2.LLD.FILTER.ALARM_SERVICE_NAMESPACE.MATCHES}'
          value: '.*'
          description: 'Filter of discoverable alarms by namespace.'
        - macro: '{$AWS.EC2.LLD.FILTER.ALARM_SERVICE_NAMESPACE.NOT_MATCHES}'
          value: CHANGE_IF_NEEDED
          description: 'Filter to exclude discovered alarms by namespace.'
        - macro: '{$AWS.EC2.LLD.FILTER.VOLUME_TYPE.MATCHES}'
          value: '.*'
          description: 'Filter of discoverable volumes by type.'
        - macro: '{$AWS.EC2.LLD.FILTER.VOLUME_TYPE.NOT_MATCHES}'
          value: CHANGE_IF_NEEDED
          description: 'Filter to exclude discovered volumes by type.'
        - macro: '{$AWS.PROXY}'
          description: 'Sets HTTP proxy value. If this macro is empty then no proxy is used.'
        - macro: '{$AWS.REGION}'
          value: us-west-1
          description: 'Amazon EC2 Region code.'
        - macro: '{$AWS.SECRET.ACCESS.KEY}'
          description: 'Secret access key.'
      valuemaps:
        - uuid: 50b7fdfdf6de41f4b4b210a07c10cd77
          name: 'Alarm state'
          mappings:
            - value: '0'
              newvalue: OK
            - value: '1'
              newvalue: 'Insufficient data'
            - value: '2'
              newvalue: Alarm
            - value: '255'
              newvalue: Unknown
        - uuid: d59e4f0c6aaa40bcb5f504f6743d9201
          name: 'Status check'
          mappings:
            - value: '0'
              newvalue: Passed
            - value: '1'
              newvalue: Failed
        - uuid: cf0267337f284182a43db45d823824b7
          name: 'Volume attachment state'
          mappings:
            - value: '0'
              newvalue: Attaching
            - value: '1'
              newvalue: Attached
            - value: '2'
              newvalue: Detaching
            - value: '255'
              newvalue: Unknown
        - uuid: 4f31d29791b94e37b065f790609c50b5
          name: 'Volume status'
          mappings:
            - value: '0'
              newvalue: Creating
            - value: '1'
              newvalue: Available
            - value: '2'
              newvalue: In-use
            - value: '3'
              newvalue: Deleting
            - value: '4'
              newvalue: Deleted
            - value: '5'
              newvalue: Error
            - value: '255'
              newvalue: Unknown
  graphs:
    - uuid: 397c46285f674ac389c59f1c828ae179
      name: 'AWS EC2: Disk read/write bytes'
      graph_items:
        - color: 199C0D
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.disk.read_bytes.rate
        - sortorder: '1'
          color: F63100
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.disk_write_bytes.rate
    - uuid: 21b7ec1e5e1445e287855e3d1a12c2bc
      name: 'AWS EC2: Disk read/write rates'
      graph_items:
        - color: 199C0D
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.disk.read_ops.rate
        - sortorder: '1'
          color: F63100
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.disk_write_ops.rate
    - uuid: a1244a6a4b6641388546988257e905dc
      name: 'AWS EC2: Network packets'
      graph_items:
        - color: 199C0D
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.packets_in.rate
        - sortorder: '1'
          color: F63100
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.packets_out.rate
    - uuid: 45e96dbc8dff48eeadd18c69b085863f
      name: 'AWS EC2: Network traffic'
      graph_items:
        - color: 199C0D
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.network_in.rate
        - sortorder: '1'
          color: F63100
          item:
            host: 'AWS EC2 by HTTP'
            key: aws.ec2.network_out.rate
