zabbix_export: version: '7.0' template_groups: - uuid: c2c162144c2d4c5491c8801193af4945 name: Templates/Cloud host_groups: - uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6 name: Applications - uuid: 748ad4d098d447d492bb935c907f652f name: Databases - uuid: 137f19e6e2dc4219b33553b812627bc2 name: 'Virtual machines' templates: - uuid: c60e5929ab474f67bbe67dc6b04e709d template: 'AWS by HTTP' name: 'AWS by HTTP' description: | Get AWS EC2, RDS and S3 instances, AWS ECS clusters. 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" 2.0.0 vendor: name: Zabbix version: 7.0-0 groups: - name: Templates/Cloud discovery_rules: - uuid: c651911bad9244ad9c8d2dad5b0d70e4 name: 'EC2 instances discovery' type: SCRIPT key: aws.ec2.discovery delay: 12h params: | var AwsEC2 = { params: {}, setParams: function (params) { ['access_key', 'region', 'secret_key'].forEach(function (field) { if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') { throw 'Required param is not set: "' + field + '".'; } }); AwsEC2.params = params; }, 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, host, params, data, uri) { if (typeof data === 'undefined' || data === null) { data = ''; } var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''), date = amzdate.replace(/T\d+Z/, ''), canonical_uri = '/' + 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 = AwsEC2.sign('AWS4' + AwsEC2.params.secret_key, date); key = AwsEC2.sign(key, region); key = AwsEC2.sign(key, service); key = AwsEC2.sign(key, 'aws4_request'); var request = new HttpRequest(), url = 'https://' + host + canonical_uri + '?' + params; if (typeof AwsEC2.params.proxy !== 'undefined' && AwsEC2.params.proxy !== '') { request.setProxy(AwsEC2.params.proxy); } request.addHeader('x-amz-date: ' + amzdate); request.addHeader('x-amz-content-sha256:' + sha256(data)); 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=' + AwsEC2.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string)); Zabbix.log(4, '[ AWS EC2 ] Sending request: ' + url); response = request.post(url, data); 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 = XML.toJson(response); } catch (error) { throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.'; } } return JSON.parse(response); }, tagToNameInstances: function (instance) { if (!Array.isArray(instance)) instance = [instance]; instance.forEach(function (item, index, instance_array) { if (typeof item !== 'object' || typeof item.instancesSet !== 'object' || typeof item.instancesSet.item !== 'object' || item.instancesSet.item.hasOwnProperty('instanceId') === false) throw 'Failed response parse. Check debug log for more information.'; var instanceName = item.instancesSet.item.instanceId if (typeof item.instancesSet.item.tagSet === 'object' && typeof item.instancesSet.item.tagSet.item === 'object') { if (!Array.isArray(item.instancesSet.item.tagSet.item)) item.instancesSet.item.tagSet.item = [item.instancesSet.item.tagSet.item]; item.instancesSet.item.tagSet.item.forEach( function (tag) { if (tag.hasOwnProperty('key') && tag.key === 'Name') { instanceName = tag.value; } } ); } instance_array[index]['instanceName'] = instanceName; }); return instance; }, listInstances: function () { var payload = {}; payload['Action'] = 'DescribeInstances', payload['Version'] = '2016-11-15' result = AwsEC2.request('POST', AwsEC2.params.region, 'ec2', 'ec2.' + AwsEC2.params.region + '.amazonaws.com', AwsEC2.prepareParams(payload), '', ''); if (typeof result !== 'object' || typeof result.DescribeInstancesResponse !== 'object' || typeof result.DescribeInstancesResponse.reservationSet !== 'object') { throw 'Cannot get EC2 instance list from AWS API. Check debug log for more information.'; } if (result.DescribeInstancesResponse.reservationSet === null) return []; if (typeof result.DescribeInstancesResponse.reservationSet.item !== 'object') throw 'Cannot get EC2 instance list from AWS API. Check debug log for more information.'; return AwsEC2.tagToNameInstances(result.DescribeInstancesResponse.reservationSet.item); } }; try { AwsEC2.setParams(JSON.parse(value)); return JSON.stringify(AwsEC2.listInstances()); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ AWS EC2 ] ERROR: ' + error); return JSON.stringify({ 'error': error }); } filter: evaltype: AND conditions: - macro: '{#AWS.EC2.INSTANCE.NAME}' value: '{$AWS.EC2.LLD.FILTER.NAME.MATCHES}' formulaid: A - macro: '{#AWS.EC2.INSTANCE.NAME}' value: '{$AWS.EC2.LLD.FILTER.NAME.NOT_MATCHES}' operator: NOT_MATCHES_REGEX formulaid: B description: 'Get EC2 instances.' host_prototypes: - uuid: c4c830c727294b07926c39b00cf19046 host: '{#AWS.EC2.INSTANCE.ID}' name: '{#AWS.EC2.INSTANCE.NAME}' group_links: - group: name: 'Virtual machines' templates: - name: 'AWS EC2 by HTTP' macros: - macro: '{$AWS.EC2.INSTANCE.ID}' value: '{#AWS.EC2.INSTANCE.ID}' description: 'EC2 instance ID.' custom_interfaces: 'YES' interfaces: - ip: '{#AWS.EC2.INSTANCE.ID}' timeout: 15s parameters: - name: access_key value: '{$AWS.ACCESS.KEY.ID}' - name: secret_key value: '{$AWS.SECRET.ACCESS.KEY}' - name: region value: '{$AWS.REGION}' - name: proxy value: '{$AWS.PROXY}' lld_macro_paths: - lld_macro: '{#AWS.EC2.INSTANCE.ID}' path: $.instancesSet.item.instanceId - lld_macro: '{#AWS.EC2.INSTANCE.NAME}' path: $.instanceName - uuid: 44b68894d68c45ec9a5ea787c975ae16 name: 'ECS clusters discovery' type: SCRIPT key: aws.ecs.discovery delay: 12h params: | var AwsECS = { params: {}, setParams: function (params) { ['access_key', 'region', 'secret_key'].forEach(function (field) { if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') { throw 'Required param is not set: "' + field + '".'; } }); AwsECS.params = params; }, 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; }, 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, host, params, data, uri) { if (typeof data === 'undefined' || data === null) { data = ''; } var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''), date = amzdate.replace(/T\d+Z/, ''), canonical_uri = '/' + 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 = AwsECS.sign('AWS4' + AwsECS.params.secret_key, date); key = AwsECS.sign(key, region); key = AwsECS.sign(key, service); key = AwsECS.sign(key, 'aws4_request'); var request = new HttpRequest(), url = 'https://' + host + canonical_uri + '?' + params; if (typeof AwsECS.params.proxy !== 'undefined' && AwsECS.params.proxy !== '') { request.setProxy(AwsECS.params.proxy); } request.addHeader('x-amz-date: ' + amzdate); request.addHeader('x-amz-content-sha256:' + sha256(data)); request.addHeader('Accept: application/json'); request.addHeader('Content-Type: application/x-www-form-urlencoded'); request.addHeader('Content-Encoding: amz-1.0'); request.addHeader('Authorization: ' + 'AWS4-HMAC-SHA256 Credential=' + AwsECS.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string)); Zabbix.log(4, '[ AWS ECS ] Sending request: ' + url); response = request.post(url, data); Zabbix.log(4, '[ AWS ECS ] Received response with status code ' + request.getStatus() + ': ' + response); if (request.getStatus() !== 200) { throw 'Request failed with status code ' + request.getStatus() + ': ' + response; } try { response = JSON.parse(response); } catch (error) { throw 'Failed to parse response received from AWS API. Check debug log for more information.'; } return response; }, listClusters: function () { var payload = {}, result, ECSClusters, data = []; payload['Action'] = 'ListClusters'; payload['Version'] = '2014-11-13'; result = AwsECS.request('POST', AwsECS.params.region, 'ecs', 'ecs.' + AwsECS.params.region + '.amazonaws.com', AwsECS.prepareParams(payload), '', ''); ECSClusters = AwsECS.getField(result, 'ListClustersResponse.ListClustersResult.clusterArns') for (k in ECSClusters) { clusters = ECSClusters[k]; json = {}; input = clusters.split('/'); for (var i = 1; i < input.length; i += 2) { json[input[i]] = input[i + 1]; } data.push({ 'clusters_name': input[1], }); } if (Array.isArray(data)) return data; else return [data]; }, decribeClusters: function (cluster_name) { var payload = {}, result; payload['Action'] = 'DescribeClusters'; payload['Version'] = '2014-11-13'; payload['clusters.clusterName'] = cluster_name; payload['include.statistics'] = 'STATISTICS'; result = AwsECS.request('POST', AwsECS.params.region, 'ecs', 'ecs.' + AwsECS.params.region + '.amazonaws.com', AwsECS.prepareParams(payload), '', ''); return result; } }; try { AwsECS.setParams(JSON.parse(value)); var clusters = AwsECS.listClusters(), infrastructure = [], metrics = ['runningEC2TasksCount', 'pendingEC2TasksCount', 'activeEC2ServiceCount', 'drainingEC2ServiceCount'], ECSClusters = [], DescribeClusters = []; DescribeClusters = clusters.map(function (cluster) { ECSClusters = AwsECS.getField(AwsECS.decribeClusters(cluster.clusters_name), 'DescribeClustersResponse.DescribeClustersResult.clusters') for (k in ECSClusters) { var ECS2 = 0; statistic = AwsECS.getField(ECSClusters[k], 'statistics'); statistic.forEach(function (id) { for (i in metrics) { if (AwsECS.getField(id, 'name') === metrics[i]) { ECS2 += Number(AwsECS.getField(id, 'value')); } } }) infrastructure = (ECS2 > 0) ? 'use_ecs2' : 'serverless'; return { 'clusterName': ECSClusters[k].clusterName, 'status': ECSClusters[k].status, 'infrastructure': infrastructure } } }) return JSON.stringify(DescribeClusters); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ AWS ECS ] ERROR: ' + error); return JSON.stringify({ 'error': error }); } filter: evaltype: AND conditions: - macro: '{#AWS.ECS.CLUSTER.NAME}' value: '{$AWS.ECS.LLD.FILTER.NAME.MATCHES}' formulaid: A - macro: '{#AWS.ECS.CLUSTER.NAME}' value: '{$AWS.ECS.LLD.FILTER.NAME.NOT_MATCHES}' operator: NOT_MATCHES_REGEX formulaid: B - macro: '{#AWS.ECS.CLUSTER.STATUS}' value: '{$AWS.ECS.LLD.FILTER.STATUS.MATCHES}' formulaid: C - macro: '{#AWS.ECS.CLUSTER.STATUS}' value: '{$AWS.ECS.LLD.FILTER.STATUS.NOT_MATCHES}' operator: NOT_MATCHES_REGEX formulaid: D description: 'Get ECS clusters.' host_prototypes: - uuid: 71072e5a149e45b293946866f8220c07 host: '{#AWS.ECS.CLUSTER.NAME}' name: '{#AWS.ECS.CLUSTER.NAME}' group_links: - group: name: Applications macros: - macro: '{$AWS.ECS.CLUSTER.NAME}' value: '{#AWS.ECS.CLUSTER.NAME}' description: 'ECS cluster name.' timeout: 15s parameters: - name: access_key value: '{$AWS.ACCESS.KEY.ID}' - name: secret_key value: '{$AWS.SECRET.ACCESS.KEY}' - name: region value: '{$AWS.REGION}' - name: proxy value: '{$AWS.PROXY}' lld_macro_paths: - lld_macro: '{#AWS.ECS.CLUSTER.NAME}' path: $.clusterName - lld_macro: '{#AWS.ECS.CLUSTER.STATUS}' path: $.status - lld_macro: '{#AWS.ECS.CLUSTER.INFRASTRUCTURE}' path: $.infrastructure overrides: - name: Serverless step: '1' filter: conditions: - macro: '{#AWS.ECS.CLUSTER.INFRASTRUCTURE}' value: ^serverless$ formulaid: A operations: - operationobject: HOST_PROTOTYPE operator: REGEXP templates: - name: 'AWS ECS Serverless Cluster by HTTP' - name: 'Use EC2 Infrastructure' step: '2' filter: conditions: - macro: '{#AWS.ECS.CLUSTER.INFRASTRUCTURE}' value: ^use_ecs2$ formulaid: A operations: - operationobject: HOST_PROTOTYPE operator: REGEXP templates: - name: 'AWS ECS Cluster by HTTP' - uuid: c1127e674b7548b2802cd8771f3a4768 name: 'RDS instances discovery' type: SCRIPT key: aws.rds.discovery delay: 12h params: | var AwsRDS = { params: {}, setParams: function (params) { ['access_key', 'region', 'secret_key'].forEach(function (field) { if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') { throw 'Required param is not set: "' + field + '".'; } }); AwsRDS.params = params; }, 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, host, params, data, uri) { if (typeof data === 'undefined' || data === null) { data = ''; } var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''), date = amzdate.replace(/T\d+Z/, ''), canonical_uri = '/' + 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 = AwsRDS.sign('AWS4' + AwsRDS.params.secret_key, date); key = AwsRDS.sign(key, region); key = AwsRDS.sign(key, service); key = AwsRDS.sign(key, 'aws4_request'); var request = new HttpRequest(), url = 'https://' + host + canonical_uri + '?' + params; if (typeof AwsRDS.params.proxy !== 'undefined' && AwsRDS.params.proxy !== '') { request.setProxy(AwsRDS.params.proxy); } request.addHeader('x-amz-date: ' + amzdate); request.addHeader('x-amz-content-sha256:' + sha256(data)); 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=' + AwsRDS.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string)); Zabbix.log(4, '[ AWS RDS ] Sending request: ' + url); response = request.post(url, data); Zabbix.log(4, '[ AWS RDS ] Received response with status code ' + request.getStatus() + ': ' + response); if (request.getStatus() !== 200) { throw 'Request failed with status code ' + request.getStatus() + ': ' + response; } try { response = JSON.parse(response); } catch (error) { throw 'Failed to parse response received from AWS API. Check debug log for more information.'; } return response; }, listInstances: function () { var payload = {}; payload['Action'] = 'DescribeDBInstances', payload['Version'] = '2014-10-31' result = AwsRDS.request('POST', AwsRDS.params.region, 'rds', 'rds.' + AwsRDS.params.region + '.amazonaws.com', AwsRDS.prepareParams(payload), '', ''); if (typeof result !== 'object' || typeof result.DescribeDBInstancesResponse !== 'object' || typeof result.DescribeDBInstancesResponse.DescribeDBInstancesResult !== 'object' || typeof result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances !== 'object') { throw 'Cannot get DB instance list from AWS RDS API. Check debug log for more information.'; } if (Array.isArray(result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances)) return result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances; else return [result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances]; } }; try { AwsRDS.setParams(JSON.parse(value)); return JSON.stringify(AwsRDS.listInstances()); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ AWS RDS ] ERROR: ' + error); return JSON.stringify({ 'error': error }); } filter: evaltype: AND conditions: - macro: '{#AWS.RDS.INSTANCE.ID}' value: '{$AWS.RDS.LLD.FILTER.NAME.MATCHES}' formulaid: A - macro: '{#AWS.RDS.INSTANCE.ID}' value: '{$AWS.RDS.LLD.FILTER.NAME.NOT_MATCHES}' operator: NOT_MATCHES_REGEX formulaid: B description: 'Get RDS instances.' host_prototypes: - uuid: 799663c52a644f78aa3b3c14d4cc7235 host: '{#AWS.RDS.INSTANCE.ID}' name: '{#AWS.RDS.INSTANCE.ID}' group_links: - group: name: Databases templates: - name: 'AWS RDS instance by HTTP' macros: - macro: '{$AWS.RDS.INSTANCE.ID}' value: '{#AWS.RDS.INSTANCE.ID}' description: 'RDS instance ID.' custom_interfaces: 'YES' interfaces: - ip: '{#AWS.RDS.INSTANCE.ID}' timeout: 15s parameters: - name: access_key value: '{$AWS.ACCESS.KEY.ID}' - name: secret_key value: '{$AWS.SECRET.ACCESS.KEY}' - name: region value: '{$AWS.REGION}' - name: proxy value: '{$AWS.PROXY}' lld_macro_paths: - lld_macro: '{#AWS.RDS.INSTANCE.ID}' path: $.DBInstanceIdentifier - uuid: ab6a97a108fb4dbc9fd1e07378721ffe name: 'S3 buckets discovery' type: SCRIPT key: aws.s3.discovery delay: 12h params: | var AwsS3 = { params: {}, setParams: function (params) { ['access_key', 'secret_key'].forEach(function (field) { if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') { throw 'Required param is not set: "' + field + '".'; } }); AwsS3.params = params; }, 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, host, params, data, uri) { if (typeof data === 'undefined' || data === null) { data = ''; } var amzdate = (new Date()).toISOString().replace(/\.\d+Z/, 'Z').replace(/[-:]/g, ''), date = amzdate.replace(/T\d+Z/, ''), canonical_uri = '/' + 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 = AwsS3.sign('AWS4' + AwsS3.params.secret_key, date); key = AwsS3.sign(key, region); key = AwsS3.sign(key, service); key = AwsS3.sign(key, 'aws4_request'); var request = new HttpRequest(), url = 'https://' + host + canonical_uri + '?' + params; if (typeof AwsS3.params.proxy !== 'undefined' && AwsS3.params.proxy !== '') { request.setProxy(AwsS3.params.proxy); } request.addHeader('x-amz-date: ' + amzdate); request.addHeader('x-amz-content-sha256:' + sha256(data)); 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=' + AwsS3.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string)); Zabbix.log(4, '[ AWS S3 ] Sending request: ' + url); response = request.get(url); Zabbix.log(4, '[ AWS S3 ] 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.'; } } return JSON.parse(response); }, getBucketLocation: function (bucket_name) { var payload = {}; payload['location'] = '', result = AwsS3.request('GET', 'us-east-1', 's3', 's3.amazonaws.com', AwsS3.prepareParams(payload), '', bucket_name); if (typeof result !== 'object' || result.hasOwnProperty('LocationConstraint') === false ) { throw 'Cannot get buckets region location data from AWS S3 API. Check debug log for more information.'; } return result.LocationConstraint !== null ? result.LocationConstraint : 'us-east-1'; }, listBuckets: function () { var payload = {}; payload['Action'] = 'ListBuckets', payload['Version'] = '2006-03-01', result = AwsS3.request('GET', 'us-east-1', 's3', 's3.us-east-1.amazonaws.com', AwsS3.prepareParams(payload), '', ''); if (typeof result !== 'object' || typeof result.ListAllMyBucketsResult !== 'object' || typeof result.ListAllMyBucketsResult.Buckets !== 'object') { throw 'Cannot get buckets list from AWS S3 API. Check debug log for more information.'; } if (result.ListAllMyBucketsResult.Buckets === null) return [] if (typeof result.ListAllMyBucketsResult.Buckets.Bucket !== 'object') { throw 'Cannot get buckets list from AWS S3 API. Check debug log for more information.'; } var buckets = []; if (!Array.isArray(result.ListAllMyBucketsResult.Buckets.Bucket)) buckets = [result.ListAllMyBucketsResult.Buckets.Bucket] else buckets = result.ListAllMyBucketsResult.Buckets.Bucket buckets.forEach( function (bucket, index, buckets_array) { if (!bucket.hasOwnProperty('Name')) throw 'Cannot get location for bucket. Check debug log for more information.'; buckets_array[index]['location'] = AwsS3.getBucketLocation(bucket['Name']); }); return buckets; } }; try { AwsS3.setParams(JSON.parse(value)); return JSON.stringify(AwsS3.listBuckets()); } catch (error) { error += (String(error).endsWith('.')) ? '' : '.'; Zabbix.log(3, '[ AWS S3 ] ERROR: ' + error); return JSON.stringify({ 'error': error }); } filter: evaltype: AND conditions: - macro: '{#AWS.S3.NAME}' value: '{$AWS.S3.LLD.FILTER.NAME.MATCHES}' formulaid: A - macro: '{#AWS.S3.NAME}' value: '{$AWS.S3.LLD.FILTER.NAME.NOT_MATCHES}' operator: NOT_MATCHES_REGEX formulaid: B description: 'Get S3 bucket instances.' host_prototypes: - uuid: e45bd9810ea14718b17b875aad3fc544 host: '{#AWS.S3.NAME}' name: '{#AWS.S3.NAME}' group_links: - group: name: Applications group_prototypes: - name: '{#AWS.S3.REGION}' templates: - name: 'AWS S3 bucket by HTTP' macros: - macro: '{$AWS.REGION}' value: '{#AWS.S3.REGION}' description: 'Amazon S3 region code.' - macro: '{$AWS.S3.BUCKET.NAME}' value: '{#AWS.S3.NAME}' description: 'S3 bucket name.' - macro: '{$AWS.S3.FILTER.ID}' value: '1' description: 'S3 bucket requests filter identifier.' custom_interfaces: 'YES' interfaces: - ip: '{#AWS.S3.NAME}' timeout: 15s parameters: - name: access_key value: '{$AWS.ACCESS.KEY.ID}' - name: secret_key value: '{$AWS.SECRET.ACCESS.KEY}' - name: proxy value: '{$AWS.PROXY}' lld_macro_paths: - lld_macro: '{#AWS.S3.NAME}' path: $.Name - lld_macro: '{#AWS.S3.REGION}' path: $.location tags: - tag: class value: software - tag: target value: aws macros: - macro: '{$AWS.ACCESS.KEY.ID}' description: 'Access key ID.' - macro: '{$AWS.EC2.LLD.FILTER.NAME.MATCHES}' value: '.*' description: 'Filter of discoverable EC2 instances by namespace.' - macro: '{$AWS.EC2.LLD.FILTER.NAME.NOT_MATCHES}' value: CHANGE_IF_NEEDED description: 'Filter to exclude discovered EC2 instances by namespace.' - macro: '{$AWS.ECS.LLD.FILTER.NAME.MATCHES}' value: '.*' description: 'Filter of discoverable ECS clusters by name.' - macro: '{$AWS.ECS.LLD.FILTER.NAME.NOT_MATCHES}' value: CHANGE_IF_NEEDED description: 'Filter to exclude discovered ECS clusters by name.' - macro: '{$AWS.ECS.LLD.FILTER.STATUS.MATCHES}' value: ACTIVE description: 'Filter of discoverable ECS clusters by status.' - macro: '{$AWS.ECS.LLD.FILTER.STATUS.NOT_MATCHES}' value: CHANGE_IF_NEEDED description: 'Filter to exclude discovered ECS clusters by status.' - macro: '{$AWS.PROXY}' description: 'Sets HTTP proxy value. If this macro is empty then no proxy is used.' - macro: '{$AWS.RDS.LLD.FILTER.NAME.MATCHES}' value: '.*' description: 'Filter of discoverable RDS instances by namespace.' - macro: '{$AWS.RDS.LLD.FILTER.NAME.NOT_MATCHES}' value: CHANGE_IF_NEEDED description: 'Filter to exclude discovered RDS instances by namespace.' - macro: '{$AWS.REGION}' value: us-west-1 description: 'Amazon EC2 region code.' - macro: '{$AWS.S3.LLD.FILTER.NAME.MATCHES}' value: '.*' description: 'Filter of discoverable S3 buckets by namespace.' - macro: '{$AWS.S3.LLD.FILTER.NAME.NOT_MATCHES}' value: CHANGE_IF_NEEDED description: 'Filter to exclude discovered S3 buckets by namespace.' - macro: '{$AWS.SECRET.ACCESS.KEY}' type: SECRET_TEXT description: 'Secret access key.'