Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,7 @@ module.exports = {
'vmssTrustedLaunchEnabled' : require(__dirname + '/plugins/azure/virtualmachinescaleset/vmssTrustedLaunchEnabled.js'),
'scaleSetAdAuthEnabled' : require(__dirname + '/plugins/azure/virtualmachinescaleset/scaleSetAdAuthEnabled.js'),
'vmssManagedIdentityEnabled' : require(__dirname + '/plugins/azure/virtualmachinescaleset/vmssManagedIdentityEnabled.js'),
'vmScaleSetVnetIntegrated' : require(__dirname + '/plugins/azure/virtualmachinescaleset/vmScaleSetVnetIntegrated.js'),
'scalesetVTPMEnabled' : require(__dirname + '/plugins/azure/virtualmachinescaleset/scalesetVTPMEnabled.js'),
'scalesetSecureBootEnabled' : require(__dirname + '/plugins/azure/virtualmachinescaleset/scalesetSecureBootEnabled.js'),
'vmssApprovedExtensions' : require(__dirname + '/plugins/azure/virtualmachinescaleset/vmssApprovedExtensions'),
Expand Down
51 changes: 51 additions & 0 deletions plugins/azure/virtualmachinescaleset/vmScaleSetVnetIntegrated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
var async = require('async');

var helpers = require('../../../helpers/azure');


module.exports = {
title: 'VM Scale Set VNet Integrated',
category: 'Virtual Machine Scale Set',
domain: 'Compute',
severity: 'Medium',
description: 'Ensure that Azure Virtual Machine scale sets has VNet integrated.',
more_info: 'You can divide a virtual network into multiple subnets for organization and security. NICs connected to subnets (same or different) within a virtual network can communicate with each other without any extra configuration.',
link: 'https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-networking',
recommended_action: 'Modify VM scale set and configure a VNet.',
apis: ['vmScaleSet:listAll'],
realtime_triggers: ['microsoftcompute:virtualmachinescalesets:write', 'microsoftcompute:virtualmachinescalesets:delete','microsoftnetwork:virtualnetworks:subnets:write','microsoftnetwork:virtualnetworks:subnets:delete'],

run: function(cache, settings, callback) {
var results = [];
var source = {};
var locations = helpers.locations(settings.govcloud);

async.each(locations.vmScaleSet, function(location, rcb) {

var vmScaleSets = helpers.addSource(cache, source, ['vmScaleSet', 'listAll', location]);

if (!vmScaleSets) return rcb();

if (vmScaleSets.err || !vmScaleSets.data) {
helpers.addResult(results, 3, 'Unable to query for VM scale sets: ' + helpers.addError(vmScaleSets), location);
return rcb();
}
if (!vmScaleSets.data.length) {
helpers.addResult(results, 0, 'No existing VM scale sets found', location);
return rcb();
}
for (let set of vmScaleSets.data) {
if (!set.id) continue;
let networkInterfaceConfigs = set.virtualMachineProfile.networkProfile.networkInterfaceConfigurations[0];
if (networkInterfaceConfigs && networkInterfaceConfigs.properties && networkInterfaceConfigs.properties.ipConfigurations[0] && networkInterfaceConfigs.properties.ipConfigurations[0].properties.subnet && networkInterfaceConfigs.properties.ipConfigurations[0].properties.subnet.id) {
helpers.addResult(results, 0, 'VM scale set has VNet Integrated', location, set.id);
} else {
helpers.addResult(results, 2, 'VM scale set does not have VNet Integrated', location, set.id);
}
}
rcb();
}, function() {
callback(null, results, source);
});
}
};
118 changes: 118 additions & 0 deletions plugins/azure/virtualmachinescaleset/vmScaleSetVnetIntegrated.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
var expect = require('chai').expect;
var vmScaleSetVnetIntegrated = require('./vmScaleSetVnetIntegrated');

const vmScaleSet = [
{ "name": 'test',
"id": "/subscriptions/123/resourceGroups/aqua-resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/test",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"location": "centralus",
"tags": {
"key" : "value"
},
"virtualMachineProfile": {
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "pool12345",
"properties": {
"primary": true,
"enableIPForwarding": true,
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"primary": true,
"subnet": {
"id": "/subscriptions/123456789/resourceGroups/MC_new-eastus-group_new-eastus-cluster_westus2/providers/Microsoft.Network/virtualNetworks/aks-vnet1234567890/subnets/aks-subnet",
},
"privateIPAddressVersion": "IPv4"
},
},
],
},
},
],
},
},
},
{ "name": 'test',
"id": "/subscriptions/123/resourceGroups/aqua-resource-group/providers/Microsoft.Compute/virtualMachineScaleSets/test",
"type": "Microsoft.Compute/virtualMachineScaleSets",
"location": "centralus",
"virtualMachineProfile": {
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "pool12345",
"properties": {
"primary": true,
"enableIPForwarding": true,
"ipConfigurations": [
],
},
},
],
},
},
},
];

const createCache = (vmScaleSet) => {
return {
vmScaleSet: {
listAll: {
'eastus': {
data: vmScaleSet
}
}
}
};
};

describe('vmScaleSetVnetIntegrated', function() {
describe('run', function() {
it('should give passing result if no scale set found', function(done) {
const cache = createCache([]);
vmScaleSetVnetIntegrated.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No existing VM scale sets found');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give unknown result if unable to query for scale set', function(done) {
const cache = createCache();
vmScaleSetVnetIntegrated.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query for VM scale sets');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give passing result if scale set has VNet integrated', function(done) {
const cache = createCache([vmScaleSet[0]]);
vmScaleSetVnetIntegrated.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('VM scale set has VNet Integrated');
expect(results[0].region).to.equal('eastus');
done();
});
});

it('should give failing result if VM scale set does not have VNet integrated', function(done) {
const cache = createCache([vmScaleSet[1]]);
vmScaleSetVnetIntegrated.run(cache, {}, (err, results) => {
expect(results.length).to.equal(1);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('VM scale set does not have VNet Integrated');
expect(results[0].region).to.equal('eastus');
done();
});
});
});
});