diff --git a/.gitignore b/.gitignore index 7d98465..316e9ba 100644 --- a/.gitignore +++ b/.gitignore @@ -423,3 +423,5 @@ override.tf.json terraform.rc deployment/terraform/DONOTCHECKIN deployment/terraform/.terraform.lock.hcl + +**/*.local.* diff --git a/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/README.md b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/README.md new file mode 100644 index 0000000..3faff1f --- /dev/null +++ b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/README.md @@ -0,0 +1,15 @@ +# ARO Secure Baseline - Spoke (Bicep - AVM) + +The purpose of this module is to deploy the spoke resource group and the spoke virtual network. + +## Deployment + +The following resources are deployed as part of the solution: + +- Resource Group +- Virtual Network and Subnets +- Network Security Group +- Route Table +- Route + +The spoke network is also peered with the hub network during the deployment. diff --git a/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/main.bicep b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/main.bicep new file mode 100644 index 0000000..3bb4ddb --- /dev/null +++ b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/main.bicep @@ -0,0 +1,237 @@ +targetScope = 'subscription' + +/* -------------------------------------------------------------------------- */ +/* IMPORTS */ +/* -------------------------------------------------------------------------- */ + +import { + getResourceName + getResourceNameFromParentResourceName +} from '../commonModules/naming/functions.bicep' + +/* -------------------------------------------------------------------------- */ +/* PARAMETERS */ +/* -------------------------------------------------------------------------- */ + +@description('The name of the workload. Defaults to aro-lza.') +@minLength(3) +@maxLength(15) +param workloadName string = 'aro-lza' + +@description('The location of the resources. Defaults to the deployment location.') +param location string = deployment().location + +@description('The type of environment. Defaults to DEV.') +@allowed([ + 'DEV' + 'TST' + 'UAT' + 'PRD' +]) +@minLength(3) +@maxLength(3) +param env string = 'DEV' + +@minLength(3) +@maxLength(5) +@description('The hash to be added to every resource, configuration and exemption name. If not set, a unique string is generated for resources with global name based on its resource group id. The size of the hash is 5 characters.') +param hash string? + +@description('The tags to apply to the resources. Defaults to an object with the environment and workload name.') +param tags object = hash == null ? { + environment: env + workload: workloadName +} : { + environment: env + workload: workloadName + hash: hash +} + +@description('Enable Azure Verified Modules (AVM) telemetry. Defaults to false.') +param enableAvmTelemetry bool = true + +@description('The name of the resource group for the spoke.') +param resourceGroupName string = getResourceName('rg', workloadName, env, hash) + +/* ----------------------------- Virtual Network ---------------------------- */ + +@description('The resource id of the hub virtual network. This is required to peer the spoke virtual network with the hub virtual network.') +param hubVirtualNetworkId string + +@description('The name of the spoke virtual network. Defaults to the naming convention `--[-]`.') +@minLength(1) +@maxLength(64) +param virtualNetworkName string = getResourceName('vnet', workloadName, env, hash) + +@description('The CIDR for the spoke virtual network. Defaults to 10.1.0.0/16.') +param virtualNetworkAddressPrefix string = '10.1.0.0/16' + +@description('The DNS server array (Optional).') +param dnsServers array? + +/* --------------------------- Master Nodes Subnet -------------------------- */ + +@description('The name of the master nodes subnet. Defaults to the naming convention `-aro-master--[-]`.') +@minLength(1) +@maxLength(80) +param masterNodesSubnetName string = getResourceName('snet', 'aro-master-${workloadName}', env, hash) + +@description('The CIDR for the master nodes subnet. Defaults to 10.1.0.0/23.') +param masterNodesSubnetAddressPrefix string = '10.1.0.0/23' + +/* --------------------------- Worker Nodes Subnet -------------------------- */ + +@description('The name of the worker nodes subnet. Defaults to the naming convention `-aro-worker--[-]`.') +@minLength(1) +@maxLength(80) +param workerNodesSubnetName string = getResourceName('snet', 'aro-worker-${workloadName}', env, hash) + +@description('The CIDR for the worker nodes subnet. Defaults to 10.1.2.0/23.') +param workerNodesSubnetAddressPrefix string = '10.1.2.0/23' + +/* ------------------------ Private Endpoints Subnet ------------------------ */ + +@description('The name of the private endpoints subnet. Defaults to the naming convention `-pep--[-]`.') +@minLength(1) +@maxLength(80) +param privateEndpointsSubnetName string = getResourceName('snet', 'pep-${workloadName}', env, hash) + +@description('The CIDR for the private endpoints subnet. Defaults to 10.1.4.0/24.') +param privateEndpointsSubnetAddressPrefix string = '10.1.4.0/24' + +@description('The name of the network security group for the private endpoints subnet. Defaults to the naming convention `-`.') +param privateEndpointsNetworkSecurityGroupName string = getResourceNameFromParentResourceName('nsg', privateEndpointsSubnetName) + +/* ----------------------------- Jumpbox Subnet ----------------------------- */ + +@description('The name of the jumpbox subnet. Defaults to the naming convention `-jumpbox--[-]`.') +@minLength(1) +@maxLength(80) +param jumpboxSubnetName string = getResourceName('snet', 'jumpbox-${workloadName}', env, hash) + +@description('The CIDR for the jumpbox subnet. Defaults to 10.1.5.0/24') +param jumpboxSubnetAddressPrefix string = '10.1.5.0/24' + +@description('The name of the network security group for the jumpbox subnet. Defaults to the naming convention `-`.') +param jumpboxNetworkSecurityGroupName string = getResourceNameFromParentResourceName('nsg', jumpboxSubnetName) + +/* ------------------------------ Other Subnets ----------------------------- */ + +// TODO add the other subnets and their type +// TODO add route table + +/* ------------------------------- Monitoring ------------------------------- */ + +@description('The Log Analytics workspace id. This is required to enable monitoring.') +param logAnalyticsWorkspaceId string + +/* -------------------------------------------------------------------------- */ +/* VARIABLES */ +/* -------------------------------------------------------------------------- */ + +/* --------------------------------- Peering -------------------------------- */ + +var hubVirtualNetworkName = last(split(hubVirtualNetworkId, '/')) + +var remotePeeringName = '${hubVirtualNetworkName}-to-${virtualNetworkName}-peering' + +var peerings = [ + { + name: '${virtualNetworkName}-to-${hubVirtualNetworkName}-peering' + remotePeeringEnabled: true + remotePeeringName: remotePeeringName + remoteVirtualNetworkId: hubVirtualNetworkId + } +] + +/* ------------------------- Netowrk Security Groups ------------------------ */ + +var privateEndpointsNsgSecurityRules = loadJsonContent('nsg/private-endpoints-nsg.jsonc', 'securityRules') + +/* --------------------------------- Subnets -------------------------------- */ + +var subnets = [ + { + name: masterNodesSubnetName + addressPrefix: masterNodesSubnetAddressPrefix + privateLinkServiceNetworkPolicies: 'Disabled' + } + { + name: workerNodesSubnetName + addressPrefix: workerNodesSubnetAddressPrefix + privateLinkServiceNetworkPolicies: 'Disabled' + } + { + name: privateEndpointsSubnetName + addressPrefix: privateEndpointsSubnetAddressPrefix + networkSecurityGroupResourceId: privateEndpointsNetworkSecurityGroup.outputs.resourceId + } + { + name: jumpboxSubnetName + addressPrefix: jumpboxSubnetAddressPrefix + networkSecurityGroupResourceId: jumpboxNetworkSecurityGroup.outputs.resourceId + } +] + +/* ------------------------------- Monitoring ------------------------------- */ + +var diagnosticsSettings = [ + { + logAnalyticsDestinationType: 'AzureDiagnostics' + workspaceResourceId: logAnalyticsWorkspaceId + } +] + +/* -------------------------------------------------------------------------- */ +/* RESOURCES */ +/* -------------------------------------------------------------------------- */ + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +/* ----------------------------- Virtual Network ---------------------------- */ + +module virtualNetwork 'br/public:avm/res/network/virtual-network:0.1.8' = { + name: take('${deployment().name}-virtual-network', 64) + scope: resourceGroup + params: { + name: virtualNetworkName + location: location + tags: tags + enableTelemetry: enableAvmTelemetry + addressPrefixes: [virtualNetworkAddressPrefix] + dnsServers: dnsServers + peerings: peerings + subnets: subnets + diagnosticSettings: diagnosticsSettings + } +} + +/* ------------------------- Netowrk Security Groups ------------------------ */ + +module privateEndpointsNetworkSecurityGroup 'br/public:avm/res/network/network-security-group:0.3.1' = { + name: take('${deployment().name}-private-endpoints-nsg', 64) + scope: resourceGroup + params: { + name: privateEndpointsNetworkSecurityGroupName + location: location + tags: tags + enableTelemetry: enableAvmTelemetry + securityRules: privateEndpointsNsgSecurityRules + diagnosticSettings: diagnosticsSettings + } +} + +module jumpboxNetworkSecurityGroup 'br/public:avm/res/network/network-security-group:0.3.1' = { + name: take('${deployment().name}-jumpbox-nsg', 64) + scope: resourceGroup + params: { + name: jumpboxNetworkSecurityGroupName + location: location + tags: tags + enableTelemetry: enableAvmTelemetry + diagnosticSettings: diagnosticsSettings + } +} diff --git a/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/main.bicepparam b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/main.bicepparam new file mode 100644 index 0000000..bb15e51 --- /dev/null +++ b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/main.bicepparam @@ -0,0 +1,5 @@ +using 'main.bicep' + +param hubVirtualNetworkId = '' + +param logAnalyticsWorkspaceId = '' diff --git a/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/nsg/jumbox-nsg.jsonc b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/nsg/jumbox-nsg.jsonc new file mode 100644 index 0000000..4187871 --- /dev/null +++ b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/nsg/jumbox-nsg.jsonc @@ -0,0 +1,8 @@ +{ + "securityRules": [ + /* --------------------------------- Inbound -------------------------------- */ + + /* -------------------------------- Outbound -------------------------------- */ + + ] +} \ No newline at end of file diff --git a/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/nsg/private-endpoints-nsg.jsonc b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/nsg/private-endpoints-nsg.jsonc new file mode 100644 index 0000000..4187871 --- /dev/null +++ b/Scenarios/Secure-Baseline/bicepWithAVM/02-Spoke/nsg/private-endpoints-nsg.jsonc @@ -0,0 +1,8 @@ +{ + "securityRules": [ + /* --------------------------------- Inbound -------------------------------- */ + + /* -------------------------------- Outbound -------------------------------- */ + + ] +} \ No newline at end of file diff --git a/Scenarios/Secure-Baseline/bicepWithAVM/commonModules/network/types.bicep b/Scenarios/Secure-Baseline/bicepWithAVM/commonModules/network/types.bicep new file mode 100644 index 0000000..e69de29