Skip to content

Commit 2830178

Browse files
committed
Azure/Automation-Account-Public-Access
1 parent cab05b5 commit 2830178

File tree

4 files changed

+151
-1
lines changed

4 files changed

+151
-1
lines changed

exports.js

+1
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,7 @@ module.exports = {
10711071

10721072
'automationAcctDiagnosticLogs' : require(__dirname + '/plugins/azure/automationAccounts/automationAcctDiagnosticLogs.js'),
10731073
'automationAcctManagedIdentity' : require(__dirname + '/plugins/azure/automationAccounts/automationAcctManagedIdentity.js'),
1074+
'automationAcctPublicAccess' : require(__dirname + '/plugins/azure/automationAccounts/automationAcctPublicAccess.js'),
10741075

10751076
},
10761077
github: {

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"tty-table": "^4.1.3"
6161
},
6262
"devDependencies": {
63-
"chai": "^4.2.0",
63+
"chai": "4.2.0",
6464
"eslint": "^6.8.0",
6565
"mocha": "^6.1.4",
6666
"nodemon": "^1.19.4",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const async = require('async');
2+
const helpers = require('../../../helpers/azure');
3+
4+
module.exports = {
5+
title: 'Automation Account Public Access Disabled',
6+
category: 'Automation',
7+
domain: 'Management and Governance',
8+
description: 'Ensure that Azure Automation accounts have have public access disabled.',
9+
more_info: 'Disabling public network access ensures that network traffic between the machines on the VNet and the Automation account traverses over the a private link, eliminating exposure from the public internet.',
10+
recommended_action: 'Modify automation account and disable public access.',
11+
link: 'https://learn.microsoft.com/en-us/azure/automation/how-to/private-link-security',
12+
apis: ['automationAccounts:list'],
13+
14+
run: function(cache, settings, callback) {
15+
const results = [];
16+
const source = {};
17+
const locations = helpers.locations(settings.govcloud);
18+
19+
async.each(locations.automationAccounts, (location, rcb) => {
20+
const automationAccounts = helpers.addSource(cache, source,
21+
['automationAccounts', 'list', location]);
22+
23+
if (!automationAccounts) return rcb();
24+
25+
if (automationAccounts.err || !automationAccounts.data) {
26+
helpers.addResult(results, 3,
27+
'Unable to query Automation accounts: ' + helpers.addError(automationAccounts), location);
28+
return rcb();
29+
}
30+
31+
if (!automationAccounts.data.length) {
32+
helpers.addResult(results, 0, 'No existing Automation accounts found', location);
33+
return rcb();
34+
}
35+
36+
for (var account of automationAccounts.data) {
37+
if (!account.id) continue;
38+
39+
if (!account.publicNetworkAccess) {
40+
helpers.addResult(results, 0, 'Automation account has public network access disabled', location, account.id);
41+
} else {
42+
helpers.addResult(results, 2, 'Automation account does not have public network access disabled', location, account.id);
43+
}
44+
}
45+
46+
rcb();
47+
}, function() {
48+
callback(null, results, source);
49+
});
50+
}
51+
};
52+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
var expect = require('chai').expect;
2+
var automationAcctPublicAccess = require('./automationAcctPublicAccess.js');
3+
4+
const automationAccounts = [
5+
{
6+
"id": "/subscriptions/12345/resourceGroups/DefaultResourceGroup-EUS/providers/Microsoft.Automation/automationAccounts/Automate-12345-EUS2",
7+
"location": "EastUS2",
8+
"name": "Automate-12345-EUS2",
9+
"type": "Microsoft.Automation/AutomationAccounts",
10+
"tags": {},
11+
"creationTime": "2023-10-27T07:27:02.76+00:00",
12+
"lastModifiedTime": "2023-10-27T07:27:02.76+00:00",
13+
"identity": {
14+
"type": "systemassigned,userassigned",
15+
"principalId": "dc03d47d-e6df-491f-aebe-50a93412a890",
16+
"tenantId": "d207c7bd-fcb1-4dd3-855a-cfd2f9b651e8",
17+
"userAssignedIdentities": {
18+
"/subscriptions/12345/resourcegroups/meerab-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testmeerab": {
19+
"PrincipalId": "123455",
20+
"ClientId": "1234554"
21+
}
22+
}
23+
},
24+
"publicNetworkAccess": false,
25+
26+
},
27+
{
28+
"id": "/subscriptions/12345/resourceGroups/DefaultResourceGroup-CUS/providers/Microsoft.Automation/automationAccounts/Automate-12345-CUS",
29+
"location": "centralus",
30+
"name": "Automate-12345-CUS",
31+
"type": "Microsoft.Automation/AutomationAccounts",
32+
"tags": {},
33+
"publicNetworkAccess": true,
34+
}
35+
];
36+
37+
const createCache = (automationAccounts,err) => {
38+
return {
39+
automationAccounts: {
40+
list: {
41+
'eastus': {
42+
data: automationAccounts,
43+
err: err
44+
}
45+
}
46+
}
47+
}
48+
};
49+
50+
describe('automationAcctPublicAccess', function () {
51+
describe('run', function () {
52+
53+
it('should give pass result if No existing automation accounts found', function (done) {
54+
const cache = createCache([]);
55+
automationAcctPublicAccess.run(cache, {}, (err, results) => {
56+
expect(results.length).to.equal(1);
57+
expect(results[0].status).to.equal(0);
58+
expect(results[0].message).to.include('No existing Automation accounts found');
59+
expect(results[0].region).to.equal('eastus');
60+
done();
61+
});
62+
});
63+
64+
it('should give unknown result if Unable to query automation accounts:', function (done) {
65+
const cache = createCache(null, 'Error');
66+
automationAcctPublicAccess.run(cache, {}, (err, results) => {
67+
expect(results.length).to.equal(1);
68+
expect(results[0].status).to.equal(3);
69+
expect(results[0].message).to.include('Unable to query Automation accounts:');
70+
expect(results[0].region).to.equal('eastus');
71+
done();
72+
});
73+
});
74+
75+
it('should give passing result if automation account has public network access disabled', function (done) {
76+
const cache = createCache([automationAccounts[0]]);
77+
automationAcctPublicAccess.run(cache, {}, (err, results) => {
78+
expect(results.length).to.equal(1);
79+
expect(results[0].status).to.equal(0);
80+
expect(results[0].message).to.include('Automation account has public network access disabled');
81+
expect(results[0].region).to.equal('eastus');
82+
done();
83+
});
84+
});
85+
86+
it('should give failing result if automation account does not have public network access disabled', function (done) {
87+
const cache = createCache([automationAccounts[1]]);
88+
automationAcctPublicAccess.run(cache, {}, (err, results) => {
89+
expect(results.length).to.equal(1);
90+
expect(results[0].status).to.equal(2);
91+
expect(results[0].message).to.include('Automation account does not have public network access disabled');
92+
expect(results[0].region).to.equal('eastus');
93+
done();
94+
});
95+
});
96+
});
97+
});

0 commit comments

Comments
 (0)