Convert NSG data in CSV to ARM templates¶
Note
The below script was developed by Nills Franssens https://github.com/NillsF/NSG-CSV-to-ARM
A powershell script to convert CSV file to ARM template for NSG automation. The script itself takes in a CSV file (see example rules.csv for an example) and creates ARM templates as an output. The solution does not do the actual deployment, but does a test of the deployment. This requires you to be logged in to Azure prior to executing the script.
How to use¶
1 2 3 4 | #First login to Azure powershell Login-AzureRMAccount #Execute script convert-csvtoarm.ps1 -filename rules.csv |
rules.csv¶
1 2 3 4 5 | Network rules,direction,Rule Priority,Rule_Name,Access,Protocol,Source,Destination,port,Description private,inbound,100,deny_Telnet-23,deny,*,*,*,23,Block telnet private,inbound,101,allow_ssh,allow,*,*,*,22,Allow SSH private,inbound,4000,deny_rdp,allow,*,*,*,3389,No outbound internet public,inbound,4096,deny_all,deny,*,*,*,*,Foundation |
convert-csvtoarm.ps1¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | param( [Parameter(Mandatory = $true)] [String]$filename ) Write-Host -Object $env:BUILD_SOURCESDIRECTORY $fileindir = "$env:BUILD_SOURCESDIRECTORY\$filename" $rules = Get-Content $fileindir $rules = ConvertFrom-Csv -InputObject $rules -Delimiter ',' $zones = @() foreach ($rule in $rules) { if($zones -contains ($rule.'Network rules')) { } else { $zones += ($rule.'Network rules') } } Write-Host -Object $zones foreach($zone in $zones) { $zonerules = @() foreach ($rule in $rules) { if($rule.'Network rules' -eq $zone) { $rule.source = ($rule.source.Trim().split(';') | ConvertTo-Json) $rule.Destination = ($rule.Destination.Trim().split(';') | ConvertTo-Json) $rule.port = ($rule.port.Trim().split(';') | ConvertTo-Json) $zonerules += $rule } } $rulesfiles = $zonerules $environment = $zone $inboundrules = @() foreach($rule in $rulesfiles) { if($rule.direction -eq 'inbound') { $inboundrules += $rule } } $outboundrules = @() foreach($rule in $rulesfiles) { if($rule.direction -eq 'outbound') { $outboundrules += $rule } } $arm = '{ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [ { "apiVersion": "2017-06-01", "type": "Microsoft.Network/networkSecurityGroups", "name": "' + $environment +'-nsg", "location": "[resourceGroup().location]", "properties": { "securityRules": [ ' foreach($rule in $inboundrules) { $sourceprefix = '""' $sourceprefixes = '""' if($rule.Source.Contains('[')) { $sourceprefixes = $rule.Source } else { $sourceprefix = $rule.Source } $destinationprefix = '""' $destinationprefixes = '""' if($rule.destination.Contains('[')) { $destinationprefixes = $rule.destination } else { $destinationprefix = $rule.destination } $jsonrule = "{ ""name"": ""IN-$($rule.'Rule_Name')"", ""properties"": { ""description"": ""$($rule.Description)"", ""protocol"": ""$($rule.Protocol)"", ""sourcePortRange"": ""*"", ""destinationPortRange"": $($rule.port), ""sourceAddressPrefixes"": $($sourceprefixes), ""destinationAddressPrefixes"": $($destinationprefixes), ""sourceAddressPrefix"": $($sourceprefix), ""destinationAddressPrefix"": $($destinationprefix), ""access"": ""$($rule.Access)"", ""priority"": $($rule.'Rule Priority'), ""direction"": ""$($rule.Direction)"" } }," $arm += $jsonrule } foreach($rule in $outboundrules) { $sourceprefix = '""' $sourceprefixes = '""' if($rule.Source.Contains('[')) { $sourceprefixes = $rule.Source } else { $sourceprefix = $rule.Source } $destinationprefix = '""' $destinationprefixes = '""' if($rule.destination.Contains('[')) { $destinationprefixes = $rule.destination } else { $destinationprefix = $rule.destination } $jsonrule = "{ ""name"": ""OUT-$($rule.'Rule_Name')"", ""properties"": { ""description"": ""$($rule.'Rule_Name')"", ""protocol"": ""$($rule.Protocol)"", ""sourcePortRange"": ""*"", ""destinationPortRange"": $($rule.port), ""sourceAddressPrefixes"": $($sourceprefixes), ""destinationAddressPrefixes"": $($destinationprefixes), ""sourceAddressPrefix"": $($sourceprefix), ""destinationAddressPrefix"": $($destinationprefix), ""access"": ""$($rule.Access)"", ""priority"": $($rule.'Rule Priority'), ""direction"": ""$($rule.Direction)"" } }," $arm += $jsonrule } $arm = $arm.Substring(0,$arm.Length-1) $arm += ' ] } } ], "outputs": { } } ' $filename = $env:BUILD_SOURCESDIRECTORY+'\'+$environment+'_template.json' $arm | Out-File $filename } foreach($zone in $zones) { $deploymentname = "nsgdeployment_$zone" $filename = "$env:BUILD_SOURCESDIRECTORY\$($zone)_template.json" $output = Test-AzureRmResourceGroupDeployment -TemplateFile $filename -ResourceGroupName network-security if ($output) { $o = New-AzureRmResourceGroupDeployment -TemplateFile $filename -ResourceGroupName network-security -Verbose $o $o.Details throw $0.Details } } |