* AKS Archetype - Initial Commit

* Change in pipeline variable group for testing

* Corrected dependency to the teardown of validation resource group

* Corrected the dependsOn for TearDownValidationResourceGroup

* Changed the Azure Subscription

* Changed from SharedServices to AKS in pipeline.yml

* Added missing Tests folder

* Removing duplicate task

* Updates to new modules

* Separate module for application rule

* Update to application rule module

* Clean up

* Cleaned up security center module

* Multiple var groups

* Added var groups for AKS

* Added env vars for User group IDs

* Updated the Packer agent file to include the az cli installation

* Splitting into Archetype and LandingZone

* Updated the paths in pipeline.yml after restructuring folders

* More updates to file paths

* AzureSecurityCenter correction

* Separate module for updating Azure Firewall

* Code fix for prevention of resource group while executing scripts

* Corrections to the orchestration and parameters file

* Added the Azure Firewall update section to the pipeline yml file

* Fixed json parameters file for AKS module that was formatted incorrectly

* Minor fixes to Virtual Network

* Updated the subscription GUIDs and added a subscription info for AKS

* Changed vNet to VirtualNetwork. Also, added dependsOn for AKS Archetype in Orchestration file.

* Changed the KeyVault behavior to enable Service EndPoint after Landing Zone deployment.

* Orchestration and Pipeline updates for AKS Archetype

* AKS Archetype pipeline / orchestration update

* Fixed unsupported versions for aks

* Changes based on feedback from AKS Archetype review

* Minor changes - feedback work continued

* Pipeline changes specific to AKS LandingZone

* AKS Archetype - Initial Commit

* Change in pipeline variable group for testing

* Corrected dependency to the teardown of validation resource group

* Corrected the dependsOn for TearDownValidationResourceGroup

* Changed the Azure Subscription

* Changed from SharedServices to AKS in pipeline.yml

* Added missing Tests folder

* Removing duplicate task

* Updates to new modules

* Separate module for application rule

* Update to application rule module

* Clean up

* Cleaned up security center module

* Multiple var groups

* Added var groups for AKS

* Added env vars for User group IDs

* Updated the Packer agent file to include the az cli installation

* Splitting into Archetype and LandingZone

* Updated the paths in pipeline.yml after restructuring folders

* More updates to file paths

* AzureSecurityCenter correction

* Separate module for updating Azure Firewall

* Code fix for prevention of resource group while executing scripts

* Corrections to the orchestration and parameters file

* Added the Azure Firewall update section to the pipeline yml file

* Fixed json parameters file for AKS module that was formatted incorrectly

* Minor fixes to Virtual Network

* Updated the subscription GUIDs and added a subscription info for AKS

* Changed vNet to VirtualNetwork. Also, added dependsOn for AKS Archetype in Orchestration file.

* Changed the KeyVault behavior to enable Service EndPoint after Landing Zone deployment.

* Orchestration and Pipeline updates for AKS Archetype

* AKS Archetype pipeline / orchestration update

* Fixed unsupported versions for aks

* Changes based on feedback from AKS Archetype review

* Minor changes - feedback work continued

* Pipeline changes specific to AKS LandingZone

* Changes based on testing firewall rules update logic

* Pipeline yml file updated

* Minor update

* Minor update

* Minor update

* Minor correction to file path

* Minor file path correction

* Minor correction

* Debug statements added

* Fix for Azure Firewall scripts

* Updated

* Updated

* Minor update

* Pipeline jobs rearranged.

* File path fixed

* Fixes to chmod script

* Minor fixes

* Updated the dependencies

* Corrected the bootstrap var in pipeline

* Live updates from feedback review

* Fixes based on today's review
This commit is contained in:
Kungumaraj Nachimuthu 2019-08-23 22:48:47 -07:00 коммит произвёл Jorge Cotillo
Родитель e514547774
Коммит 2c83f220e1
99 изменённых файлов: 6866 добавлений и 2778 удалений

Просмотреть файл

@ -38,6 +38,18 @@
}
],
"provisioners": [
{
"type": "shell",
"inline": [
"apt-get update",
"apt-get install -y ca-certificates curl apt-transport-https lsb-release gnupg",
"curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/microsoft.asc.gpg > /dev/null",
"echo 'deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ bionic main' | tee /etc/apt/sources.list.d/azure-cli.list",
"apt-get update",
"apt-get install -y azure-cli"
],
"execute_command": "sudo sh -c '{{ .Vars }} {{ .Path }}'"
},
{
"type": "shell",
"inline": [

Просмотреть файл

@ -1,6 +1,6 @@
{
"Comments": "Toolkit subscription and tenant information",
"TenantId": "00000000000000000000000",
"SubscriptionId": "00000000000000000000000",
"TenantId": "00000000-0000-0000-0000-000000000000",
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"Location": "West US 2"
}

Просмотреть файл

@ -0,0 +1,5 @@
{
"Subscriptions": "env(VDC_SUBSCRIPTIONS)",
"Parameters": "file(./parameters.json)",
"Orchestration": "file(./orchestration.json)"
}

Просмотреть файл

@ -0,0 +1,141 @@
{
"ModuleConfigurationsPath": "../../../Modules",
"ModuleConfigurations": [
{
"Name": "ContainerRegistry",
"ModuleDefinitionName": "ContainerRegistries",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.ContainerRegistry.ResourceGroup}",
"Version": "2.0",
"Deployment": {
"Comments": "We need the 'update' module instance to lock this resource after the Virtual Network got created",
"TemplatePath": "../../../Modules/ContainerRegistries/2.0/deploy.json",
"OverrideParameters": {
"containerRegistryName": {
"value": "${Parameters.ModuleConfigurationParameters.ContainerRegistry.Name}"
},
"location": {
"value": "westus"
}
}
}
},
{
"Name": "AzureKubernetesServices",
"ModuleDefinitionName": "AzureKubernetesServices",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.Kubernetes.ResourceGroup}",
"Version": "2.0",
"Deployment": {
"Comments": "We need the 'update' module instance to lock this resource after the Virtual Network got created",
"TemplatePath": "../../../Modules/AzureKubernetesServices/2.0/deploy.json",
"OverrideParameters": {
"aksClusterName": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterName}"
},
"location": {
"value": "${Parameters.ModuleConfigurationParameters.Region}"
},
"dnsPrefix": {
"value": "${Parameters.ModuleConfigurationParameters.DnsPrefix}"
},
"servicePrincipalClientId": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.ServicePrincipalClientId}"
},
"servicePrincipalClientSecret": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.ServicePrincipalClientSecret}"
},
"osType": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.OsType}"
},
"kubernetesVersion": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.KubernetesVersion}"
},
"networkPlugin": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.NetworkPlugin}"
},
"enableRBAC": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.EnableRbac}"
},
"vNetId": {
"value": "reference(VirtualNetwork.vNetResourceId)"
},
"subnetName": {
"value": "default"
},
"serviceCIDR": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.ServiceCIDR}"
},
"dnsServiceIp": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.DnsServiceIp}"
},
"dockerBridgeCIDR": {
"value": "${Parameters.ModuleConfigurationParameters.Kubernetes.DockerBridgeCIDR}"
},
"logAnalyticsResourceId": {
"value": "reference(LogAnalytics.logAnalyticsWorkspaceResourceId)"
},
"diagnosticsEventHubName": {
"value": "reference(EventHub.diagnosticEventHubName)"
},
"diagnosticsEventHubAuthRuleId": {
"value": "reference(EventHub.diagnosticsEventHubAuthRuleId)"
},
"diagnosticsStorageId": {
"value": "reference(DiagnosticStorageAccount.storageAccountResourceId)"
},
"rbacServerAppId": {
"value":"${Parameters.ModuleConfigurationParameters.Kubernetes.RbacServerAppid}"
},
"rbacServerSecret": {
"value":"${Parameters.ModuleConfigurationParameters.Kubernetes.RbacServerSecret}"
},
"rbacClientAppId": {
"value":"${Parameters.ModuleConfigurationParameters.Kubernetes.RbacClientAppId}"
},
"rbacTenant": {
"value":"${Parameters.ModuleConfigurationParameters.Kubernetes.RbacTenant}"
}
}
}
},
{
"Name": "PermissionsScriptsPreReqs",
"Comments": "PermissionsScriptsPreReqs",
"Script": {
"Command": "chmod +x ../../../Scripts/AKS/install-kubectl.sh",
"Arguments" : {} }
},
{
"Name": "ScriptsPreReqs",
"Comments": "ScriptsPreReqs",
"DependsOn": [
"PermissionsScriptsPreReqs"
],
"Script": {
"Command": "../../../Scripts/AKS/install-kubectl.sh",
"Arguments" : {}
}
},
{
"Name": "CreateClusterRBACRoleBindings",
"Comments": "CreateClusterRBACRoleBindings",
"DependsOn": [
"AzureKubernetesServices",
"ScriptsPreReqs"
],
"Script": {
"Command": "../../../Scripts/AKS/create-cluster-rbac-role-bindings.sh",
"Arguments" : {
"1_SCRIPT_EXECUTION_SP_ID": "env(SCRIPT_EXECUTION_SP_ID)",
"2_SCRIPT_EXECUTION_SP_KEY": "env(SCRIPT_EXECUTION_SP_KEY)",
"3_TENANT": "${Subscriptions.AKS.TenantId}",
"4_CLUSTER_NAME" : "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterName}",
"5_CLUSTER_RG" : "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterResourceGroupName}",
"6_RBAC_CLUSTER_ADMIN_AD_GROUP" : "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterAdminGroupId}",
"7_RBAC_CLUSTER_VIEW_AD_GROUP" : "${Parameters.ModuleConfigurationParameters.Kubernetes.NocUserGroupId}",
"8_RBAC_EXTEND_VIEW_CLUSTER_ROLE" : "Y",
"9_RBAC_ENABLE_READ_ONLY_DASHBOARD" : "Y"
}
}
}
]
}

Просмотреть файл

@ -0,0 +1,107 @@
{
"Organization": "file(../../_Common/organizationName.txt)",
"DeploymentName": "aks",
"InstanceName": "${Parameters.Organization}-${Parameters.DeploymentName}",
"Subscription": "AKS",
"ModuleConfigurationParameters": {
"ResourceGroupPrefix": "${Parameters.Organization}-${Parameters.DeploymentName}",
"Region": "westus2",
"DnsPrefix": "aks",
"Kubernetes": {
"KubernetesVersion": "1.13.9",
"ResourceGroup": "${Parameters.InstanceName}-aks-rg",
"OsType": "Linux",
"NetworkPlugin": "azure",
"MaxPods": 30,
"OsDiskSizeGb": 60,
"AgentCount": 2,
"AgentVmSize": "Standard_DS3_v2",
"EnableRbac": true,
"EnableHttpApplicationRouting": false,
"EnableOmsAgent": true,
"CaCertKeyName": "${Parameters.Organization}-${Parameters.DeploymentName}-ca",
"CaName": "${Parameters.Organization}-${Parameters.DeploymentName}-ca",
"ClusterName": "${Parameters.Organization}-${Parameters.DeploymentName}-k8s",
"ClusterResourceGroupName": "${Parameters.Organization}-${Parameters.DeploymentName}-aks-rg",
"TillerNamespace": "tiller",
"ServicePrincipalClientId": "env(SERVICE_PRINCIPAL_CLIENT_ID)",
"ServicePrincipalClientSecret": "env(SERVICE_PRINCIPAL_CLIENT_SECRET)",
"RbacServerAppid": "env(RBAC_SERVER_APP_ID)",
"RbacServerSecret": "env(RBAC_SERVER_SECRET)",
"RbacClientAppId": "env(RBAC_CLIENT_APP_ID)",
"RbacTenant": "env(RBAC_TENANT)",
"ServiceCIDR": "10.0.0.0/16",
"DnsServiceIp": "10.0.0.10",
"DockerBridgeCIDR": "172.17.0.1/16",
"AksClusterAdminRbacRoleId": "0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8",
"AksClusterUserRbacRoleId": "4abbcc35-e782-43d8-92c5-2d3f1bd2253f",
"ReaderRbacRoleId": "acdd72a7-3385-48ef-bd42-f606fba81ae7",
"ClusterAdminGroupId": "env(CLUSTER_ADMIN_GROUP_ID)",
"NocUserGroupId": "env(NOC_USER_GROUP_ID)",
"DevUserGroupId": "env(DEV_USER_GROUP_ID)",
},
"Rbac": {
"ResourceGroupAssignments": [
{
"Comments": "Azure Service Cluster Admin Role - Use Admin Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.AksClusterAdminRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterAdminGroupId}"
},
{
"Comments": "Azure Service Cluster User Role - Admin",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.AksClusterUserRbacRoleid}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterAdminGroupId}"
},
{
"Comments": "Azure Service Cluster User Role - NOC user",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.AksClusterUserRbacRoleid}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.NocUserGroupId}"
},
{
"Comments": "Azure Service Cluster User Role - Devs",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.AksClusterUserRbacRoleid}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.DevUserGroupId}"
},
{
"Comments": "Reader Role - Use Admin Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ReaderRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterAdminGroupId}"
},
{
"Comments": "Reader Role - Use Dev Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ReaderRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.DevUserGroupId}"
},
{
"Comments": "Reader Role - Use NOC Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ReaderRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.NocUserGroupId}"
}
],
"Comments": "aks-node-resource-group-assignments gets its assignment scope by grabbing a node resource group name from AKS deployment outputs",
"AksNodeResourceGroupAssignments": [
{
"Comments": "Reader Role - Use Admin Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ReaderRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ClusterAdminGroupId}"
},
{
"Comments": "Reader Role - Use Dev Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ReaderRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.DevUserGroupId}"
},
{
"Comments": "Reader Role - Use NOC Persona Principal Id",
"RoleDefinitionId": "${Parameters.ModuleConfigurationParameters.Kubernetes.ReaderRbacRoleId}",
"PrincipalId": "${Parameters.ModuleConfigurationParameters.Kubernetes.NocUserGroupId}"
}
]
},
"ContainerRegistry": {
"Name": "${Parameters.Organization}${Parameters.DeploymentName}acr",
"ResourceGroup": "${Parameters.InstanceName}-acr-rg",
"AdminUserEnabled": true,
"Sku": "Standard"
}
}
}

Просмотреть файл

@ -0,0 +1,208 @@
# VDC Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
# Set variables once
variables:
- group: VDC_SECRETS_Copy
- group: VDC_AKS_SECRETS
trigger:
- master
stages:
- stage: Validate
jobs:
- job: SetupValidationResourceGroup
pool:
name: 'vdc-self-hosted'
steps:
- task: AzurePowerShell@4
displayName: "Setup Validation Resource Group"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ValidationResourceGroupSetup.ps1'
ScriptArguments: '-ResourceGroupName vdc-validation-rg -SetupResourceGroup'
azurePowerShellVersion: 'LatestVersion'
- job: ContainerRegistry
pool:
name: 'vdc-self-hosted'
dependsOn: SetupValidationResourceGroup
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Container Registries"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/ContainerRegistries/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Container Registries"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "ContainerRegistry" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: AzureKubernetesServices
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, ContainerRegistry ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.ContainerRegistry.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Azure Kubernetes Services"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/AzureKubernetesServices/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Azure Kubernetes Services"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "AzureKubernetesServices" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: TearDownValidationResourceGroup
pool:
name: 'vdc-self-hosted'
dependsOn: [ ContainerRegistry, AzureKubernetesServices ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.ContainerRegistry.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Teardown Validation Resource Group"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ValidationResourceGroupSetup.ps1'
ScriptArguments: '-TearDownResourceGroup'
azurePowerShellVersion: 'LatestVersion'
- stage: Deploy
jobs:
- job: ContainerRegistry
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
steps:
- task: AzurePowerShell@4
displayName: "Container Registries"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "ContainerRegistry"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: AzureKubernetesServices
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: ContainerRegistry
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.ContainerRegistry.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Azure Kubernetes Services"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "AzureKubernetesServices"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: ScriptsPreReqs
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: ContainerRegistry
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.ContainerRegistry.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Permissions Scripts Pre Reqs"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "PermissionsScriptsPreReqs"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "Scripts Pre Reqs"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "ScriptsPreReqs"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: CreateClusterRBACRoleBindings
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ AzureKubernetesServices, ScriptsPreReqs, ContainerRegistry ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.ContainerRegistry.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Create Cluster RBAC Role Bindings"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/Archetype/definition.json" -ModuleConfigurationName "CreateClusterRBACRoleBindings"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)

Просмотреть файл

@ -0,0 +1,5 @@
{
"Subscriptions": "env(VDC_SUBSCRIPTIONS)",
"Parameters": "file(./parameters.json)",
"Orchestration": "file(./orchestration.json)"
}

Просмотреть файл

@ -0,0 +1,397 @@
{
"ModuleConfigurationsPath": "../../../Modules",
"ModuleConfigurations": [
{
"Name": "DiagnosticStorageAccount",
"ModuleDefinitionName": "StorageAccounts",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.ResourceGroup}",
"Version": "2.0",
"Policies": {
"Comments": "Optional - If no object is specified, no Policies deployment will occur",
"OverrideParameters": {
"effect": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Policies.Effect}"
},
"resourceGroup": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.ResourceGroup}"
},
"resourceGroupLocation": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Location}"
}
}
},
"Deployment": {
"Comments": "We need the 'update' module instance to lock this resource after the Virtual Network got created",
"TemplatePath": "../../../Modules/StorageAccounts/2.0/deploy.json",
"OverrideParameters": {
"storageAccountName": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Name}"
},
"storageAccountSku": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Sku}"
},
"location": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Location}"
}
}
}
},
{
"Name": "LogAnalytics",
"ModuleDefinitionName": "LogAnalytics",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.LogAnalytics.ResourceGroup}",
"DependsOn": [
"DiagnosticStorageAccount"
],
"Deployment": {
"OverrideParameters": {
"logAnalyticsWorkspaceName": {
"value": "${Parameters.ModuleConfigurationParameters.LogAnalytics.Name}"
},
"diagnosticStorageAccountName": {
"value": "reference(DiagnosticStorageAccount.storageAccountName)"
},
"diagnosticStorageAccountId": {
"value": "reference(DiagnosticStorageAccount.storageAccountResourceId)"
},
"diagnosticStorageAccountAccessKey": {
"value": "reference(DiagnosticStorageAccount.storageAccountAccessKey)"
},
"location": {
"value": "${Parameters.ModuleConfigurationParameters.LogAnalytics.Location}"
}
}
}
},
{
"Name": "AzureSecurityCenter",
"ModuleDefinitionName": "AzureSecurityCenter",
"DependsOn": [
"LogAnalytics"
],
"Deployment": {
"OverrideParameters": {
"workspaceId": {
"value": "reference(LogAnalytics.logAnalyticsWorkspaceResourceId)"
}
}
}
},
{
"Name": "EventHub",
"ModuleDefinitionName": "EventHub",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.EventHub.ResourceGroup}",
"Deployment": {
"OverrideParameters": {
"location": {
"value": "${Parameters.ModuleConfigurationParameters.EventHub.Location}"
},
"eventHubName": {
"value": "${Parameters.ModuleConfigurationParameters.EventHub.Name}"
},
"eventHubSku": {
"value": "Standard"
},
"namespaceName": {
"value": "${Parameters.ModuleConfigurationParameters.EventHub.Namespace}"
},
"consumerGroupName": {
"value": "${Parameters.ModuleConfigurationParameters.EventHub.ConsumerGroupName}"
}
}
}
},
{
"Name": "DefaultNSG",
"ModuleDefinitionName": "NetworkSecurityGroups",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.ResourceGroup}",
"DependsOn": [
"LogAnalytics",
"DiagnosticStorageAccount"
],
"Deployment": {
"OverrideParameters": {
"workspaceId": {
"value": "reference(LogAnalytics.logAnalyticsWorkspaceResourceId)"
},
"diagnosticStorageAccountId": {
"value": "reference(DiagnosticStorageAccount.storageAccountResourceId)"
},
"networkSecurityGroupName": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.NetworkSecurityGroups[0].Name}"
},
"networkSecurityGroupSecurityRules": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.NetworkSecurityGroups[0].Rules}"
}
}
}
},
{
"Name": "DefaultRouteTable",
"ModuleDefinitionName": "RouteTables",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.ResourceGroup}",
"Deployment": {
"OverrideParameters": {
"routeTableName": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.UserDefinedRoutes[0].Name}"
},
"routes": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.UserDefinedRoutes[0].Routes}"
}
}
}
},
{
"Name": "VirtualNetwork",
"ModuleDefinitionName": "VirtualNetwork",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.ResourceGroup}",
"DependsOn": [
"LogAnalytics",
"DiagnosticStorageAccount",
"DefaultRouteTable",
"DefaultNSG"
],
"Deployment": {
"OverrideParameters": {
"vnetName": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.Name}"
},
"vnetAddressPrefixes": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.AddressPrefixes}"
},
"dnsServers": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.DnsServers}"
},
"subnets": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.Subnets}"
},
"enableDdosProtection": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.EnableDdosProtection}"
},
"enableVmProtection": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.EnableVmProtection}"
}
}
}
},
{
"Name": "LocalVirtualNetworkPeering",
"ModuleDefinitionName": "VirtualNetworkPeering",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.ResourceGroup}",
"DependsOn": [
"VirtualNetwork"
],
"Deployment": {
"OverrideParameters": {
"localVnetName": {
"value": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.Name}"
},
"peeringName": {
"value": "aks-shared-peering"
},
"remoteVirtualNetworkId": {
"value": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.Id}"
},
"useRemoteGateways": {
"value": false
}
}
}
},
{
"Name": "RemoteVirtualNetworkPeering",
"ModuleDefinitionName": "VirtualNetworkPeering",
"Subscription": "SharedServices",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.ResourceGroupName}",
"DependsOn": [
"VirtualNetwork"
],
"Deployment": {
"OverrideParameters": {
"localVnetName": {
"value": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.Name}"
},
"peeringName": {
"value": "shared-aks-peering"
},
"remoteVirtualNetworkId": {
"value": "reference(VirtualNetwork.vNetResourceId)"
},
"useRemoteGateways": {
"value": false
}
}
}
},
{
"Name": "EnableServiceEndPointOnDiagnosticStorageAccount",
"ModuleDefinitionName": "StorageAccounts",
"Updates": "DiagnosticStorageAccount",
"Comments": "Enables Service endpoint on the Storage Account",
"DependsOn": [
"VirtualNetwork"
],
"Deployment": {
"OverrideParameters": {
"networkAcls": {
"value": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.NetworkAcls}"
},
"vNetId": {
"value": "reference(VirtualNetwork.vNetResourceId)"
}
}
}
},
{
"Name": "KeyVault",
"ModuleDefinitionName": "KeyVault",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.KeyVault.ResourceGroup}",
"DependsOn": [
"DiagnosticStorageAccount",
"LogAnalytics",
"VirtualNetwork"
],
"Deployment": {
"OverrideParameters": {
"keyVaultName": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.Name}"
},
"accessPolicies": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.AccessPolicies}"
},
"secretsObject": {
"value": {
"secrets": "${Parameters.ModuleConfigurationParameters.KeyVault.SecretsObject.Secrets}"
}
},
"enableVaultForDeployment": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.EnableVaultForDeployment}"
},
"enableVaultForDiskEncryption": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.EnableVaultForDiskEncryption}"
},
"enableVaultForTemplateDeployment": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.EnableVaultForTemplateDeployment}"
},
"vaultSku": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.Sku}"
},
"diagnosticStorageAccountId": {
"value": "reference(DiagnosticStorageAccount.storageAccountResourceId)"
},
"workspaceId": {
"value": "reference(LogAnalytics.logAnalyticsWorkspaceResourceId)"
},
"vNetId": {
"value": "reference(VirtualNetwork.vNetResourceId)"
},
"networkAcls": {
"value": {
"bypass": "AzureServices",
"defaultAction": "Allow",
"virtualNetworkRules": [],
"ipRules": []
}
}
}
}
},
{
"Name": "ConsolidateApplicationRules",
"Comments": "ConsolidateApplicationRules",
"Script": {
"Command": "../../../Modules/AzureFirewall/2.0/Scripts/azure.firewall.addrulecollection.ps1",
"Arguments" : {
"SubscriptionId": "${Subscriptions.SharedServices.SubscriptionId}",
"AzureFirewallName": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.NetworkVirtualAppliance.AzureFirewall.Name}",
"AzureFirewallResourceGroup": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.ResourceGroupName}",
"RuleCollections": "'${Parameters.ModuleConfigurationParameters.VirtualNetwork.AzureFirewallApplicationRuleCollection}'",
"RuleType": "application"
}
}
},
{
"Name": "ConsolidateNetworkRules",
"Comments": "ConsolidateNetworkRules",
"Script": {
"Command": "../../../Modules/AzureFirewall/2.0/Scripts/azure.firewall.addrulecollection.ps1",
"Arguments" : {
"SubscriptionId": "${Subscriptions.SharedServices.SubscriptionId}",
"AzureFirewallName": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.NetworkVirtualAppliance.AzureFirewall.Name}",
"AzureFirewallResourceGroup": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.ResourceGroupName}",
"RuleCollections": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.AzureFirewallNetworkRuleCollection}",
"RuleType": "network"
}
}
},
{
"Name": "UpdateAzureFirewall",
"ModuleDefinitionName": "AzureFirewall",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.Kubernetes.ResourceGroup}",
"Version": "2.0",
"DependsOn": [
"ConsolidateNetworkRules",
"ConsolidateApplicationRules"
],
"Deployment": {
"Comments": "We need the 'update' module instance to lock this resource after the Virtual Network got created",
"TemplatePath": "../../../Modules/UpdateAzureFirewall/2.0/deploy.json",
"OverrideParameters": {
"azureFirewallName": {
"value": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.NetworkVirtualAppliance.AzureFirewall.Name}"
},
"azureFirewallResourceGroupName": {
"value": "${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.ResourceGroupName}"
},
"azureFirewallSubscriptionId": {
"value": "${Subscriptions.SharedServices.SubscriptionId}"
},
"azureFirewallNatRuleCollection": {
"value": []
},
"azureFirewallApplicationRuleCollection": {
"value": "reference(ConsolidateApplicationRules.output)"
},
"azureFirewallNetworkRuleCollection": {
"value": "reference(ConsolidateNetworkRules.output)"
}
}
}
},
{
"Name": "CreateCACertificate",
"Comments": "CreateCACertificate",
"dependsOn": [ "KeyVault" ],
"Script": {
"Command": "../../../Scripts/AKS/create-and-upload-ca-cert.sh",
"Arguments" : {
"1_SCRIPT_EXECUTION_SP_ID": "env(SCRIPT_EXECUTION_SP_ID)",
"2_SCRIPT_EXECUTION_SP_KEY": "env(SCRIPT_EXECUTION_SP_KEY)",
"3_TENANT": "${Subscriptions.AKS.TenantId}",
"4_KEY_VAULT_NAME" : "${Parameters.ModuleConfigurationParameters.KeyVault.Name}",
"5_CA_CERT_KEY_NAME" : "${Parameters.ModuleConfigurationParameters.Kubernetes.CaCertKeyName}",
"6_CA_NAME" : "${Parameters.ModuleConfigurationParameters.Kubernetes.CaName}"
}
}
},
{
"Name": "EnableServiceEndpointOnKeyVault",
"ModuleDefinitionName": "KeyVault",
"Updates": "KeyVault",
"ResourceGroupName": "${Parameters.ModuleConfigurationParameters.KeyVault.ResourceGroup}",
"DependsOn": [
"CreateClusterRBACRoleBindings"
],
"Deployment": {
"OverrideParameters": {
"networkAcls": {
"value": "${Parameters.ModuleConfigurationParameters.KeyVault.NetworkAcls}"
},
"vNetId": {
"value": "reference(VirtualNetwork.vNetResourceId)"
}
}
}
}
]
}

Просмотреть файл

@ -0,0 +1,375 @@
{
"Organization": "file(../../_Common/organizationName.txt)",
"DeploymentName": "aks",
"InstanceName": "${Parameters.Organization}-${Parameters.DeploymentName}",
"Subscription": "AKS",
"ModuleConfigurationParameters": {
"DeploymentUserId": "env(DEPLOYMENT_USER_ID)",
"DeploymentAppId": "env(DEPLOYMENT_APP_ID)",
"ResourceGroupPrefix": "${Parameters.Organization}-${Parameters.DeploymentName}",
"Region": "westus2",
"DnsPrefix": "aks",
"SharedServices": {
"DeploymentName": "shrdsvcs",
"ActiveDirectory": {
"VmIpAddressStart": [ "172.0.0.10" ]
},
"VirtualNetwork": {
"Id": "/subscriptions/${Subscriptions.SharedServices.SubscriptionId}/resourceGroups/${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.ResourceGroupName}/providers/Microsoft.Network/virtualNetworks/${Parameters.ModuleConfigurationParameters.SharedServices.VirtualNetwork.Name}",
"Name": "${Parameters.Organization}-${Parameters.ModuleConfigurationParameters.SharedServices.DeploymentName}-vnet",
"ResourceGroupName": "${Parameters.Organization}-${Parameters.ModuleConfigurationParameters.SharedServices.DeploymentName}-network-rg",
"AddressPrefix": "10.4.0.32/27",
"NetworkVirtualAppliance": {
"EgressIp": "10.4.1.4",
"AzureFirewall": {
"Name": "${Parameters.Organization}-${Parameters.ModuleConfigurationParameters.SharedServices.DeploymentName}-azfw"
}
}
}
},
"KeyVault": {
"Name": "${Parameters.Organization}-${Parameters.DeploymentName}-kv",
"ResourceGroup": "${Parameters.InstanceName}-keyvault-rg",
"Sku": "Premium",
"EnableVaultForDeployment": true,
"EnableVaultForDiskEncryption": true,
"EnableVaultForTemplateDeployment": true,
"AccessPolicies": [
{
"tenantId": "${Subscriptions.AKS.TenantId}",
"objectId": "${Parameters.ModuleConfigurationParameters.DeploymentUserId}",
"permissions": {
"certificates": [
"All"
],
"keys": [
"All"
],
"secrets": [
"All"
]
}
},
{
"tenantId": "${Subscriptions.AKS.TenantId}",
"objectId": "${Parameters.ModuleConfigurationParameters.DeploymentAppId}",
"permissions": {
"certificates": [
"All"
],
"keys": [
"All"
],
"secrets": [
"All"
]
}
}
],
"SecretsObject": {
"Comments": "Creating an object so we can use a secretsobject parameter type in our ARM template",
"Secrets": [ ]
},
"NetworkAcls": {
"bypass": "AzureServices",
"defaultAction": "Deny",
"virtualNetworkRules": [
{
"subnet": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.Subnets[0].Name}"
}
],
"ipRules": []
}
},
"DiagnosticStorageAccount": {
"Name": "${Parameters.Organization}${Parameters.DeploymentName}diag01",
"ResourceGroup": "${Parameters.InstanceName}-diagnostics-rg",
"Location": "${Parameters.Location}",
"Sku": "Standard_GRS",
"NetworkAcls": {
"bypass": "AzureServices",
"defaultAction": "Deny",
"virtualNetworkRules": [
{
"subnet": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.Subnets[0].Name}"
}
],
"ipRules": []
},
"Policies": {
"Effect": "Audit"
}
},
"VirtualNetwork": {
"Name": "${Parameters.InstanceName}-vnet",
"ResourceGroup": "${Parameters.InstanceName}-network-rg",
"EnableDdosProtection": false,
"EnableVmProtection": false,
"AddressPrefixes": ["10.2.0.0/16"],
"ApplicationSecurityGroups": [],
"AzureFirewallNetworkRuleCollection": [
{
"name": "aks-cluster-nrc-01",
"properties": {
"priority": "500",
"action": {
"type": "Allow"
},
"rules": [
{
"name": "allow-ssh-access",
"description": "Allows outbound SSH access",
"protocols": [
"TCP"
],
"sourceAddresses": [
"${Parameters.ModuleConfigurationParameters.VirtualNetwork.Subnets[0].AddressPrefix}"
],
"destinationAddresses": [
"*"
],
"destinationPorts": [
"22"
]
}
]
}
}
],
"AzureFirewallApplicationRuleCollection": [
{
"name": "aks-cluster-01",
"properties": {
"priority": 500,
"action": {
"type": "Allow"
},
"rules": [
{
"name": "cluster",
"protocols": [
{
"protocolType": "Http",
"port": 80
},
{
"protocolType": "Https",
"port": 443
}
],
"fqdnTags": [],
"targetFqdns": [
"*"
],
"sourceAddresses": [
"${Parameters.ModuleConfigurationParameters.VirtualNetwork.Subnets[0].AddressPrefix}"
]
}
]
}
}
],
"NetworkSecurityGroups": [
{
"Name": "default",
"Rules": [
{
"Name": "allow-azure-loadbalancer",
"Properties": {
"Access": "Allow",
"DestinationAddressPrefixes": [],
"DestinationAddressPrefix": "VirtualNetwork",
"DestinationPortRange": "*",
"DestinationPortRanges":[],
"DestinationApplicationSecurityGroups": [],
"Direction": "Inbound",
"Priority": 100,
"Protocol": "*",
"SourcePortRange": "*",
"SourcePortRanges": [],
"SourceAddressPrefix": "AzureLoadBalancer",
"SourceApplicationSecurityGroups":[]
}
},
{
"Name": "allow-ssh",
"Properties": {
"Access": "Allow",
"DestinationAddressPrefixes": [],
"DestinationAddressPrefix": "VirtualNetwork",
"DestinationPortRange": "22",
"DestinationPortRanges": [],
"DestinationApplicationSecurityGroups": [],
"Direction": "Inbound",
"Priority": 110,
"Protocol": "Tcp",
"SourcePortRange": "*",
"SourcePortRanges": [],
"SourceAddressPrefix": "10.4.0.32/27",
"SourceApplicationSecurityGroups": []
}
},
{
"Name": "allow-http",
"Properties": {
"Access": "Allow",
"DestinationAddressPrefixes": [],
"DestinationAddressPrefix": "VirtualNetwork",
"DestinationPortRange": "80",
"DestinationPortRanges": [],
"DestinationApplicationSecurityGroups": [],
"Direction": "Inbound",
"Priority": 120,
"Protocol": "*",
"SourcePortRange": "*",
"SourcePortRanges": [],
"SourceAddressPrefix": "VirtualNetwork",
"SourceApplicationSecurityGroups": []
}
},
{
"Name": "allow-https",
"Properties": {
"Access": "Allow",
"DestinationAddressPrefixes": [],
"DestinationAddressPrefix": "VirtualNetwork",
"DestinationPortRange": "443",
"DestinationPortRanges": [],
"DestinationApplicationSecurityGroups": [],
"Direction": "Inbound",
"Priority": 130,
"Protocol": "*",
"SourcePortRange": "*",
"SourcePortRanges": [],
"SourceAddressPrefix": "VirtualNetwork",
"SourceApplicationSecurityGroups": []
}
},
{
"Name": "deny-internet",
"Properties": {
"Access": "Deny",
"DestinationAddressPrefix": "*",
"DestinationAddressPrefixes": [],
"DestinationPortRange": "*",
"DestinationPortRanges": [],
"DestinationApplicationSecurityGroups": [],
"Direction": "Inbound",
"Priority": 4095,
"Protocol": "Tcp",
"SourcePortRange": "*",
"SourcePortRanges": [],
"SourceAddressPrefix": "Internet",
"SourceApplicationSecurityGroups": []
}
},
{
"Name": "deny-vnet",
"Properties": {
"Access": "Deny",
"DestinationAddressPrefix": "VirtualNetwork",
"DestinationAddressPrefixes": [],
"DestinationPortRange": "*",
"DestinationPortRanges": [],
"DestinationApplicationSecurityGroups": [],
"Direction": "Inbound",
"Priority": 4096,
"Protocol": "Tcp",
"SourcePortRange": "*",
"SourcePortRanges": [],
"SourceAddressPrefix": "VirtualNetwork",
"SourceApplicationSecurityGroups": []
}
}
]
}
],
"UserDefinedRoutes": [
{
"Name": "default",
"Routes": [
{
"Name": "default",
"Properties": {
"AddressPrefix": "0.0.0.0/0",
"NextHopIpAddress": "172.0.3.4",
"NextHopType": "VirtualAppliance"
}
},
{
"Name": "to-on-premises",
"Properties": {
"AddressPrefix": "192.168.1.0/28",
"NextHopType": "VirtualNetworkGateway"
}
}
]
}
],
"Subnets": [
{
"name": "default",
"addressPrefix": "10.2.0.0/17",
"networkSecurityGroupName": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.NetworkSecurityGroups[0].Name}",
"userDefinedRoute": "",
"routeTableName": "${Parameters.ModuleConfigurationParameters.VirtualNetwork.UserDefinedRoutes[0].Name}",
"serviceEndpoints": [
{
"Service": "Microsoft.EventHub"
},
{
"Service": "Microsoft.Sql"
},
{
"Service": "Microsoft.KeyVault"
},
{
"Service": "Microsoft.Storage"
}
]
}
],
"DnsServers": "${Parameters.ModuleConfigurationParameters.SharedServices.ActiveDirectory.VmIpAddressStart}"
},
"Kubernetes": {
"ResourceGroup": "${Parameters.InstanceName}-aks-rg",
"CaCertKeyName": "${Parameters.Organization}-${Parameters.DeploymentName}-ca",
"CaName": "${Parameters.Organization}-${Parameters.DeploymentName}-ca"
},
"LogAnalytics": {
"Name": "${Parameters.InstanceName}-la",
"Comments": "Log Analytics and Diagnostic Storage Account must be deployed in the same region",
"ResourceGroup": "${Parameters.InstanceName}-diagnostics-rg",
"Location": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Location}",
"ListOfAllowedRegions": [
"Australia Central",
"Australia East",
"Australia Southeast",
"Canada Central",
"Central India",
"Central US",
"East Asia",
"East US",
"East US 2",
"France Central",
"Japan East",
"Korea Central",
"North Europe",
"South Central US",
"Southeast Asia",
"UK South",
"West Europe",
"West US",
"West US 2"
]
},
"EventHub": {
"ResourceGroup": "${Parameters.InstanceName}-diagnostics-rg",
"Location": "${Parameters.ModuleConfigurationParameters.DiagnosticStorageAccount.Location}",
"Namespace": "${Parameters.Organization}eventhubnamespace",
"Name": "${Parameters.Organization}-diagnostics-eventhub",
"ConsumerGroupName": "${Parameters.Organization}eventconsumergroup1",
"Sku": "Standard"
}
}
}

Просмотреть файл

@ -0,0 +1,739 @@
# VDC Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
# Set variables once
variables:
- group: VDC_SECRETS_Copy
- group: VDC_AKS_SECRETS
trigger:
- master
stages:
- stage: Validate
jobs:
- job: SetupValidationResourceGroup
pool:
name: 'vdc-self-hosted'
steps:
- task: AzurePowerShell@4
displayName: "Setup Validation Resource Group"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ValidationResourceGroupSetup.ps1'
ScriptArguments: '-ResourceGroupName vdc-validation-rg -SetupResourceGroup'
azurePowerShellVersion: 'LatestVersion'
- job: StorageAccounts
pool:
name: 'vdc-self-hosted'
dependsOn: SetupValidationResourceGroup
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Storage Accounts"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/StorageAccounts/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Diagnostic Storage Account"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "DiagnosticStorageAccount" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "ARM Validation - Enable Service EndPoint On Diagnostic Storage Account"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "EnableServiceEndPointOnDiagnosticStorageAccount" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: LogAnalytics
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Log Analytics"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/LogAnalytics/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Log Analytics"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "LogAnalytics" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: SecurityCenter
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Security Center"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/AzureSecurityCenter/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Security Center"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "AzureSecurityCenter" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: EventHub
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - EventHub"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/EventHub/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - EventHub"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "EventHub" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: NetworkSecurityGroup
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Network Security Groups"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/NetworkSecurityGroups/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Network Security Groups"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "DefaultNSG" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: RouteTable
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Route Tables"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/RouteTables/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - RouteTables"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "DefaultRouteTable" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: VirtualNetwork
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - Virtual Net"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/VirtualNetwork/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Virtual Network"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "VirtualNetwork" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: PowerShell@2
displayName: "Pester Tests for Module - Virtual Network Peering"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/VirtualNetworkPeering/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - VirtualNetwork Peering To AKS"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "LocalVirtualNetworkPeering" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "ARM Validation - VirtualNetwork Peering From AKS"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "RemoteVirtualNetworkPeering" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: KeyVault
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - KeyVault"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/KeyVault/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - KeyVault"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "KeyVault" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "ARM Validation - Enable Service Endpoint on Key Vault"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "EnableServiceEndpointOnKeyVault" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: UpdateAzureFirewall
pool:
name: 'vdc-self-hosted'
dependsOn: [ SetupValidationResourceGroup, StorageAccounts ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: PowerShell@2
displayName: "Pester Tests for Module - UpdateAzureFirewall"
inputs:
targetType: 'inline'
script: '# Write your powershell commands here.
Invoke-Pester -Script "./Modules/UpdateAzureFirewall/2.0/Tests";
# Use the environment variables input below to pass secret variables to this script.'
pwsh: true
- task: AzurePowerShell@4
displayName: "ARM Validation - Update Azure Firewall"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "UpdateAzureFirewall" -Validate'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: TearDownValidationResourceGroup
pool:
name: 'vdc-self-hosted'
dependsOn: [ StorageAccounts, LogAnalytics, SecurityCenter, EventHub, NetworkSecurityGroup, RouteTable, VirtualNetwork, KeyVault ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.StorageAccounts.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Teardown Validation Resource Group"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ValidationResourceGroupSetup.ps1'
ScriptArguments: '-TearDownResourceGroup'
azurePowerShellVersion: 'LatestVersion'
- stage: Deploy
jobs:
- job: DiagnosticStorageAccount
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
steps:
- task: AzurePowerShell@4
displayName: "Diagnostics Storage Account"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "DiagnosticStorageAccount"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: LogAnalytics
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: DiagnosticStorageAccount
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Log Analytics"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "LogAnalytics"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: SecurityCenter
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ LogAnalytics, DiagnosticStorageAccount ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Security Center"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "AzureSecurityCenter"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: EventHub
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
dependsOn: DiagnosticStorageAccount
steps:
- task: AzurePowerShell@4
displayName: "Event Hub"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "EventHub"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: DefaultNSG
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ LogAnalytics, DiagnosticStorageAccount ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Network Security Groups"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "DefaultNSG"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: DefaultRouteTable
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: DiagnosticStorageAccount
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Route Tables"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "DefaultRouteTable"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: VirtualNetwork
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ LogAnalytics, DiagnosticStorageAccount, DefaultRouteTable, DefaultNSG ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Virtual Network"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "VirtualNetwork"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "Local Virtual Network Peering"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "LocalVirtualNetworkPeering"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "Remote Virtual Network Peering"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "RemoteVirtualNetworkPeering"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: EnableServiceEndPointOnDiagnosticStorageAccount
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ VirtualNetwork, DiagnosticStorageAccount ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Enable Service Endpoint On Diagnostic Storage Account"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "EnableServiceEndpointOnDiagnosticStorageAccount"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: KeyVault
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ DiagnosticStorageAccount, LogAnalytics, VirtualNetwork ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Key Vault"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "KeyVault"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: PrepareRuleCollectionForUpdate
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: DiagnosticStorageAccount
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Consolidate Application Rules"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "ConsolidateApplicationRules"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- task: AzurePowerShell@4
displayName: "Consolidate Network Rules"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "ConsolidateNetworkRules"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: UpdateAzureFirewall
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ PrepareRuleCollectionForUpdate, DiagnosticStorageAccount ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Add Rules To Azure Firewall"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "UpdateAzureFirewall" -Debug'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: CreateCACertificate
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ KeyVault, DiagnosticStorageAccount ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Create CA Certificate"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "CreateCACertificate"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)
- job: EnableServiceEndpointOnKeyVault
timeoutInMinutes: 0
pool:
name: 'vdc-self-hosted'
dependsOn: [ CreateCACertificate, DiagnosticStorageAccount ]
variables:
BOOTSTRAP_INITIALIZED: $[dependencies.DiagnosticStorageAccount.outputs['bootstratInitializedOutput.BOOTSTRAP_INITIALIZED']]
steps:
- task: AzurePowerShell@4
displayName: "Enable Service Endpoint On Key Vault"
inputs:
azureSubscription: 'Kunachim Azure SC'
ScriptType: 'FilePath'
ScriptPath: 'Orchestration/OrchestrationService/ModuleConfigurationDeployment.ps1'
ScriptArguments: '-DefinitionPath "Environments/AKS/LandingZone/definition.json" -ModuleConfigurationName "EnableServiceEndpointOnKeyVault"'
azurePowerShellVersion: 'LatestVersion'
env:
VDC_SUBSCRIPTIONS: $(VDC_SUBSCRIPTIONS)
VDC_TOOLKIT_SUBSCRIPTION: $(VDC_TOOLKIT_SUBSCRIPTION)
DEPLOYMENT_USER_ID: $(DEPLOYMENT_USER_ID)
ADMIN_USER_PWD: $(ADMIN_USER_PWD)
DOMAIN_ADMIN_USER_PWD: $(DOMAIN_ADMIN_USER_PWD)
TENANT_ID: $(TENANT_ID)

Просмотреть файл

@ -1 +1 @@
fontoso
knvdc

Просмотреть файл

@ -2,20 +2,26 @@
"Comments": "Dashes are not supported as part of a Subscription name",
"OnPremises": {
"Comments": "Simulated On-Premises subscription and tenant information",
"TenantId": "00000000000000000000000",
"SubscriptionId": "00000000000000000000000",
"TenantId": "00000000-0000-0000-0000-000000000000",
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"Location": "West US 2"
},
"SharedServices": {
"Comments": "Shared services subscription and tenant information",
"TenantId": "00000000000000000000000",
"SubscriptionId": "00000000000000000000000",
"TenantId": "00000000-0000-0000-0000-000000000000",
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"Location": "West US 2"
},
"AKS": {
"Comments": "Shared services subscription and tenant information",
"TenantId": "00000000-0000-0000-0000-000000000000",
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"Location": "West US 2"
},
"ASE_SQLDB": {
"Comments": "Workload subscription and tenant information",
"TenantId": "00000000000000000000000",
"SubscriptionId": "00000000000000000000000",
"TenantId": "00000000-0000-0000-0000-000000000000",
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"Location": "West US 2"
},
"NTier_IaaS": {
@ -26,8 +32,8 @@
},
"Artifacts": {
"Comments": "Subscription and tenant information where the Artifacts Storage Account will reside",
"TenantId": "00000000000000000000000",
"SubscriptionId": "00000000000000000000000",
"TenantId": "00000000-0000-0000-0000-000000000000",
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"Location": "West US"
}
}

Просмотреть файл

@ -5,6 +5,19 @@
"virtualMachineName": {
"value": "adds"
},
"virtualMachineCount": {
"value": 2
},
"virtualMachineSize": {
"value": "Standard_DS2_v2"
},
"virtualMachineOSImage": {
"value": {
"offer": "WindowsServer",
"publisher": "MicrosoftWindowsServer",
"sku": "2016-Datacenter"
}
},
"artifactsStorageAccountSasKey": {
"value": ""
},
@ -29,6 +42,9 @@
"ADSitename": {
"value": "Cloud-Site"
},
"domaincontrollerDriveLetter": {
"value": "F"
},
"domainAdminUsername": {
"value": "contoso"
},

Просмотреть файл

@ -0,0 +1,79 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"virtualMachineName": {
"value": "adds"
},
"virtualMachineCount": {
"value": 2
},
"virtualMachineSize": {
"value": "Standard_DS2_v2"
},
"virtualMachineOSImage": {
"value": {
"offer": "WindowsServer",
"publisher": "MicrosoftWindowsServer",
"sku": "2016-Datacenter"
}
},
"artifactsStorageAccountSasKey": {
"value": ""
},
"artifactsStorageAccountName": {
"value": "vdcstorage"
},
"artifactsStorageAccountKey": {
"value": ""
},
"workspaceId": {
"value": "00000000-0000-0000-0000-000000000000"
},
"logAnalyticsWorkspacePrimarySharedKey": {
"value": ""
},
"diagnosticsStorageAccountName": {
"value": "contoso-diag-storage"
},
"diagnosticsStorageAccountSasToken": {
"value": ""
},
"addsAddressStart": {
"value": "11.4.0.46"
},
"vNetId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup/providers/Microsoft.Network/virtualNetworks/contoso-vnet-example"
},
"domainControllerAsgId": {
"value": "dc"
},
"subnetName": {
"value": "sharedsvcs"
},
"adminUsername": {
"value": "admin-user"
},
"adminPassword": {
"value": "password"
},
"domainName": {
"value": "contoso.com"
},
"primaryDCIP": {
"value": "192.168.1.4"
},
"ADSitename": {
"value": "Cloud-Site"
},
"domaincontrollerDriveLetter": {
"value": "F"
},
"domainAdminUsername": {
"value": "contoso"
},
"domainAdminPassword": {
"value": "password"
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"virtualMachineName": {
"value": "adds"
},
"artifactsStorageAccountSasKey": {
"value": ""
},
"artifactsStorageAccountName": {
"value": "vdcstorage"
},
"artifactsStorageAccountKey": {
"value": ""
},
"addsAddressStart": {
"value": "11.4.0.46"
},
"domainName": {
"value": "contoso.com"
},
"primaryDCIP": {
"value": "192.168.1.4"
},
"ADSitename": {
"value": "Cloud-Site"
},
"domainAdminUsername": {
"value": "contoso"
},
"domainAdminPassword": {
"value": "password"
}
}
}

Просмотреть файл

@ -0,0 +1,100 @@
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[string]$SubscriptionId,
[Parameter(Mandatory=$True)]
[string]$AzureFirewallName,
[Parameter(Mandatory=$True)]
[string]$AzureFirewallResourceGroup,
[Parameter(Mandatory=$True)]
[array]$RuleCollections,
[Parameter(Mandatory=$True)]
[string]$RuleType
)
Function ConvertTo-HashTable() {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
$InputObject
)
if($InputObject) {
# Convert to string prior to converting to
# hashtable
$objectString = `
ConvertTo-Json `
-InputObject $InputObject `
-Depth 100;
# Convert string to hashtable and return it
return `
ConvertFrom-Json `
-InputObject $objectString `
-AsHashtable;
}
else {
return $null;
}
}
# Construct the Resource Id for Azure Firewall using subscription id, resource group name and azure firewall name
$azureFirewallId = "/subscriptions/$SubscriptionId/resourceGroups/$AzureFirewallResourceGroup/providers/Microsoft.Network/azureFirewalls/$AzureFirewallName";
# Get the current state of the Azure Firewall from Graph
$azfw = Search-AzGraph -Query "where id == '$azureFirewallId'";
if($null -ne $azfw) {
# Convert AzureFirewall object to hashtable
$azfw = ConvertTo-HashTable -InputObject $azfw;
# Convert Rule Collection passed to this script into hashtable
$RuleCollections= ConvertTo-HashTable -InputObject $RuleCollections;
if($RuleType -eq "application") {
$RuleCollectionType = "applicationRuleCollections";
}
elseif($RuleType -eq "network") {
$RuleCollectionType = "networkRuleCollections"
}
else {
Throw "This Rule Type is not supported by this script.";
}
$RuleCollections | ForEach-Object {
$RuleCollection = $_;
# Retrive the specific application rule collection by name from the Azure Firewall
$currentRuleCollection = `
$azfw.properties.$RuleCollectionType | `
Where-Object {
$_.name -eq $RuleCollection.name
};
# Branch based on whether the Rule Collection already exists or not.
# If it already exists, check the rules and update it if necessary.
# If it doesn't already exists, add the new rule collection.
if($null -ne $currentRuleCollection) {
Write-Host "Found";
# Get the index of the application rule collection
$indexOfRuleCollection = [array]::indexOf($azfw.properties.$RuleCollectionType, $currentRuleCollection);
# Empty the previous Rules list and reset it to the new Rules list
$azfw.properties.$RuleCollectionType[$indexOfRuleCollection].properties.rules = $RuleCollection.properties.rules;
}
else {
Write-Host "Not Found";
$azfw.properties.$RuleCollectionType += $RuleCollection;
}
}
# Print out the Rule Collection as output.
return $azfw.properties.$RuleCollectionType;
}
else {
Throw "Firewall named $AzureFirewallName does not exists";
}

Просмотреть файл

@ -0,0 +1,151 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test ADDS ARM Templates
Version: 1.0.0.0 - 1st August 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Storage Account ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Storage Account ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "parameters.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Module.Parameters = (Get-ChildItem -Path (Join-Path $($File.DirectoryName) "parameters.json")).FullName;
$Modules += @{ Module = $Module };
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Storage Accounts" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Has environment parameters file" {
(Join-Path "$here" "parameters.json") | Should Exist
}
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,78 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aksClusterName": {
"value": "org-aks-k8s"
},
"location": {
"value": "westus2"
},
"dnsPrefix": {
"value": "aks"
},
"osDiskSizeGb": {
"value": 30
},
"agentCount": {
"value": 3
},
"agentVMSize": {
"value": "Standard_DS3_v2"
},
"servicePrincipalClientId": {
"value": "00000000-0000-0000-0000-000000000000"
},
"servicePrincipalClientSecret": {
"value": "secret"
},
"osType": {
"value": "Linux"
},
"kubernetesVersion": {
"value": "1.13.5"
},
"networkPlugin": {
"value": "azure"
},
"enableRBAC": {
"value": true
},
"vNetSubnetId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-network-rg/providers/Microsoft.Network/virtualNetworks/org-aks-vnet/subnets/default"
},
"serviceCIDR": {
"value": "10.0.0.0/16"
},
"dnsServiceIp": {
"value": "10.0.0.10"
},
"dockerBridgeCIDR": {
"value": "172.17.0.1/16"
},
"logAnalyticsResourceId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-diagnostics-rg/providers/Microsoft.OperationalInsights/workspaces/org-aks-la"
},
"diagnosticsEventHubName": {
"value": "org-diagnostics-eventhub"
},
"diagnosticsEventHubAuthRuleId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-diagnostics-rg/providers/Microsoft.EventHub/namespaces/orgeventhubnamespace/AuthorizationRules/RootManageSharedAccessKey"
},
"diagnosticsStorageId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-diagnostics-rg/providers/Microsoft.Storage/storageAccounts/orgaksdiag01"
},
"rbacServerAppId": {
"value":"00000000-0000-0000-0000-000000000000"
},
"rbacServerSecret": {
"value":"secret"
},
"rbacClientAppId": {
"value":"00000000-0000-0000-0000-000000000000"
},
"rbacTenant": {
"value":"00000000-0000-0000-0000-000000000000"
}
}
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Policy" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Policy" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "RBAC" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -Recurse | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "RBAC" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" -TestCases $TemplateFileTestCases {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
Write-Host "TF: $TemplateFile"
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,331 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aksClusterName": {
"type": "string",
"minLength": 3,
"maxLength": 31,
"metadata": {
"description": "Required. AKS Cluster Name."
}
},
"dnsPrefix": {
"type": "string",
"metadata": {
"description": "Required. DNS prefix to use with hosted Kubernetes API server FQDN."
}
},
"osDiskSizeGb": {
"defaultValue": 0,
"minValue": 0,
"maxValue": 1023,
"type": "int",
"metadata": {
"description": "Optional. Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize."
}
},
"osType": {
"defaultValue": "Linux",
"allowedValues": [
"Linux"
],
"type": "string",
"metadata": {
"description": "Optional. The type of operating system."
}
},
"agentCount": {
"defaultValue": 3,
"minValue": 1,
"maxValue": 50,
"type": "int",
"metadata": {
"description": "Optional. The number of agent nodes for the cluster."
}
},
"agentVMSize": {
"defaultValue": "Standard_D2_v2",
"type": "string",
"metadata": {
"description": "Optional. The size of the Virtual Machine."
}
},
"servicePrincipalClientId": {
"type": "securestring",
"metadata": {
"description": "Required. Client ID (used by cloudprovider)."
}
},
"servicePrincipalClientSecret": {
"type": "securestring",
"metadata": {
"description": "Required. The Service Principal Client Secret."
}
},
"kubernetesVersion": {
"defaultValue": "1.7.7",
"type": "string",
"metadata": {
"description": "Optional. The version of Kubernetes."
}
},
"networkPlugin": {
"allowedValues": [
"azure",
"kubenet"
],
"type": "string",
"metadata": {
"description": "Required. Network plugin used for building Kubernetes network."
}
},
"enableRBAC": {
"defaultValue": true,
"type": "bool",
"metadata": {
"description": "Optional. Boolean flag to turn on and off of RBAC."
}
},
"vNetId": {
"type": "string",
"metadata": {
"description": "Required. Resource ID of virtual network used for nodes and/or pods IP assignment."
}
},
"subnetName": {
"type": "string",
"metadata": {
"description": "Required. Resource Name of subnet used for nodes and/or pods IP assignment."
}
},
"serviceCIDR": {
"type": "string",
"metadata": {
"description": "Required. A CIDR notation IP range from which to assign service cluster IPs."
}
},
"dnsServiceIp": {
"type": "string",
"metadata": {
"description": "Required. Containers DNS server IP address."
}
},
"dockerBridgeCIDR": {
"type": "string",
"metadata": {
"description": "Required. A CIDR notation IP for Docker bridge."
}
},
"logAnalyticsResourceId": {
"type": "string",
"metadata": {
"description": "Required. Resource ID containing the insights"
}
},
"diagnosticsEventHubName": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Optional. Event Hub Name for the diagnostics events"
}
},
"diagnosticsEventHubAuthRuleId": {
"type": "string",
"metadata": {
"description": "Required. Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
}
},
"diagnosticsStorageId": {
"type": "string",
"metadata": {
"description": "Required. Storage account for the diagnostics events"
}
},
"rbacServerAppId": {
"type": "string",
"metadata": {
"description": "Required. RBAC server app id"
}
},
"rbacServerSecret": {
"type": "securestring",
"metadata": {
"description": "Required. RBAC server app secret"
}
},
"rbacClientAppId": {
"type": "string",
"metadata": {
"description": "Required. RBAC client app id"
}
},
"rbacTenant": {
"type": "string",
"defaultValue": "[subscription().tenantId]",
"metadata": {
"description": "Optional. RBAC tenant"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Optional. The location of AKS resource."
}
}
},
"variables": {
"authRuleResourceId": "[parameters('diagnosticsEventHubAuthRuleId')]",
"emptyContent": {},
"omsAgentConfig": {
"omsagent": {
"enabled": true,
"config": {
"logAnalyticsWorkspaceResourceID": "[parameters('logAnalyticsResourceId')]"
}
}
}
},
"resources": [
{
"type": "Microsoft.ContainerService/managedClusters",
"name": "[parameters('aksClusterName')]",
"apiVersion": "2018-03-31",
"location": "[parameters('location')]",
"tags": {
"displayName": "[concat(parameters('aksClusterName'))]"
},
"properties": {
"kubernetesVersion": "[parameters('kubernetesVersion')]",
"enableRBAC": "[parameters('enableRBAC')]",
"dnsPrefix": "[parameters('dnsPrefix')]",
"agentPoolProfiles": [
{
"name": "agentpool",
"osDiskSizeGB": "[parameters('osDiskSizeGb')]",
"count": "[parameters('agentCount')]",
"vmSize": "[parameters('agentVMSize')]",
"osType": "[parameters('osType')]",
"storageProfile": "ManagedDisks",
"vnetSubnetID": "[concat(parameters('vNetId'), '/subnets/', parameters('subnetName'))]"
}
],
"servicePrincipalProfile": {
"clientId": "[parameters('servicePrincipalClientId')]",
"Secret": "[parameters('servicePrincipalClientSecret')]"
},
"networkProfile": {
"networkPlugin": "[parameters('networkPlugin')]",
"serviceCidr": "[parameters('serviceCIDR')]",
"dnsServiceIP": "[parameters('dnsServiceIP')]",
"dockerBridgeCidr": "[parameters('dockerBridgeCIDR')]"
},
"aadProfile": {
"clientAppID": "[parameters('rbacClientAppId')]",
"serverAppID": "[parameters('rbacServerAppId')]",
"serverAppSecret": "[parameters('rbacServerSecret')]",
"tenantID": "[parameters('rbacTenant')]"
},
"addonProfiles": "[if( empty(parameters('logAnalyticsResourceId')) , variables('emptyContent'), variables('omsAgentConfig'))]"
},
"resources": [
{
"type": "Microsoft.ContainerService/managedClusters/providers/diagnosticSettings",
"name": "[concat(parameters('aksClusterName'), '/Microsoft.Insights/service')]",
"dependsOn": [
"[resourceId('Microsoft.ContainerService/managedClusters', parameters('aksClusterName'))]"
],
"apiVersion": "2017-05-01-preview",
"properties": {
"workspaceId": "[parameters('logAnalyticsResourceId')]",
"storageAccountId": "[parameters('diagnosticsStorageId')]",
"eventHubName": "[parameters('diagnosticsEventHubName')]",
"eventHubAuthorizationRuleId": "[parameters('diagnosticsEventHubAuthRuleId')]",
"logs": [
{
"category": "kube-apiserver",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-controller-manager",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "cluster-autoscaler",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-scheduler",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-audit",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
}
],
"metrics": [
{
"timeGrain": "PT1M",
"enabled": true,
"retentionPolicy": {
"enabled": false,
"days": 0
}
}
]
}
}
],
"dependsOn": [
]
}
],
"outputs": {
"aksClusterId": {
"type": "string",
"value": "[resourceId('Microsoft.ContainerService/managedClusters', parameters('aksClusterName'))]"
},
"aksClusterResourceGroup": {
"type": "string",
"value": "[resourceGroup().name]"
},
"aksClusterName": {
"type": "string",
"value": "[parameters('aksClusterName')]"
},
"nodeResourceGroupId": {
"type": "string",
"value": "[concat('/subscriptions/', resourceGroup().id, '/resourceGroups/', reference(concat('Microsoft.ContainerService/managedClusters/', parameters('aksClusterName'))).nodeResourceGroup)]"
},
"nodeResourceGroup": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', parameters('aksClusterName'))).nodeResourceGroup]"
},
"controlPlaneFQDN": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', parameters('aksClusterName'))).fqdn]"
}
}
}

Просмотреть файл

@ -1,65 +0,0 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"metadata": {
"description": "The location of AKS resource."
}
},
"acr-name": {
"type": "string",
"minLength": 5,
"maxLength": 50,
"metadata": {
"description": "Name of your Azure Container Registry"
}
},
"acr-admin-user-enabled": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Enable admin user that have push / pull permission to the registry."
}
},
"acr-sku": {
"type": "string",
"metadata": {
"description": "Tier of your Azure Container Registry."
},
"defaultValue": "Basic",
"allowedValues": [
"Basic",
"Standard",
"Premium"
]
}
},
"variables": {},
"resources": [
{
"name": "[parameters('acr-name')]",
"type": "Microsoft.ContainerRegistry/registries",
"apiVersion": "2017-10-01",
"location": "[parameters('location')]",
"comments": "Container registry for storing docker images",
"tags": {
"displayName": "[concat(parameters('acr-name'))]"
},
"sku": {
"name": "[parameters('acr-sku')]",
"tier": "[parameters('acr-sku')]"
},
"properties": {
"adminUserEnabled": "[parameters('acr-admin-user-enabled')]"
}
}
],
"outputs": {
"acr-login-server": {
"value": "[reference(resourceId('Microsoft.ContainerRegistry/registries',parameters('acr-name')),'2017-10-01').loginServer]",
"type": "string"
}
}
}

Просмотреть файл

@ -1,14 +0,0 @@
{
"location": {
"value": "${ENV:ENVIRONMENT-TYPE.region}"
},
"acr-name": {
"value": "${ENV:ENVIRONMENT-TYPE.acr.name}"
},
"acr-admin-user-enabled": {
"value": "${ENV:ENVIRONMENT-TYPE.acr.admin-user-enabled}"
},
"acr-sku": {
"value": "${ENV:ENVIRONMENT-TYPE.acr.sku}"
}
}

Просмотреть файл

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>bc0088dc-a19a-4b17-abec-3b71ce40b413</ProjectGuid>
</PropertyGroup>
<PropertyGroup>
<PrepareForBuildDependsOn>
</PrepareForBuildDependsOn>
</PropertyGroup>
<Import Condition=" Exists('Deployment.targets') " Project="Deployment.targets" />
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
<!-- vertag<:>start tokens<:>maj.min -->
<Import Condition=" Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Deployment\1.1\DeploymentProject.targets') " Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Deployment\1.1\DeploymentProject.targets" />
<!-- vertag<:>end -->
<ItemGroup>
<None Include="Pipeline\git_placeholder.md" />
<None Include="Policy\git_placeholder.md" />
<None Include="RBAC\git_placeholder.md" />
<None Include="Deployment.targets">
<Visible>False</Visible>
</None>
<Content Include="_README.md" />
<None Include="Scripts\git_placeholder.md" />
<Content Include="container.registries.deploy.json" />
<Content Include="container.registries.parameters.json" />
<None Include="Tests\container.registries.module.tests.ps1" />
</ItemGroup>
<Target Name="GetReferenceAssemblyPaths" />
</Project>

Просмотреть файл

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DebugSymbols>false</DebugSymbols>
<SkipCopyBuildProduct>true</SkipCopyBuildProduct>
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
<TargetRuntime>None</TargetRuntime>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">obj\</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition=" !HasTrailingSlash('$(BaseIntermediateOutputPath)') ">$(BaseIntermediateOutputPath)\</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
<ProjectReferencesOutputPath Condition=" '$(ProjectReferencesOutputPath)' == '' ">$(IntermediateOutputPath)ProjectReferences</ProjectReferencesOutputPath>
<ProjectReferencesOutputPath Condition=" !HasTrailingSlash('$(ProjectReferencesOutputPath)') ">$(ProjectReferencesOutputPath)\</ProjectReferencesOutputPath>
<StageArtifacts Condition=" '$(StageArtifacts)' == '' ">true</StageArtifacts>
</PropertyGroup>
<PropertyGroup>
<DefineCommonItemSchemas>false</DefineCommonItemSchemas>
<DefineCommonCapabilities>false</DefineCommonCapabilities>
</PropertyGroup>
<ProjectExtensions>
<ProjectCapabilities>
<DeploymentProject />
</ProjectCapabilities>
</ProjectExtensions>
<ItemDefinitionGroup>
<Content>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<ProjectReference>
<Private>false</Private>
<Targets>Build</Targets>
</ProjectReference>
</ItemDefinitionGroup>
<Target Name="CreateManifestResourceNames" />
<PropertyGroup>
<StageArtifactsDependsOn>
_GetDeploymentProjectContent;
_CalculateContentOutputRelativePaths;
_GetReferencedProjectsOutput;
_CalculateArtifactStagingDirectory;
_CopyOutputToArtifactStagingDirectory;
</StageArtifactsDependsOn>
</PropertyGroup>
<Target Name="_CopyOutputToArtifactStagingDirectory">
<Copy SourceFiles="@(DeploymentProjectContentOutput)" DestinationFiles="$(ArtifactStagingDirectory)\$(MSBuildProjectName)%(RelativePath)" />
<Copy SourceFiles="@(BuildProjectReferencesOutput)" DestinationFiles="$(ArtifactStagingDirectory)\$(MSBuildProjectName)\%(ProjectName)\%(RecursiveDir)%(FileName)%(Extension)" />
</Target>
<Target Name="_GetDeploymentProjectContent">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="ContentFilesProjectOutputGroup">
<Output TaskParameter="TargetOutputs" ItemName="DeploymentProjectContentOutput" />
</MSBuild>
</Target>
<Target Name="_GetReferencedProjectsOutput">
<PropertyGroup>
<MsBuildProperties>Configuration=$(Configuration);Platform=$(Platform)</MsBuildProperties>
</PropertyGroup>
<MSBuild Projects="@(ProjectReference)"
BuildInParallel="$(BuildInParallel)"
Properties="$(MsBuildProperties)"
Targets="%(ProjectReference.Targets)" />
<ItemGroup>
<BuildProjectReferencesOutput Include="%(ProjectReference.IncludeFilePath)">
<ProjectName>$([System.IO.Path]::GetFileNameWithoutExtension('%(ProjectReference.Identity)'))</ProjectName>
</BuildProjectReferencesOutput>
</ItemGroup>
</Target>
<Target Name="_CalculateArtifactStagingDirectory" Condition=" '$(ArtifactStagingDirectory)'=='' ">
<PropertyGroup>
<ArtifactStagingDirectory Condition=" '$(OutDir)'!='' ">$(OutDir)</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" '$(ArtifactStagingDirectory)'=='' ">$(OutputPath)</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" !HasTrailingSlash('$(ArtifactStagingDirectory)') ">$(ArtifactStagingDirectory)\</ArtifactStagingDirectory>
<ArtifactStagingDirectory>$(ArtifactStagingDirectory)staging\</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" '$(Build_StagingDirectory)'!='' AND '$(TF_Build)'=='True' ">$(Build_StagingDirectory)</ArtifactStagingDirectory>
</PropertyGroup>
</Target>
<!-- Appends each of the deployment project's content output files with metadata indicating its relative path from the deployment project's folder. -->
<Target Name="_CalculateContentOutputRelativePaths"
Outputs="%(DeploymentProjectContentOutput.Identity)">
<PropertyGroup>
<_OriginalIdentity>%(DeploymentProjectContentOutput.Identity)</_OriginalIdentity>
<_RelativePath>$(_OriginalIdentity.Replace('$(MSBuildProjectDirectory)', ''))</_RelativePath>
</PropertyGroup>
<ItemGroup>
<DeploymentProjectContentOutput>
<RelativePath>$(_RelativePath)</RelativePath>
</DeploymentProjectContentOutput>
</ItemGroup>
</Target>
<Target Name="CoreCompile" />
<PropertyGroup>
<StageArtifactsAfterTargets Condition=" '$(StageArtifacts)' == 'true' ">
PrepareForRun
</StageArtifactsAfterTargets>
</PropertyGroup>
<Target Name="StageArtifacts" DependsOnTargets="$(StageArtifactsDependsOn)" AfterTargets="$(StageArtifactsAfterTargets)"/>
<!-- Custom target to clean up local deployment staging files -->
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
<RemoveDir Directories="$(OutputPath)" />
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,151 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test ADDS ARM Templates
Version: 1.0.0.0 - 1st August 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Storage Account ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Storage Account ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "parameters.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Module.Parameters = (Get-ChildItem -Path (Join-Path $($File.DirectoryName) "parameters.json")).FullName;
$Modules += @{ Module = $Module };
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Storage Accounts" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Has environment parameters file" {
(Join-Path "$here" "parameters.json") | Should Exist
}
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
#endregion

Просмотреть файл

@ -2,9 +2,6 @@
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "West US 2"
},
"containerRegistryName": {
"value": "org-container-registry-name"
},
@ -13,6 +10,9 @@
},
"containerRegistrySku": {
"value": "Standard"
},
"location": {
"value": "West US 2"
}
}
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Policy" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Policy" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "RBAC" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -Recurse | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "RBAC" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" -TestCases $TemplateFileTestCases {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
Write-Host "TF: $TemplateFile"
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -2,31 +2,25 @@
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"metadata": {
"description": "Location of AKS resource."
}
},
"containerRegistryName": {
"type": "string",
"minLength": 5,
"maxLength": 50,
"metadata": {
"description": "Name of your Container Registry"
"description": "Required. Name of your Container Registry"
}
},
"containerRegistryAdminUserEnabled": {
"type": "bool",
"defaultValue": false,
"metadata": {
"description": "Enable admin user that have push / pull permission to the registry."
"description": "Optional. Enable admin user that have push / pull permission to the registry."
}
},
"containerRegistrySku": {
"type": "string",
"metadata": {
"description": "Tier of your Container Registry."
"description": "Optional. Tier of your Container Registry."
},
"defaultValue": "Basic",
"allowedValues": [
@ -34,6 +28,13 @@
"Standard",
"Premium"
]
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Required. Location of AKS resource."
}
}
},
"variables": {},
@ -57,9 +58,33 @@
}
],
"outputs": {
"containerRegistryResourceId": {
"value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('containerRegistryName'))]",
"type": "string",
"metadata": {
"description": "The Resource Id of the Container Registry"
}
},
"containerRegistryResourceGroup": {
"value": "[resourceGroup().name]",
"type": "string",
"metadata": {
"description": "The name of the Resource Group the Container Registry was created in."
}
},
"containerRegistryName": {
"value": "[parameters('containerRegistryName')]",
"type": "string",
"metadata": {
"description": "The Name of the Container Registry"
}
},
"containerRegistryLoginServer": {
"value": "[reference(resourceId('Microsoft.ContainerRegistry/registries',parameters('containerRegistryName')),'2017-10-01').loginServer]",
"type": "string"
"type": "string",
"metadata": {
"description": "The Login Server of the Container Registry"
}
}
}
}

Просмотреть файл

@ -1,145 +0,0 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"deployment-prefix": {
"type": "string",
"metadata": {
"description": "Deployment prefix. E.g. Organization-DeploymentType"
}
},
"location": {
"type": "string",
"allowedValues": [
"Australia Southeast",
"Canada Central",
"Central India",
"East US",
"Japan East",
"Southeast Asia",
"UK South",
"West Europe",
"West US 2"
],
"metadata": {
"description": "Region used when establishing the workspace."
}
},
"event-hub-name": {
"type": "string",
"metadata": {
"description": "Optional. Name of the event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category."
}
},
"namespace-name": {
"type": "string",
"metadata": {
"description": "Name of EventHub namespace"
}
},
"eventhub-sku": {
"type": "string",
"allowedValues": ["Basic", "Standard"],
"defaultValue": "Standard",
"metadata": {
"description": "The messaging tier for service Bus namespace"
}
},
"sku-capacity": {
"type": "int",
"allowedValues": [1, 2, 4],
"defaultValue": 1,
"metadata": {
"description": "MessagingUnits for premium namespace"
}
},
"consumer-group-name": {
"type": "string",
"metadata": {
"description": "Name of Consumer Group"
}
},
"authorizationrules-root-manage-shared-access-key-name": {
"defaultValue": "RootManageSharedAccessKey",
"type": "string"
}
},
"variables": {
"k8s-workspace-name": "[concat(parameters('deployment-prefix'), '-diagnostics-la')]"
},
"resources": [
{
"apiVersion": "2017-04-01",
"name": "[parameters('namespace-name')]",
"type": "Microsoft.EventHub/namespaces",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('eventhub-sku')]",
"tier": "[parameters('eventhub-sku')]",
"capacity": "[parameters('sku-capacity')]"
},
"tags": {
"tag1": "value1",
"tag2": "value2"
},
"properties": {},
"resources": [
{
"apiVersion": "2017-04-01",
"name": "[parameters('event-hub-name')]",
"type": "eventhubs",
"dependsOn": [
"[concat('Microsoft.EventHub/namespaces/', parameters('namespace-name'))]"
],
"properties": {},
"resources": [
{
"apiVersion": "2017-04-01",
"name": "[parameters('consumer-group-name')]",
"type": "consumergroups",
"dependsOn": ["[parameters('event-hub-name')]"],
"properties": {
"userMetadata": "User Metadata"
}
}
]
}
]
},
{
"type": "Microsoft.EventHub/namespaces/AuthorizationRules",
"name": "[concat(parameters('namespace-name'), '/', parameters('authorizationrules-root-manage-shared-access-key-name'))]",
"apiVersion": "2017-04-01",
"location": "[parameters('location')]",
"scale": null,
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
},
"dependsOn": [
"[resourceId('Microsoft.EventHub/namespaces', parameters('namespace-name'))]"
]
}
],
"outputs": {
"diagnostics-event-hub-name": {
"type": "string",
"value": "[parameters('event-hub-name')]"
},
"diagnostics-event-hub-auth-rule-id": {
"type": "string",
"value": "[resourceId('Microsoft.EventHub/namespaces/AuthorizationRules', parameters('namespace-name'), parameters('authorizationrules-root-manage-shared-access-key-name'))]"
},
"diagnostics-resource-group-id": {
"type": "string",
"value": "[resourceGroup().id]"
},
"diagnostics-resource-group-name": {
"type": "string",
"value": "[resourceGroup().name]"
}
}
}

Просмотреть файл

@ -1,26 +0,0 @@
{
"deployment-prefix": {
"value": "${general.organization-name}-${ENV:ENVIRONMENT-TYPE.deployment-name}"
},
"location": {
"value": "${ENV:ENVIRONMENT-TYPE.region}"
},
"event-hub-name": {
"value": "${ENV:ENVIRONMENT-TYPE.event-hub.name}"
},
"namespace-name": {
"value": "${ENV:ENVIRONMENT-TYPE.event-hub.namespace}"
},
"eventhub-sku": {
"value": "${ENV:ENVIRONMENT-TYPE.event-hub.sku}"
},
"sku-capacity": {
"value": 1
},
"consumer-group-name": {
"value": "${ENV:ENVIRONMENT-TYPE.event-hub.name}-consumer"
},
"authorizationrules-root-manage-shared-access-key-name": {
"value": "RootManageSharedAccessKey"
}
}

Просмотреть файл

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DebugSymbols>false</DebugSymbols>
<SkipCopyBuildProduct>true</SkipCopyBuildProduct>
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
<TargetRuntime>None</TargetRuntime>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">obj\</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition=" !HasTrailingSlash('$(BaseIntermediateOutputPath)') ">$(BaseIntermediateOutputPath)\</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
<ProjectReferencesOutputPath Condition=" '$(ProjectReferencesOutputPath)' == '' ">$(IntermediateOutputPath)ProjectReferences</ProjectReferencesOutputPath>
<ProjectReferencesOutputPath Condition=" !HasTrailingSlash('$(ProjectReferencesOutputPath)') ">$(ProjectReferencesOutputPath)\</ProjectReferencesOutputPath>
<StageArtifacts Condition=" '$(StageArtifacts)' == '' ">true</StageArtifacts>
</PropertyGroup>
<PropertyGroup>
<DefineCommonItemSchemas>false</DefineCommonItemSchemas>
<DefineCommonCapabilities>false</DefineCommonCapabilities>
</PropertyGroup>
<ProjectExtensions>
<ProjectCapabilities>
<DeploymentProject />
</ProjectCapabilities>
</ProjectExtensions>
<ItemDefinitionGroup>
<Content>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<ProjectReference>
<Private>false</Private>
<Targets>Build</Targets>
</ProjectReference>
</ItemDefinitionGroup>
<Target Name="CreateManifestResourceNames" />
<PropertyGroup>
<StageArtifactsDependsOn>
_GetDeploymentProjectContent;
_CalculateContentOutputRelativePaths;
_GetReferencedProjectsOutput;
_CalculateArtifactStagingDirectory;
_CopyOutputToArtifactStagingDirectory;
</StageArtifactsDependsOn>
</PropertyGroup>
<Target Name="_CopyOutputToArtifactStagingDirectory">
<Copy SourceFiles="@(DeploymentProjectContentOutput)" DestinationFiles="$(ArtifactStagingDirectory)\$(MSBuildProjectName)%(RelativePath)" />
<Copy SourceFiles="@(BuildProjectReferencesOutput)" DestinationFiles="$(ArtifactStagingDirectory)\$(MSBuildProjectName)\%(ProjectName)\%(RecursiveDir)%(FileName)%(Extension)" />
</Target>
<Target Name="_GetDeploymentProjectContent">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="ContentFilesProjectOutputGroup">
<Output TaskParameter="TargetOutputs" ItemName="DeploymentProjectContentOutput" />
</MSBuild>
</Target>
<Target Name="_GetReferencedProjectsOutput">
<PropertyGroup>
<MsBuildProperties>Configuration=$(Configuration);Platform=$(Platform)</MsBuildProperties>
</PropertyGroup>
<MSBuild Projects="@(ProjectReference)"
BuildInParallel="$(BuildInParallel)"
Properties="$(MsBuildProperties)"
Targets="%(ProjectReference.Targets)" />
<ItemGroup>
<BuildProjectReferencesOutput Include="%(ProjectReference.IncludeFilePath)">
<ProjectName>$([System.IO.Path]::GetFileNameWithoutExtension('%(ProjectReference.Identity)'))</ProjectName>
</BuildProjectReferencesOutput>
</ItemGroup>
</Target>
<Target Name="_CalculateArtifactStagingDirectory" Condition=" '$(ArtifactStagingDirectory)'=='' ">
<PropertyGroup>
<ArtifactStagingDirectory Condition=" '$(OutDir)'!='' ">$(OutDir)</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" '$(ArtifactStagingDirectory)'=='' ">$(OutputPath)</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" !HasTrailingSlash('$(ArtifactStagingDirectory)') ">$(ArtifactStagingDirectory)\</ArtifactStagingDirectory>
<ArtifactStagingDirectory>$(ArtifactStagingDirectory)staging\</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" '$(Build_StagingDirectory)'!='' AND '$(TF_Build)'=='True' ">$(Build_StagingDirectory)</ArtifactStagingDirectory>
</PropertyGroup>
</Target>
<!-- Appends each of the deployment project's content output files with metadata indicating its relative path from the deployment project's folder. -->
<Target Name="_CalculateContentOutputRelativePaths"
Outputs="%(DeploymentProjectContentOutput.Identity)">
<PropertyGroup>
<_OriginalIdentity>%(DeploymentProjectContentOutput.Identity)</_OriginalIdentity>
<_RelativePath>$(_OriginalIdentity.Replace('$(MSBuildProjectDirectory)', ''))</_RelativePath>
</PropertyGroup>
<ItemGroup>
<DeploymentProjectContentOutput>
<RelativePath>$(_RelativePath)</RelativePath>
</DeploymentProjectContentOutput>
</ItemGroup>
</Target>
<Target Name="CoreCompile" />
<PropertyGroup>
<StageArtifactsAfterTargets Condition=" '$(StageArtifacts)' == 'true' ">
PrepareForRun
</StageArtifactsAfterTargets>
</PropertyGroup>
<Target Name="StageArtifacts" DependsOnTargets="$(StageArtifactsDependsOn)" AfterTargets="$(StageArtifactsAfterTargets)"/>
<!-- Custom target to clean up local deployment staging files -->
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
<RemoveDir Directories="$(OutputPath)" />
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
</Project>

Просмотреть файл

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>b6ce9707-b060-4439-81c9-d03a566f411c</ProjectGuid>
</PropertyGroup>
<PropertyGroup>
<PrepareForBuildDependsOn>
</PrepareForBuildDependsOn>
</PropertyGroup>
<Import Condition=" Exists('Deployment.targets') " Project="Deployment.targets" />
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
<!-- vertag<:>start tokens<:>maj.min -->
<Import Condition=" Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Deployment\1.1\DeploymentProject.targets') " Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Deployment\1.1\DeploymentProject.targets" />
<!-- vertag<:>end -->
<ItemGroup>
<Content Include="event.hub.parameters.json" />
<Content Include="event.hub.deploy.json" />
<None Include="Deployment.targets">
<Visible>False</Visible>
</None>
<None Include="_README.md" />
<None Include="Pipeline\git_placeholder.md" />
<None Include="Policy\git_placeholder.md" />
<None Include="RBAC\git_placeholder.md" />
<None Include="Scripts\git_placeholder.md" />
<None Include="Tests\event.hub.module.tests.ps1" />
</ItemGroup>
<Target Name="GetReferenceAssemblyPaths" />
</Project>

Просмотреть файл

@ -0,0 +1,151 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test ADDS ARM Templates
Version: 1.0.0.0 - 1st August 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Storage Account ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Storage Account ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "parameters.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Module.Parameters = (Get-ChildItem -Path (Join-Path $($File.DirectoryName) "parameters.json")).FullName;
$Modules += @{ Module = $Module };
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Storage Accounts" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Has environment parameters file" {
(Join-Path "$here" "parameters.json") | Should Exist
}
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content "$($Module.Parameters)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Policy" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Policy" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "RBAC" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -Recurse | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "RBAC" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" -TestCases $TemplateFileTestCases {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
Write-Host "TF: $TemplateFile"
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -16,7 +16,7 @@
"West US 2"
],
"metadata": {
"description": "Region used when establishing the workspace."
"description": "Optional. Region used when establishing the workspace."
}
},
"eventHubName": {
@ -30,13 +30,13 @@
"allowedValues": [ "Basic", "Standard" ],
"defaultValue": "Standard",
"metadata": {
"description": "The messaging tier for service Bus namespace"
"description": "Required. The messaging tier for service Bus namespace"
}
},
"namespaceName": {
"type": "string",
"metadata": {
"description": "Name of EventHub namespace"
"description": "Optional. Name of EventHub namespace"
}
},
"skuCapacity": {
@ -44,18 +44,21 @@
"allowedValues": [ 1, 2, 4 ],
"defaultValue": 1,
"metadata": {
"description": "MessagingUnits for premium namespace"
"description": "Optional. MessagingUnits for premium namespace"
}
},
"consumerGroupName": {
"type": "string",
"metadata": {
"description": "Name of Consumer Group"
"description": "Optional. Name of Consumer Group"
}
},
"authorizationRulesRootManageSharedAccessKeyName": {
"defaultValue": "RootManageSharedAccessKey",
"type": "string"
"type": "string",
"metadata": {
"description": "Optional. Authorization Rules Root Managed Shared Access Key."
}
}
},
"variables": {

Просмотреть файл

@ -0,0 +1,74 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVaultName": {
"value": "vdckeyvault"
},
"accessPolicies": {
"value": [
{
"tenantId": null,
"objectId": null,
"permissions": {
"certificates": [
"All"
],
"keys": [
"All"
],
"secrets": [
"All"
]
}
}
]
},
"secretsObject": {
"value": {
"secrets": [
{
"secretName": "Secret--AzureAd--Domain",
"secretValue": "Some value"
}
]
}
},
"enableVaultForDeployment": {
"value": true
},
"enableVaultForDiskEncryption": {
"value": true
},
"enableVaultForTemplateDeployment": {
"value": true
},
"logsRetentionInDays": {
"value": 365
},
"vaultSku": {
"value": "Premium"
},
"diagnosticStorageAccountId": {
"value": "/subscriptions/00000000/resourceGroups/resourceGroup"
},
"workspaceId": {
"value": "/subscriptions/00000000/resourceGroups/resourceGroup"
},
"networkAcls": {
"value": {
"bypass": "AzureServices",
"defaultAction": "Deny",
"virtualNetworkRules": [
{
"subnet": "sharedsvcs"
}
],
"ipRules": []
}
},
"vNetId": {
"value": "/subscriptions/00000000/resourceGroups/resourceGroup"
}
}
}

Просмотреть файл

@ -0,0 +1,74 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVaultName": {
"value": "vdckeyvault"
},
"accessPolicies": {
"value": [
{
"tenantId": null,
"objectId": null,
"permissions": {
"certificates": [
"All"
],
"keys": [
"All"
],
"secrets": [
"All"
]
}
}
]
},
"secretsObject": {
"value": {
"secrets": [
{
"secretName": "Secret--AzureAd--Domain",
"secretValue": "Some value"
}
]
}
},
"enableVaultForDeployment": {
"value": true
},
"enableVaultForDiskEncryption": {
"value": true
},
"enableVaultForTemplateDeployment": {
"value": true
},
"logsRetentionInDays": {
"value": 365
},
"vaultSku": {
"value": "Premium"
},
"diagnosticStorageAccountId": {
"value": "/subscriptions/00000000/resourceGroups/resourceGroup"
},
"workspaceId": {
"value": "/subscriptions/00000000/resourceGroups/resourceGroup"
},
"networkAcls": {
"value": {
"bypass": "AzureServices",
"defaultAction": "Deny",
"virtualNetworkRules": [
{
"subnet": "sharedsvcs"
}
],
"ipRules": []
}
},
"vNetId": {
"value": "/subscriptions/00000000/resourceGroups/resourceGroup"
}
}
}

Просмотреть файл

@ -194,7 +194,7 @@
{
"type": "Microsoft.KeyVault/vaults/secrets",
"apiVersion": "2015-06-01",
"name": "[concat(parameters('keyVaultName'), '/', parameters('secretsObject').secrets[copyIndex()].secretName)]",
"name": "[if(equals(copyIndex(),0), concat(parameters('keyVaultName'), '/', 'dummy'), concat(parameters('keyVaultName'), '/', parameters('secretsObject').secrets[copyIndex()].secretName))]",
"properties": {
"value": "[parameters('secretsObject').secrets[copyIndex()].secretValue]"
},

Просмотреть файл

@ -1,112 +0,0 @@
{
"policies": [
{
"name": "Diagnositcs Enabled for AKS Cluster",
"description": "Policy to prevent the disabling diagnostics in AKS Cluster.",
"rules": {
"if": {
"field": "type",
"in": [
"Microsoft.ContainerService/managedClusters"
]
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Insights/diagnosticSettings",
"existenceCondition": {
"allOf": [
{
"field": "Microsoft.Insights/diagnosticSettings/logs.enabled",
"equals": "true"
},
{
"field": "Microsoft.Insights/diagnosticSettings/metrics.enabled",
"equals": "true"
}
]
}
}
}
}
},
{
"name": "RBAC Role - Reader Role Assigned",
"description": "Policy to check the RBAC role assignment.",
"rules": {
"if": {
"field": "type",
"in": [
"Microsoft.ContainerService/managedClusters"
]
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Authorization/roleAssignments",
"existenceCondition": {
"allOf": [
{
"field": "Microsoft.Authorization/roleAssignments/roleDefinitionId",
"contains": "acdd72a7-3385-48ef-bd42-f606fba81ae7"
}
]
}
}
}
}
},
{
"name": "RBAC Role - Azure Kubernetes Service Cluster User Role Assigned",
"description": "Policy to check the RBAC role assignment.",
"rules": {
"if": {
"field": "type",
"in": [
"Microsoft.ContainerService/managedClusters"
]
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Authorization/roleAssignments",
"existenceCondition": {
"allOf": [
{
"field": "Microsoft.Authorization/roleAssignments/roleDefinitionId",
"contains": "4abbcc35-e782-43d8-92c5-2d3f1bd2253f"
}
]
}
}
}
}
},
{
"name": "RBAC Role - Azure Kubernetes Service Cluster Admin Role Assigned",
"description": "Policy to check the RBAC role assignment.",
"rules": {
"if": {
"field": "type",
"in": [
"Microsoft.ContainerService/managedClusters"
]
},
"then": {
"effect": "auditIfNotExists",
"details": {
"type": "Microsoft.Authorization/roleAssignments",
"existenceCondition": {
"allOf": [
{
"field": "Microsoft.Authorization/roleAssignments/roleDefinitionId",
"contains": "0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8"
}
]
}
}
}
}
}
]
}

Просмотреть файл

@ -1,376 +0,0 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"deployment-prefix": {
"type": "string",
"metadata": {
"description": "Deployment prefix. E.g. Organization-DeploymentType"
}
},
"shared-services-deployment-prefix": {
"type": "string",
"metadata": {
"description": "Deployment prefix for Shared Services. E.g. Organization-DeploymentType"
}
},
"location": {
"type": "string",
"metadata": {
"description": "The location of AKS resource."
}
},
"dns-prefix": {
"type": "string",
"metadata": {
"description": "Optional DNS prefix to use with hosted Kubernetes API server FQDN."
}
},
"os-disk-size-gb": {
"defaultValue": 0,
"minValue": 0,
"maxValue": 1023,
"type": "int",
"metadata": {
"description": "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize."
}
},
"agent-count": {
"defaultValue": 3,
"minValue": 1,
"maxValue": 50,
"type": "int",
"metadata": {
"description": "The number of agent nodes for the cluster."
}
},
"agent-vm-size": {
"defaultValue": "Standard_D2_v2",
"type": "string",
"metadata": {
"description": "The size of the Virtual Machine."
}
},
"service-principal-client-id": {
"type": "securestring",
"metadata": {
"description": "Client ID (used by cloudprovider)."
}
},
"service-principal-client-secret": {
"type": "securestring",
"metadata": {
"description": "The Service Principal Client Secret."
}
},
"os-type": {
"defaultValue": "Linux",
"allowedValues": [
"Linux"
],
"type": "string",
"metadata": {
"description": "The type of operating system."
}
},
"kubernetes-version": {
"defaultValue": "1.7.7",
"type": "string",
"metadata": {
"description": "The version of Kubernetes."
}
},
"network-plugin": {
"allowedValues": [
"azure",
"kubenet"
],
"type": "string",
"metadata": {
"description": "Network plugin used for building Kubernetes network."
}
},
"enable-rbac": {
"defaultValue": true,
"type": "bool",
"metadata": {
"description": "Boolean flag to turn on and off of RBAC."
}
},
"vnet-subnet-id": {
"type": "string",
"metadata": {
"description": "Resource ID of virtual network subnet used for nodes and/or pods IP assignment."
}
},
"service-cidr": {
"type": "string",
"metadata": {
"description": "A CIDR notation IP range from which to assign service cluster IPs."
}
},
"dns-service-ip": {
"type": "string",
"metadata": {
"description": "Containers DNS server IP address."
}
},
"docker-bridge-cidr": {
"type": "string",
"metadata": {
"description": "A CIDR notation IP for Docker bridge."
}
},
"oms-id": {
"type": "string",
"metadata": {
"description": "Resource ID containing the insights"
}
},
"diagnostic-event-hub-name": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Event Hub Name for the diagnostics events"
}
},
"diagnostics-event-hub-auth-rule-id": {
"type": "string",
"metadata": {
"description": "Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
}
},
"oms-storage-id": {
"type": "string",
"metadata": {
"description": "Storage account for the diagnostics events"
}
},
"rbac-server-appid": {
"type": "string",
"metadata": {
"description": "RBAC server app id"
}
},
"rbac-server-secret": {
"type": "string",
"metadata": {
"description": "RBAC server app secret"
}
},
"rbac-client-appid": {
"type": "string",
"metadata": {
"description": "RBAC client app id"
}
},
"rbac-tenant": {
"type": "string",
"metadata": {
"description": "RBAC tenant"
}
},
"azure-firewall-application-rule-collection": {
"type": "array",
"metadata": {
"description": "Array containing AKS specific Azure Firewall application rule collections"
}
},
"azure-firewall-network-rule-collection": {
"type": "array",
"metadata": {
"description": "Array containing AKS specific Azure Firewall network rule collections"
}
},
"subscription-id": {
"type": "string",
"metadata": {
"description": "AKS Cluster deployment Subcription Id"
}
}
},
"variables": {
"auth-rule-resource-id": "[parameters('diagnostics-event-hub-auth-rule-id')]",
"aks-cluster-name": "[concat(parameters('deployment-prefix'), '-k8s')]",
"emptyContent": {},
"omsAgentConfig": {
"omsagent": {
"enabled": true,
"config": {
"logAnalyticsWorkspaceResourceID": "[parameters('oms-id')]"
}
}
},
"azure-fw-resource-group": "[concat(parameters('shared-services-deployment-prefix'), '-net-rg')]",
"azure-fw-name": "[concat(parameters('shared-services-deployment-prefix'), '-az-fw')]"
},
"resources": [
{
"apiVersion": "2017-05-10",
"name": "nestedDeployCreateAzureApplicationRules",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[concat(parameters('shared-services-deployment-prefix'),'-net-rg')]",
"subscriptionId": "[parameters('subscription-id')]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/azureFirewalls",
"apiVersion": "2018-08-01",
"location": "[resourceGroup().location]",
"name": "[variables('azure-fw-name')]",
"properties": {
"ipConfigurations": "[reference(resourceId(parameters('subscription-id'), variables('azure-fw-resource-group'), 'Microsoft.Network/azureFirewalls', variables('azure-fw-name')), '2018-08-01').ipConfigurations]",
"natRuleCollections": "[reference(resourceId(parameters('subscription-id'), variables('azure-fw-resource-group'), 'Microsoft.Network/azureFirewalls', variables('azure-fw-name')), '2018-08-01').natRuleCollections]",
"applicationRuleCollections": "[concat(reference(resourceId(parameters('subscription-id'), variables('azure-fw-resource-group'), 'Microsoft.Network/azureFirewalls', variables('azure-fw-name')), '2018-08-01').applicationRuleCollections, parameters('azure-firewall-application-rule-collection'))]",
"networkRuleCollections": "[concat(reference(resourceId(parameters('subscription-id'), variables('azure-fw-resource-group'), 'Microsoft.Network/azureFirewalls', variables('azure-fw-name')), '2018-08-01').networkRuleCollections, parameters('azure-firewall-network-rule-collection'))]"
}
}
]
}
}
},
{
"type": "Microsoft.ContainerService/managedClusters",
"name": "[variables('aks-cluster-name')]",
"apiVersion": "2018-03-31",
"location": "[parameters('location')]",
"tags": {
"displayName": "[concat(variables('aks-cluster-name'))]"
},
"properties": {
"kubernetesVersion": "[parameters('kubernetes-version')]",
"enableRBAC": "[parameters('enable-rbac')]",
"dnsPrefix": "[parameters('dns-prefix')]",
"agentPoolProfiles": [
{
"name": "agentpool",
"osDiskSizeGB": "[parameters('os-disk-size-gb')]",
"count": "[parameters('agent-count')]",
"vmSize": "[parameters('agent-vm-size')]",
"osType": "[parameters('os-type')]",
"storageProfile": "ManagedDisks",
"vnetSubnetID": "[parameters('vnet-subnet-id')]"
}
],
"servicePrincipalProfile": {
"clientId": "[parameters('service-principal-client-id')]",
"Secret": "[parameters('service-principal-client-secret')]"
},
"networkProfile": {
"networkPlugin": "[parameters('network-plugin')]",
"serviceCidr": "[parameters('service-cidr')]",
"dnsServiceIP": "[parameters('dns-service-ip')]",
"dockerBridgeCidr": "[parameters('docker-bridge-cidr')]"
},
"aadProfile": {
"clientAppID": "[parameters('rbac-client-appid')]",
"serverAppID": "[parameters('rbac-server-appid')]",
"serverAppSecret": "[parameters('rbac-server-secret')]",
"tenantID": "[parameters('rbac-tenant')]"
},
"addonProfiles": "[if( empty(parameters('oms-id')) , variables('emptyContent'), variables('omsAgentConfig'))]"
},
"resources": [
{
"type": "Microsoft.ContainerService/managedClusters/providers/diagnosticSettings",
"name": "[concat(variables('aks-cluster-name'), '/Microsoft.Insights/service')]",
"dependsOn": [
"[resourceId('Microsoft.ContainerService/managedClusters', variables('aks-cluster-name'))]"
],
"apiVersion": "2017-05-01-preview",
"properties": {
"workspaceId": "[parameters('oms-id')]",
"storageAccountId": "[parameters('oms-storage-id')]",
"eventHubName": "[parameters('diagnostic-event-hub-name')]",
"eventHubAuthorizationRuleId": "[parameters('diagnostics-event-hub-auth-rule-id')]",
"logs": [
{
"category": "kube-apiserver",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-controller-manager",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "cluster-autoscaler",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-scheduler",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-audit",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
}
],
"metrics": [
{
"timeGrain": "PT1M",
"enabled": true,
"retentionPolicy": {
"enabled": false,
"days": 0
}
}
]
}
}
],
"dependsOn": [
"nestedDeployCreateAzureApplicationRules"
]
}
],
"outputs": {
"resource-group-id": {
"type": "string",
"value": "[concat('/subscriptions/', parameters('subscription-id'), '/resourceGroups/', reference(concat('Microsoft.ContainerService/managedClusters/', variables('aks-cluster-name'))).nodeResourceGroup)]"
},
"resource-group-name": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', variables('aks-cluster-name'))).nodeResourceGroup]"
},
"controlPlaneFQDN": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', variables('aks-cluster-name'))).fqdn]"
},
"NamespaceConnectionString": {
"type": "string",
"value": "[listkeys(variables('auth-rule-resource-id'), '2017-04-01').primaryConnectionString]"
},
"SharedAccessPolicyPrimaryKey": {
"type": "string",
"value": "[listkeys(variables('auth-rule-resource-id'), '2017-04-01').primaryKey]"
}
}
}

Просмотреть файл

@ -1,77 +0,0 @@
{
"deployment-prefix": {
"value": "${general.organization-name}-${workload.deployment-name}"
},
"shared-services-deployment-prefix": {
"value": "${general.organization-name}-${shared-services.deployment-name}"
},
"resource-group-id": {
"value": "[resourceGroup().id]"
},
"location": {
"value": "${workload.region}"
},
"dns-prefix": {
"value": "${workload.dns-prefix}"
},
"os-disk-size-gb": {
"value": "${workload.kubernetes.os-disk-size-gb}"
},
"agent-count": {
"value": "${workload.kubernetes.agent-count}"
},
"agent-vm-size": {
"value": "${workload.kubernetes.agent-vm-size}"
},
"service-principal-client-id": {
"value": "${workload.kubernetes.service-principal-client-id}"
},
"service-principal-client-secret": {
"value": "${workload.kubernetes.service-principal-client-secret}"
},
"os-type": {
"value": "${workload.kubernetes.os-type}"
},
"kubernetes-version": {
"value": "${workload.kubernetes.kubernetes-version}"
},
"network-plugin": {
"value": "${workload.kubernetes.network-plugin}"
},
"rbac-server-appid": {
"value":"${workload.kubernetes.rbac-server-appid}"
},
"rbac-server-secret": {
"value":"${workload.kubernetes.rbac-server-secret}"
},
"rbac-client-appid": {
"value":"${workload.kubernetes.rbac-client-appid}"
},
"rbac-tenant": {
"value":"${workload.kubernetes.rbac-tenant}"
},
"enable-rbac": {
"value": "${workload.kubernetes.enable-rbac}"
},
"vnet-subnet-id": {
"value": "/subscriptions/${general.workload.subscription-id}/resourceGroups/${workload.resource-group-prefix}-net-rg/providers/Microsoft.Network/virtualNetworks/${workload.resource-group-prefix}-vnet/subnets/default"
},
"service-cidr": {
"value": "${workload.kubernetes.service-cidr}"
},
"dns-service-ip": {
"value": "${workload.kubernetes.dns-service-ip}"
},
"docker-bridge-cidr": {
"value": "${workload.kubernetes.docker-bridge-cidr}"
},
"azure-firewall-application-rule-collection": {
"value": "${workload.network.azure-firewall-application-rule-collection}"
},
"azure-firewall-network-rule-collection": {
"value": "${workload.network.azure-firewall-network-rule-collection}"
},
"subscription-id": {
"value": "${workload.subscription-id}"
}
}

Просмотреть файл

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputPath>bin\$(Configuration)\</OutputPath>
<DebugSymbols>false</DebugSymbols>
<SkipCopyBuildProduct>true</SkipCopyBuildProduct>
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
<TargetRuntime>None</TargetRuntime>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">obj\</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition=" !HasTrailingSlash('$(BaseIntermediateOutputPath)') ">$(BaseIntermediateOutputPath)\</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
<ProjectReferencesOutputPath Condition=" '$(ProjectReferencesOutputPath)' == '' ">$(IntermediateOutputPath)ProjectReferences</ProjectReferencesOutputPath>
<ProjectReferencesOutputPath Condition=" !HasTrailingSlash('$(ProjectReferencesOutputPath)') ">$(ProjectReferencesOutputPath)\</ProjectReferencesOutputPath>
<StageArtifacts Condition=" '$(StageArtifacts)' == '' ">true</StageArtifacts>
</PropertyGroup>
<PropertyGroup>
<DefineCommonItemSchemas>false</DefineCommonItemSchemas>
<DefineCommonCapabilities>false</DefineCommonCapabilities>
</PropertyGroup>
<ProjectExtensions>
<ProjectCapabilities>
<DeploymentProject />
</ProjectCapabilities>
</ProjectExtensions>
<ItemDefinitionGroup>
<Content>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None>
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<ProjectReference>
<Private>false</Private>
<Targets>Build</Targets>
</ProjectReference>
</ItemDefinitionGroup>
<Target Name="CreateManifestResourceNames" />
<PropertyGroup>
<StageArtifactsDependsOn>
_GetDeploymentProjectContent;
_CalculateContentOutputRelativePaths;
_GetReferencedProjectsOutput;
_CalculateArtifactStagingDirectory;
_CopyOutputToArtifactStagingDirectory;
</StageArtifactsDependsOn>
</PropertyGroup>
<Target Name="_CopyOutputToArtifactStagingDirectory">
<Copy SourceFiles="@(DeploymentProjectContentOutput)" DestinationFiles="$(ArtifactStagingDirectory)\$(MSBuildProjectName)%(RelativePath)" />
<Copy SourceFiles="@(BuildProjectReferencesOutput)" DestinationFiles="$(ArtifactStagingDirectory)\$(MSBuildProjectName)\%(ProjectName)\%(RecursiveDir)%(FileName)%(Extension)" />
</Target>
<Target Name="_GetDeploymentProjectContent">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="ContentFilesProjectOutputGroup">
<Output TaskParameter="TargetOutputs" ItemName="DeploymentProjectContentOutput" />
</MSBuild>
</Target>
<Target Name="_GetReferencedProjectsOutput">
<PropertyGroup>
<MsBuildProperties>Configuration=$(Configuration);Platform=$(Platform)</MsBuildProperties>
</PropertyGroup>
<MSBuild Projects="@(ProjectReference)"
BuildInParallel="$(BuildInParallel)"
Properties="$(MsBuildProperties)"
Targets="%(ProjectReference.Targets)" />
<ItemGroup>
<BuildProjectReferencesOutput Include="%(ProjectReference.IncludeFilePath)">
<ProjectName>$([System.IO.Path]::GetFileNameWithoutExtension('%(ProjectReference.Identity)'))</ProjectName>
</BuildProjectReferencesOutput>
</ItemGroup>
</Target>
<Target Name="_CalculateArtifactStagingDirectory" Condition=" '$(ArtifactStagingDirectory)'=='' ">
<PropertyGroup>
<ArtifactStagingDirectory Condition=" '$(OutDir)'!='' ">$(OutDir)</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" '$(ArtifactStagingDirectory)'=='' ">$(OutputPath)</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" !HasTrailingSlash('$(ArtifactStagingDirectory)') ">$(ArtifactStagingDirectory)\</ArtifactStagingDirectory>
<ArtifactStagingDirectory>$(ArtifactStagingDirectory)staging\</ArtifactStagingDirectory>
<ArtifactStagingDirectory Condition=" '$(Build_StagingDirectory)'!='' AND '$(TF_Build)'=='True' ">$(Build_StagingDirectory)</ArtifactStagingDirectory>
</PropertyGroup>
</Target>
<!-- Appends each of the deployment project's content output files with metadata indicating its relative path from the deployment project's folder. -->
<Target Name="_CalculateContentOutputRelativePaths"
Outputs="%(DeploymentProjectContentOutput.Identity)">
<PropertyGroup>
<_OriginalIdentity>%(DeploymentProjectContentOutput.Identity)</_OriginalIdentity>
<_RelativePath>$(_OriginalIdentity.Replace('$(MSBuildProjectDirectory)', ''))</_RelativePath>
</PropertyGroup>
<ItemGroup>
<DeploymentProjectContentOutput>
<RelativePath>$(_RelativePath)</RelativePath>
</DeploymentProjectContentOutput>
</ItemGroup>
</Target>
<Target Name="CoreCompile" />
<PropertyGroup>
<StageArtifactsAfterTargets Condition=" '$(StageArtifacts)' == 'true' ">
PrepareForRun
</StageArtifactsAfterTargets>
</PropertyGroup>
<Target Name="StageArtifacts" DependsOnTargets="$(StageArtifactsDependsOn)" AfterTargets="$(StageArtifactsAfterTargets)"/>
<!-- Custom target to clean up local deployment staging files -->
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
<RemoveDir Directories="$(OutputPath)" />
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
</Project>

Просмотреть файл

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>d31d50c1-187d-4e1a-aa32-869b2cb1a70f</ProjectGuid>
</PropertyGroup>
<PropertyGroup>
<PrepareForBuildDependsOn>
</PrepareForBuildDependsOn>
</PropertyGroup>
<Import Condition=" Exists('Deployment.targets') " Project="Deployment.targets" />
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
<!-- vertag<:>start tokens<:>maj.min -->
<Import Condition=" Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Deployment\1.1\DeploymentProject.targets') " Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Deployment\1.1\DeploymentProject.targets" />
<!-- vertag<:>end -->
<ItemGroup>
<Content Include="kubernetes.aks.deploy.json" />
<Content Include="kubernetes.aks.parameters.json" />
<None Include="Deployment.targets">
<Visible>False</Visible>
</None>
<None Include="Pipeline\git_placeholder.md" />
<Content Include="Policy\kubernetes.aks.deploy.json" />
<Content Include="Policy\kubernetes.aks.parameters.json" />
<Content Include="RBAC\kubernetes.aks.deploy.json" />
<Content Include="RBAC\kubernetes.aks.parameters.json" />
<Content Include="Scripts\create-and-upload-ca-cert.sh" />
<Content Include="Scripts\create-and-upload-helm-and-tiller-certs.sh" />
<Content Include="Scripts\create-cluster-rbac-role-bindings.sh" />
<Content Include="Scripts\create-sign-w-x509-and-upload-cert.sh" />
<Content Include="Scripts\create-tiller-enabled-namespace.sh" />
<Content Include="Scripts\install-kubectl.sh" />
<Content Include="Scripts\install-secured-tiller-instance.sh" />
<Content Include="Scripts\view-all-cluster-role.yaml" />
<None Include="Tests\kubernetes.aks.module.tests.ps1" />
<Content Include="Tests\kubernetes.aks.output.tests.ps1" />
<None Include="_README.md" />
</ItemGroup>
<Target Name="GetReferenceAssemblyPaths" />
</Project>

Просмотреть файл

@ -1,320 +0,0 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aksClusterName": {
"type": "string",
"metadata": {
"description": "AKS Cluster Name"
}
},
"subscriptionId": {
"type": "string",
"metadata": {
"description": "AKS Cluster deployment Subcription Id"
}
},
"location": {
"type": "string",
"metadata": {
"description": "The location of AKS resource."
}
},
"osDiskSizeGb": {
"defaultValue": 0,
"minValue": 0,
"maxValue": 1023,
"type": "int",
"metadata": {
"description": "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize."
}
},
"osType": {
"defaultValue": "Linux",
"allowedValues": [
"Linux"
],
"type": "string",
"metadata": {
"description": "The type of operating system."
}
},
"agentCount": {
"defaultValue": 3,
"minValue": 1,
"maxValue": 50,
"type": "int",
"metadata": {
"description": "The number of agent nodes for the cluster."
}
},
"agentVMSize": {
"defaultValue": "Standard_D2_v2",
"type": "string",
"metadata": {
"description": "The size of the Virtual Machine."
}
},
"servicePrincipalClientId": {
"type": "securestring",
"metadata": {
"description": "Client ID (used by cloudprovider)."
}
},
"servicePrincipalClientSecret": {
"type": "securestring",
"metadata": {
"description": "The Service Principal Client Secret."
}
},
"kubernetesVersion": {
"defaultValue": "1.7.7",
"type": "string",
"metadata": {
"description": "The version of Kubernetes."
}
},
"networkPlugin": {
"allowedValues": [
"azure",
"kubenet"
],
"type": "string",
"metadata": {
"description": "Network plugin used for building Kubernetes network."
}
},
"vnetSubnetId": {
"type": "string",
"metadata": {
"description": "Resource ID of virtual network subnet used for nodes and/or pods IP assignment."
}
},
"serviceCIDR": {
"type": "string",
"metadata": {
"description": "A CIDR notation IP range from which to assign service cluster IPs."
}
},
"dnsPrefix": {
"type": "string",
"metadata": {
"description": "Optional DNS prefix to use with hosted Kubernetes API server FQDN."
}
},
"dnsServiceIP": {
"type": "string",
"metadata": {
"description": "Containers DNS server IP address."
}
},
"dockerBridgeCIDR": {
"type": "string",
"metadata": {
"description": "A CIDR notation IP for Docker bridge."
}
},
"diagnosticEventHubName": {
"type": "string",
"defaultValue": "",
"metadata": {
"description": "Event Hub Name for the diagnostics events"
}
},
"diagnosticEventHubAuthRuleId": {
"type": "string",
"metadata": {
"description": "Resource ID of the event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to."
}
},
"diagnosticOMSId": {
"type": "string",
"metadata": {
"description": "Resource ID containing the insights"
}
},
"diagnosticStorageId": {
"type": "string",
"metadata": {
"description": "Storage account for the diagnostics events"
}
},
"enableRBAC": {
"defaultValue": true,
"type": "bool",
"metadata": {
"description": "Boolean flag to turn on and off of RBAC."
}
},
"rbacServerAppId": {
"type": "string",
"metadata": {
"description": "RBAC server app id"
}
},
"rbacServerSecret": {
"type": "string",
"metadata": {
"description": "RBAC server app secret"
}
},
"rbacClientAppId": {
"type": "string",
"metadata": {
"description": "RBAC client app id"
}
},
"rbacTenant": {
"type": "string",
"metadata": {
"description": "RBAC tenant"
}
}
},
"variables": {
"authRuleResourceId": "[parameters('diagnosticEventHubAuthRuleId')]",
"emptyContent": {},
"omsAgentConfig": {
"omsagent": {
"enabled": true,
"config": {
"logAnalyticsWorkspaceResourceID": "[parameters('diagnosticOMSId')]"
}
}
}
},
"resources": [
{
"type": "Microsoft.ContainerService/managedClusters",
"name": "[parameters('aksClusterName')]",
"apiVersion": "2018-03-31",
"location": "[parameters('location')]",
"properties": {
"kubernetesVersion": "[parameters('kubernetesVersion')]",
"enableRBAC": "[parameters('enableRBAC')]",
"dnsPrefix": "[parameters('dnsPrefix')]",
"agentPoolProfiles": [
{
"name": "agentpool",
"osDiskSizeGB": "[parameters('osDiskSizeGb')]",
"count": "[parameters('agentCount')]",
"vmSize": "[parameters('agentVMSize')]",
"osType": "[parameters('osType')]",
"storageProfile": "ManagedDisks",
"vnetSubnetID": "[parameters('vnetSubnetId')]"
}
],
"servicePrincipalProfile": {
"clientId": "[parameters('servicePrincipalClientId')]",
"Secret": "[parameters('servicePrincipalClientSecret')]"
},
"networkProfile": {
"networkPlugin": "[parameters('networkPlugin')]",
"serviceCidr": "[parameters('serviceCIDR')]",
"dnsServiceIP": "[parameters('dnsServiceIP')]",
"dockerBridgeCidr": "[parameters('dockerBridgeCIDR')]"
},
"aadProfile": {
"clientAppID": "[parameters('rbacClientAppId')]",
"serverAppID": "[parameters('rbacServerAppId')]",
"serverAppSecret": "[parameters('rbacServerSecret')]",
"tenantID": "[parameters('rbacTenant')]"
},
"addonProfiles": "[if( empty(parameters('diagnosticOMSId')) , variables('emptyContent'), variables('omsAgentConfig'))]"
},
"resources": [
{
"type": "Microsoft.ContainerService/managedClusters/providers/diagnosticSettings",
"name": "[concat(parameters('aksClusterName'), '/Microsoft.Insights/service')]",
"dependsOn": [
"[resourceId('Microsoft.ContainerService/managedClusters', parameters('aksClusterName'))]"
],
"apiVersion": "2017-05-01-preview",
"properties": {
"workspaceId": "[parameters('diagnosticOMSId')]",
"storageAccountId": "[parameters('diagnosticStorageId')]",
"eventHubName": "[parameters('diagnosticEventHubName')]",
"eventHubAuthorizationRuleId": "[parameters('diagnosticEventHubAuthRuleId')]",
"logs": [
{
"category": "kube-apiserver",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-controller-manager",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "cluster-autoscaler",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-scheduler",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
},
{
"category": "kube-audit",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
}
],
"metrics": [
{
"timeGrain": "PT1M",
"enabled": true,
"retentionPolicy": {
"enabled": false,
"days": 0
}
}
]
}
}
],
"dependsOn": [
]
}
],
"outputs": {
"nodeResourceGroupId": {
"type": "string",
"value": "[concat('/subscriptions/', parameters('subscriptionId'), '/resourceGroups/', reference(concat('Microsoft.ContainerService/managedClusters/', parameters('aksClusterName'))).nodeResourceGroup)]"
},
"nodeResourceGroupName": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', parameters('aksClusterName'))).nodeResourceGroup]"
},
"aksFQDN": {
"type": "string",
"value": "[reference(concat('Microsoft.ContainerService/managedClusters/', parameters('aksClusterName'))).fqdn]"
},
"namespaceConnectionString": {
"type": "string",
"value": "[listkeys(variables('authRuleResourceId'), '2017-04-01').primaryConnectionString]"
},
"sharedAccessPolicyPrimaryKey": {
"type": "string",
"value": "[listkeys(variables('authRuleResourceId'), '2017-04-01').primaryKey]"
}
}
}

Просмотреть файл

@ -1,81 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aksClusterName": {
"value": "org-aks-cluster"
},
"subscriptionId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000"
},
"location": {
"value": "West US 2"
},
"osDiskSizeGb": {
"value": 60
},
"osType": {
"value": "Linux"
},
"agentCount": {
"value": 2
},
"agentVMSize": {
"value": "Standard_DS3_v2"
},
"servicePrincipalClientId": {
"value": "00000000-0000-0000-0000-000000000000"
},
"servicePrincipalClientSecret": {
"value": "secret"
},
"kubernetesVersion": {
"value": "1.12.6"
},
"networkPlugin": {
"value": "azure"
},
"vnetSubnetId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-net-rg/providers/Microsoft.Network/virtualNetworks/org-aks-vnet/subnets/default"
},
"serviceCIDR": {
"value": "11.0.0.0/16"
},
"dnsPrefix": {
"value": "aks"
},
"dnsServiceIP": {
"value": "11.0.0.10"
},
"dockerBridgeCIDR": {
"value": "172.17.0.1/16"
},
"diagnosticEventHubName": {
"value": "org-event-hub"
},
"diagnosticEventHubAuthRuleId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-diagnostics-rg/providers/Microsoft.EventHub/namespaces/doeventhubnamespace/AuthorizationRules/RootManageSharedAccessKey"
},
"diagnosticOMSId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-diagnostics-rg/providers/Microsoft.OperationalInsights/workspaces/org-aks-la"
},
"diagnosticStorageId": {
"value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/org-aks-diagnostics-rg/providers/Microsoft.Storage/storageAccounts/doaksdiagcyxhc6odcasnec"
},
"enableRBAC": {
"value": true
},
"rbacServerAppId": {
"value": "00000000-0000-0000-0000-000000000000"
},
"rbacServerSecret": {
"value": "secret"
},
"rbacClientAppId": {
"value": "00000000-0000-0000-0000-000000000000"
},
"rbacTenant": {
"value": "00000000-0000-0000-0000-000000000000"
}
}
}

Просмотреть файл

@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.539
MinimumVisualStudioVersion = 10.0.40219.1
Project("{151D2E53-A2C4-4D7D-83FE-D05416EBD58E}") = "Kubernetes AKS", "2.0\Kubernetes.aks_2.0.deployproj", "{D31D50C1-187D-4E1A-AA32-869B2CB1A70F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D31D50C1-187D-4E1A-AA32-869B2CB1A70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D31D50C1-187D-4E1A-AA32-869B2CB1A70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D31D50C1-187D-4E1A-AA32-869B2CB1A70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D31D50C1-187D-4E1A-AA32-869B2CB1A70F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5CC08404-76BA-4EEC-9EA0-1534D4BDCA06}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -402,628 +402,12 @@
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Available Bytes"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter14",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Committed Bytes"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter15",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Cache Bytes"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter16",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Pool Paged Bytes"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter17",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Pool Nonpaged Bytes"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter18",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Pages/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter19",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Memory",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Page Faults/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter20",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Process",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Working Set"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter21",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Process",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Working Set - Private"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter22",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "% Disk Time"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter23",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "% Disk Read Time"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter24",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "% Disk Write Time"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter25",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "% Idle Time"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter26",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Disk Bytes/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter27",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Disk Read Bytes/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter28",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Disk Write Bytes/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter29",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Disk Transfers/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter30",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Disk Reads/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter31",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Disk Writes/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter32",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Avg. Disk sec/Transfer"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter33",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Avg. Disk sec/Read"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter34",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Avg. Disk sec/Write"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter35",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Avg. Disk Queue Length"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter36",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Avg. Disk Write Queue Length"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter37",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "% Free Space"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter38",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "LogicalDisk",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Free Megabytes"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter39",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Bytes Total/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter40",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Bytes Sent/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter41",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Bytes Received/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter42",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Packets/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter43",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Packets Sent/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter44",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Packets Received/sec"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter45",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Packets Outbound Errors"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "windowsPerfCounter46",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "WindowsPerformanceCounter",
"properties": {
"objectName": "Network Interface",
"instanceName": "*",
"intervalSeconds": 60,
"counterName": "Packets Received Errors"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "sampleIISLog1",
"condition": false,
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "IISLogs",
"properties": {
"state": "OnPremiseEnabled"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "sampleSyslog1",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "LinuxSyslog",
"properties": {
"syslogName": "kern",
"syslogSeverities": [
{
"severity": "emerg"
},
{
"severity": "alert"
},
{
"severity": "crit"
},
{
"severity": "err"
},
{
"severity": "warning"
}
]
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "sampleSyslogCollection1",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "LinuxSyslogCollection",
"properties": {
"state": "Enabled"
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "sampleLinuxPerf1",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "LinuxPerformanceObject",
"properties": {
"performanceCounters": [
{
"counterName": "% Used Inodes"
},
{
"counterName": "Free Megabytes"
},
{
"counterName": "% Used Space"
},
{
"counterName": "Disk Transfers/sec"
},
{
"counterName": "Disk Reads/sec"
},
{
"counterName": "Disk Writes/sec"
}
],
"objectName": "Logical Disk",
"instanceName": "*",
"intervalSeconds": 10
}
},
{
"apiVersion": "2015-11-01-preview",
"type": "datasources",
"name": "sampleLinuxPerfCollection1",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"kind": "LinuxPerformanceCollection",
"properties": {
"state": "Enabled"
}
},
{
"apiVersion": "2015-03-20",
"name": "[concat(parameters('diagnosticStorageAccountName'),parameters('logAnalyticsWorkspaceName'))]",
"type": "storageinsightconfigs",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName'))]"
],
"properties": {
"containers": [],
"tables": [
"WADWindowsEventLogsTable",
"WADETWEventTable",
"WADServiceFabric*EventTable",
"LinuxsyslogVer2v0"
],
"storageAccount": {
"id": "[parameters('diagnosticStorageAccountId')]",
"key": "[parameters('diagnosticStorageAccountAccessKey')]"
}
}
}
]
},

Просмотреть файл

@ -162,19 +162,19 @@
}
],
"outputs": {
"ServiceBusConnectionString": {
"serviceBusConnectionString": {
"type": "string",
"value": "[listkeys(variables('defaultAuthRuleResourceId'), variables('sbVersion')).primaryConnectionString]"
},
"ServiceBusPrimaryKey": {
"serviceBusPrimaryKey": {
"type": "string",
"value": "[listkeys(variables('defaultAuthRuleResourceId'), variables('sbVersion')).primaryKey]"
},
"ServiceBusSendListenConnectionString": {
"serviceBusSendListenConnectionString": {
"type": "string",
"value": "[listkeys(variables('SendListenAuthRuleResourceId'), variables('sbVersion')).primaryConnectionString]"
},
"ServiceBusSendListenPrimaryKey": {
"serviceBusSendListenPrimaryKey": {
"type": "string",
"value": "[listkeys(variables('SendListenAuthRuleResourceId'), variables('sbVersion')).primaryKey]"
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"value": "vdcstorageawus018"
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"value": "vdcstorageawus018"
}
}
}

Просмотреть файл

@ -0,0 +1,153 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Azure Firewall ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Azure Firewall ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Azure Firewall ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "parameters.json") | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = $File }
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Azure Firewall" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Has environment parameters file" {
(Join-Path "$here" "parameters.json") | Should Exist
}
It "Parameter file contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
BeforeEach {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") `
| Select-Object -ExpandProperty Name) ) {
$Module.Template = $File
}
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "parameters.json") `
| Select-Object -ExpandProperty Name) ) {
$Module.Parameters = $File
}
}
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
It "Has all parameters in parameters file existing in template file" {
$allParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
It "Has required parameters in template file existing in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,47 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: output.test.ps1
Purpose: Test - Azure Firewall ARM Template Output Variables
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Firewall ARM template output variables.
.DESCRIPTION
This script contains functionality used to test Azure Firewall ARM template output variables.
Deployment steps of the script are outlined below.
1) Outputs Variable Logic to pipeline
.PARAMETER AzureFirewallResourceId
Specify the Azure Firewall Workspace Name output parameter.
.EXAMPLE
Default:
C:\PS>.\azure.firewall.output.test.ps1 `
-AzureFirewallResourceId <"AzureFirewallResourceId">
#>
#Requires -Version 5
[CmdletBinding()]
param
(
[Parameter(Mandatory = $false)]
[string]$AzureFirewallResourceId
)
if($AzureFirewallResourceId -ne $null)
{
write-output "Azure Firewall Resource Id: $($AzureFirewallResourceId)"
}
else
{
write-output "Azure Firewall Resource Id: NULL"
}

Просмотреть файл

@ -0,0 +1,76 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"azureFirewallName": {
"value": "org-shrdsvcs-azfw"
},
"azureFirewallResourceGroupName": {
"value": "org-shrdsvcs-network-rg"
},
"azureFirewallSubscriptionId": {
"value": "00000000-0000-0000-0000-000000000000"
},
"azureFirewallNatRuleCollection": {
"value": []
},
"azureFirewallApplicationRuleCollection": {
"value": [
{
"name":"aks-cluster-01",
"properties":
{
"rules": [
{
"name":"cluster",
"protocols": [
{
"protocolType":"Http",
"port":80
},
{
"protocolType":"Https",
"port":443
}
],
"targetFqdns": [ "*" ],
"fqdnTags": [],
"sourceAddresses": [ "10.2.0.0/17" ]
}
],
"priority":500,
"action":
{
"type":"Allow"
}
}
}
]
},
"azureFirewallNetworkRuleCollection": {
"value": [
{
"name":"aks-cluster-nrc-01",
"properties":
{
"rules": [
{
"sourceAddresses": [ "10.2.0.0/17" ],
"name":"allow-ssh-access",
"destinationAddresses": [ "*" ],
"protocols": [ "TCP" ],
"description": "Allows outbound SSH access",
"destinationPorts": [ "22" ]
}
],
"priority":"500",
"action":
{
"type":"Allow"
}
}
}
]
}
}
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Policy" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Policy" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Policy" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,163 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Key Vault ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Azure Key Vault ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Azure Key Vault ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -ErrorAction SilentlyContinue -Recurse | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "RBAC" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("deploy.json")) -ErrorAction SilentlyContinue ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "RBAC" -AdditionalChildPath @("*parameters.json")) -Recurse | Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "RBAC" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
if ($null -ne $TemplateFileTestCases -and
$TemplateFileTestCases.Count -gt 0) {
#region Run Pester Test Script
Describe "Template: $template - Key Vault" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" -TestCases $TemplateFileTestCases {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
Write-Host "TF: $TemplateFile"
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,81 @@
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"azureFirewallName": {
"type": "string",
"metadata": {
"description": "Required. Azure Firewall Name."
}
},
"azureFirewallResourceGroupName": {
"type": "string",
"metadata": {
"description": "Required. Azure Firewall Resource Group Name."
}
},
"azureFirewallSubscriptionId": {
"type": "string",
"metadata": {
"description": "Required. Azure Firewall Subscription Id."
}
},
"azureFirewallNatRuleCollection": {
"type": "array",
"metadata": {
"description": "Required. Array containing Azure Firewall Nat rule collections"
}
},
"azureFirewallApplicationRuleCollection": {
"type": "array",
"metadata": {
"description": "Required. Array containing Azure Firewall application rule collections"
}
},
"azureFirewallNetworkRuleCollection": {
"type": "array",
"metadata": {
"description": "Required. Array containing Firewall network rule collections"
}
}
},
"variables": {
"azureFirewallPipName": "[concat(parameters('azureFirewallName'), '-pip')]",
"azureFirewallPipId": "[resourceId('Microsoft.Network/publicIPAddresses', variables('azureFirewallPipName'))]"
},
"resources": [
{
"apiVersion": "2019-06-01",
"name": "nestedDeployCreateAzureApplicationRules",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('azureFirewallResourceGroupName')]",
"subscriptionId": "[parameters('azureFirewallSubscriptionId')]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/azureFirewalls",
"apiVersion": "2019-06-01",
"location": "[resourceGroup().location]",
"name": "[parameters('azureFirewallName')]",
"properties": {
"ipConfigurations": "[reference(resourceId(parameters('azureFirewallSubscriptionId'), parameters('azureFirewallResourceGroupName'), 'Microsoft.Network/azureFirewalls', parameters('azureFirewallName')), '2018-08-01').ipConfigurations]",
"natRuleCollections": "[parameters('azureFirewallNatRuleCollection')]",
"applicationRuleCollections": "[parameters('azureFirewallApplicationRuleCollection')]",
"networkRuleCollections": "[parameters('azureFirewallNetworkRuleCollection')]"
}
}
]
}
}
}
],
"outputs": {
}
}

Просмотреть файл

@ -0,0 +1,45 @@
# AzureFirewall
This module deploys Azure Firewall.
## Resources
- Microsoft.Network/azureFirewalls
- Microsoft.Network/azureFirewalls/providers/diagnosticsettings
- Microsoft.Network/publicIPAddresses
## Parameters
| Parameter Name | Default Value | Description |
| :- | :- | :- |
| `azureFirewallName` | | Required. Name of the Azure Firewall.
| `applicationRuleCollections` | | Required. Collection of application rule collections used by Azure Firewall.
| `networkRuleCollections` | | Required. Collection of network rule collections used by Azure Firewall.
| `vNetId` | | Required. Shared services Virtual Network resource Id
| `diagnosticStorageAccountId` | | Required. Diagnostic Storage Account resource identifier
| `workspaceId` | | Required. Log Analytics workspace resource identifier
| `logsRetentionInDays` | `365` | Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.
## Outputs
| Output Name | Description |
| :- | :- |
| `azureFirewallResourceId` | The Resource Id of the Azure Firewall.
| `azureFirewallName` | The Name of the Azure Firewall.
| `azureFirewallResourceGroup` | The name of the Resource Group the Azure Firewall was created in.
| `azureFirewallPrivateIp` | The private IP of the Azure Firewall.
| `azureFirewallPublicIp` | The public IP of the Azure Firewall.
| `applicationRuleCollections` | List of Application Rule Collections.
| `networkRuleCollections` | List of Network Rule Collections.
## Considerations
The `applicationRuleCollections` parameter accepts a JSON Array of AzureFirewallApplicationRule objects.
The `networkRuleCollections` parameter accepts a JSON Array of AzureFirewallNetworkRuleCollection objects.
## Additional resources
- [Microsoft.Network azureFirewalls template reference](https://docs.microsoft.com/en-us/azure/templates/microsoft.network/2018-08-01/azurefirewalls)
- [AzureFirewallApplicationRuleCollection object reference](https://docs.microsoft.com/en-us/azure/templates/microsoft.network/2018-08-01/azurefirewalls#AzureFirewallApplicationRuleCollection)
- [AzureFirewallNetworkRuleCollection object reference](https://docs.microsoft.com/en-us/azure/templates/microsoft.network/2018-08-01/azurefirewalls#AzureFirewallNetworkRuleCollection)

Просмотреть файл

@ -24,37 +24,25 @@
#Requires -Version 5
#region Parameters
#region - Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
ForEach ($File in (Get-ChildItem (Join-Path "$here" "deploy.json") | Select-Object -ExpandProperty Name))
{
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Tests" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Tests" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
$ParameterFileTestCases = @()
ForEach ($File in (Get-ChildItem (Join-Path "$here" "parameters.json") | Select-Object -ExpandProperty Name))
{
$ParameterFileTestCases += @{ ParameterFile = $File }
}
#endregion
#region Run Pester Test Script
#region - Run Pester Test Script
Describe "Template: $template - Virtual Network" -Tags Unit {
Context "Template File Syntax" {
@ -64,13 +52,13 @@ Describe "Template: $template - Virtual Network" -Tags Unit {
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
Param ($TemplateFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
'outputs'| Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
@ -82,13 +70,15 @@ Describe "Template: $template - Virtual Network" -Tags Unit {
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
It "Has environment parameters file" {
(Join-Path "$here" "parameters.json") | Should Exist
}
It "Parameter file contains the expected properties" -TestCases $ParameterFileTestCases {
Param ($ParameterFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
@ -96,64 +86,69 @@ Describe "Template: $template - Virtual Network" -Tags Unit {
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
BeforeEach {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
ForEach ($File in (Get-ChildItem (Join-Path "$here" "deploy.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Template = $File
}
ForEach ($File in (Get-ChildItem (Join-Path "$here" "parameters.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Parameters = $File
}
}
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
It "Has all parameters in parameters file existing in template file" {
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
$allParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
@($allParametersInParametersFile | Where-Object { $allParametersInTemplateFile -notcontains $_ }).Count | Should Be 0
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
It "Has required parameters in template file existing in parameters file" {
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
@($requiredParametersInTemplateFile | Where-Object { $allParametersInParametersFile -notcontains $_ }).Count | Should Be 0
}
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,154 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Virtual Network ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Virtual Network ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Virtual Network ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region - Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ($File in (Get-ChildItem (Join-Path "$here" "deploy.json") | Select-Object -ExpandProperty Name))
{
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ($File in (Get-ChildItem (Join-Path "$here" "parameters.json") | Select-Object -ExpandProperty Name))
{
$ParameterFileTestCases += @{ ParameterFile = $File }
}
#endregion
#region - Run Pester Test Script
Describe "Template: $template - Virtual Network" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param ($TemplateFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs'| Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Has environment parameters file" {
(Join-Path "$here" "parameters.json") | Should Exist
}
It "Parameter file contains the expected properties" -TestCases $ParameterFileTestCases {
Param ($ParameterFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
BeforeEach {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
ForEach ($File in (Get-ChildItem (Join-Path "$here" "deploy.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Template = $File
}
ForEach ($File in (Get-ChildItem (Join-Path "$here" "parameters.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Parameters = $File
}
}
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count
}
It "Has all parameters in parameters file existing in template file" {
$allParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($allParametersInParametersFile | Where-Object { $allParametersInTemplateFile -notcontains $_ }).Count | Should Be 0
}
It "Has required parameters in template file existing in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile | Where-Object { $allParametersInParametersFile -notcontains $_ }).Count | Should Be 0
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,159 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Virtual Network ARM Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test Virtual Network ARM template synatax.
.DESCRIPTION
This script contains functionality used to test Virtual Network ARM template synatax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Tests" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Tests" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Virtual Network" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion

Просмотреть файл

@ -5,7 +5,7 @@
File: module.tests.ps1
Purpose: Pester - Test Virtual Network Peering Peering Templates
Purpose: Pester - Test vNet Peering Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
@ -24,53 +24,41 @@
#Requires -Version 5
#region Parameters
#region - Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*deploy.json") | Select-Object -ExpandProperty Name))
{
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Tests" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Tests" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
$ParameterFileTestCases = @()
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*parameters.json") | Select-Object -ExpandProperty Name))
{
$ParameterFileTestCases += @{ ParameterFile = $File }
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Virtual Network Peering" -Tags Unit {
#region - Run Pester Test Script
Describe "Template: $template - vNetPeering" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
(Join-Path "$here" "*deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
Param ($TemplateFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
'outputs'| Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
@ -82,13 +70,15 @@ Describe "Template: $template - Virtual Network Peering" -Tags Unit {
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
It "Has environment parameters file" {
(Join-Path "$here" "*parameters.json") | Should Exist
}
It "Parameter file contains the expected properties" -TestCases $ParameterFileTestCases {
Param ($ParameterFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
@ -96,64 +86,69 @@ Describe "Template: $template - Virtual Network Peering" -Tags Unit {
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
BeforeEach {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*deploy.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Template = $File
}
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*parameters.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Parameters = $File
}
}
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
It "Has all parameters in parameters file existing in template file" {
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
$allParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
@($allParametersInParametersFile | Where-Object { $allParametersInTemplateFile -notcontains $_ }).Count | Should Be 0
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
It "Has required parameters in template file existing in parameters file" {
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
@($requiredParametersInTemplateFile | Where-Object { $allParametersInParametersFile -notcontains $_ }).Count | Should Be 0
}
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,154 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test vNet Peering Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test vNet Peering ARM template syntax.
.DESCRIPTION
This script contains functionality used to test vNet Peering ARM template syntax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region - Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*deploy.json") | Select-Object -ExpandProperty Name))
{
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*parameters.json") | Select-Object -ExpandProperty Name))
{
$ParameterFileTestCases += @{ ParameterFile = $File }
}
#endregion
#region - Run Pester Test Script
Describe "Template: $template - vNetPeering" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "*deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param ($TemplateFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs'| Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Has environment parameters file" {
(Join-Path "$here" "*parameters.json") | Should Exist
}
It "Parameter file contains the expected properties" -TestCases $ParameterFileTestCases {
Param ($ParameterFile)
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
BeforeEach {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*deploy.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Template = $File
}
ForEach ($File in (Get-ChildItem (Join-Path "$here" "*parameters.json") `
| Select-Object -ExpandProperty Name))
{
$Module.Parameters = $File
}
}
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count
}
It "Has all parameters in parameters file existing in template file" {
$allParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($allParametersInParametersFile | Where-Object { $allParametersInTemplateFile -notcontains $_ }).Count | Should Be 0
}
It "Has required parameters in template file existing in parameters file" {
$requiredParametersInTemplateFile = (Get-Content (Join-Path "$here" "$($Module.Template)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
$allParametersInParametersFile = (Get-Content (Join-Path "$here" "$($Module.Parameters)") `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile | Where-Object { $allParametersInParametersFile -notcontains $_ }).Count | Should Be 0
}
}
}
#endregion

Просмотреть файл

@ -0,0 +1,159 @@
<#
.NOTES
==============================================================================================
Copyright(c) Microsoft Corporation. All rights reserved.
File: module.tests.ps1
Purpose: Pester - Test Virtual Network Peering Peering Templates
Version: 1.0.0.0 - 1st April 2019 - Azure Virtual Datacenter Development Team
==============================================================================================
.SYNOPSIS
This script contains functionality used to test vNet Peering ARM template syntax.
.DESCRIPTION
This script contains functionality used to test vNet Peering ARM template syntax.
Deployment steps of the script are outlined below.
1) Test Template File Syntax
2) Test Parameter File Syntax
3) Test Template and Parameter File Compactibility
#>
#Requires -Version 5
#region Parameters
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$here = Join-Path $here ".."
$template = Split-Path -Leaf $here
$TemplateFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") -Recurse | Select-Object -ExpandProperty Name) ) {
$TemplateFileTestCases += @{ TemplateFile = $File }
}
$ParameterFileTestCases = @()
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) ) {
$ParameterFileTestCases += @{ ParameterFile = Join-Path "Tests" $File }
}
$Modules = @();
ForEach ( $File in (Get-ChildItem (Join-Path "$here" "deploy.json") ) ) {
$Module = [PSCustomObject]@{
'Template' = $null
'Parameters' = $null
}
$Module.Template = $File.FullName;
$Parameters = @();
ForEach ( $ParameterFile in (Get-ChildItem (Join-Path "$here" "Tests" -AdditionalChildPath @("*parameters.json")) -Recurse -ErrorAction SilentlyContinue| Select-Object -ExpandProperty Name) ) {
$Parameters += (Join-Path "$here" "Tests" -AdditionalChildPath @("$ParameterFile") )
}
$Module.Parameters = $Parameters;
$Modules += @{ Module = $Module };
}
#endregion
#region Run Pester Test Script
Describe "Template: $template - Virtual Network Peering" -Tags Unit {
Context "Template File Syntax" {
It "Has a JSON template file" {
(Join-Path "$here" "deploy.json") | Should Exist
}
It "Converts from JSON and has the expected properties" -TestCases $TemplateFileTestCases {
Param( $TemplateFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters',
'variables',
'resources',
'outputs' | Sort-Object
$templateProperties = (Get-Content (Join-Path "$here" "$TemplateFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateProperties | Should Be $expectedProperties
}
}
Context "Parameter File Syntax" {
It "Parameter file does not contains the expected properties" -TestCases $ParameterFileTestCases {
Param( $ParameterFile )
$expectedProperties = '$schema',
'contentVersion',
'parameters' | Sort-Object
Write-Host $ParameterFile
Join-Path "$here" "$ParameterFile" | Write-Host
$templateFileProperties = (Get-Content (Join-Path "$here" "$ParameterFile") `
| ConvertFrom-Json -ErrorAction SilentlyContinue) `
| Get-Member -MemberType NoteProperty `
| Sort-Object -Property Name `
| ForEach-Object Name
$templateFileProperties | Should Be $expectedProperties
}
}
Context "Template and Parameter Compactibility" {
It "Is count of required parameters in template file equal or lesser than count of all parameters in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$requiredParametersInTemplateFile.Count | Should Not BeGreaterThan $allParametersInParametersFile.Count;
}
}
It "Has all parameters in parameters file existing in template file" -TestCases $Modules {
Param( $Module )
$allParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
Write-Host "File analyzed: $Parameter";
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
$result = @($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_});
Write-Host "Invalid parameters: $(ConvertTo-Json $result)";
@($allParametersInParametersFile| Where-Object {$allParametersInTemplateFile -notcontains $_}).Count | Should Be 0;
}
}
It "Has required parameters in template file existing in parameters file" -TestCases $Modules {
Param( $Module )
$requiredParametersInTemplateFile = (Get-Content "$($Module.Template)" `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Where-Object -FilterScript { -not ($_.Value.PSObject.Properties.Name -eq "defaultValue") } `
| Sort-Object -Property Name `
| ForEach-Object Name
ForEach ( $Parameter in $Module.Parameters ) {
$allParametersInParametersFile = (Get-Content $Parameter `
| ConvertFrom-Json -ErrorAction SilentlyContinue).Parameters.PSObject.Properties `
| Sort-Object -Property Name `
| ForEach-Object Name
@($requiredParametersInTemplateFile| Where-Object {$allParametersInParametersFile -notcontains $_}).Count | Should Be 0;
}
}
}
}
#endregion

Просмотреть файл

@ -235,8 +235,14 @@ Class CustomScriptExecution {
if($null -ne $parameterName `
-and $arguments.ContainsKey($parameterName) `
-and $parameterName -notin $systemParameters) {
if($arguments[$parameterName] -is [array]) {
$orderedArguments += , $arguments[$parameterName];
}
else {
$orderedArguments += $arguments[$parameterName];
}
}
elseif($null -ne $parameterName `
-and $parameterName -notin $systemParameters) {
$orderedArguments += $null;
@ -300,7 +306,7 @@ Class CustomScriptExecution {
(Get-Job -Name $job.Name).ChildJobs | ForEach-Object {
# Set the result only if there is an output
if($_.Output.Count -ge 1) {
$result = $_.Output[$_.Output.Count-1];
$result = $_.Output | Select-Object -Property * -ExcludeProperty PSComputerName,RunspaceID,PSShowComputerName;
}
else {
$result = $null;

Просмотреть файл

@ -582,11 +582,12 @@ Function New-CustomScripts {
# value otherwise Powershell detects that $scriptOutput is an object and
# will preserve it which results in having a $deploymentOutputs.Output
# equals to an object instead of the desired returned string
if ($scriptOutput.GetType().ToString().ToLower() -like "*string") {
if ($null -ne $scriptOutput -and `
$scriptOutput.GetType().ToString().ToLower() -like "*string") {
$tmpOutput = $scriptOutput.ToString();
$type = "String";
}
else {
elseif($null -ne $scriptOutput){
# TODO: Analyze other types.
$type = "Object";
$tmpOutput = $scriptOutput;

Просмотреть файл

@ -0,0 +1,88 @@
#!/usr/bin/env bash
DIR=$(dirname $0)
PGM=$(basename $0)
# Names set in set-environment-vars.sh:
# VNET
# KEY_VAULT_NAME
# PRIVATE_DNS_ZONE
# CA_CERT_KEY_NAME
# CA_NAME
SP_ID=$1
SP_SECRET=$2
TENANT=$3
KEY_VAULT_NAME=$4
CA_CERT_KEY_NAME=$5
CA_NAME=$6
az login --service-principal -u $SP_ID -p $SP_SECRET --tenant $TENANT
# keyvault appears to need pkc8
KEY_CONTENT=$(openssl genpkey \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:2048 | \
openssl pkcs8 -topk8 \
-nocrypt \
-inform PEM \
-outform PEM
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: error creating private key:$KEY_CONTENT"
exit 1
fi
# this config section is needed to support
# getting basic constraint for CA:TRUE
# added
CONFIG="
[req]
distinguished_name=dn
[ dn ]
[ ext ]
basicConstraints=CA:TRUE,pathlen:0
"
CA_CERT_CONTENT=$(openssl \
req -new \
-subj "/CN=$CA_NAME" \
-key <(echo "$KEY_CONTENT") \
-config <(echo "$CONFIG") \
-extensions ext \
-sha256 -days 365 -nodes -x509 -out /dev/stdout
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: error creating ca cert:$CA_CERT_CONTENT"
exit 1
fi
# need to concatenate key and cert as PEM
CERT_WITH_KEY=$(echo -e "${KEY_CONTENT}\n${CA_CERT_CONTENT}")
echo "$PGM: Checking cert with key ..."
CHECK_CERT_RESULT=$(
openssl x509 -text -noout -in <(echo "$CERT_WITH_KEY" 2>&1 )
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Verifying cert failed:$CHECK_CERT_RESULT"
exit 1
fi
echo "$PGM: CERT is valid"
# upload cert with key to keyvault
echo "$PGM: importing CA certificate to keyvault ... $KEY_VAULT_NAME"
IMPORT_RESULT=$(az keyvault certificate import \
--name $CA_CERT_KEY_NAME \
--vault-name $KEY_VAULT_NAME \
--file <(echo "$CERT_WITH_KEY")
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: upload cert failed:$IMPORT_RESULT"
exit 1
fi
echo "$PGM: import complete"

Просмотреть файл

@ -0,0 +1,25 @@
#!/usr/bin/env bash
DIR=$(dirname $0)
PGM=$(basename $0)
if [[ "$1" == "" ]];then
echo "$PGM: usage namespace"
exit 1
fi
TILLER_NAMESPACE=$1
KEY_VAULT_NAME=$2
CA_CERT_NAME=$3
HELM_CA=helm
TILLER_CA=tiller
if [[ $TILLER_NAMESPACE != "tiller" ]];then
HELM_CA=${TILLER_NAMESPACE}-$HELM_CA
TILLER_CA=${TILLER_NAMESPACE}-$TILLER_CA
fi
echo "$PGM: Creating helm cert with CA:$HELM_CA"
#$DIR/../infra/create-sign-w-x509-and-upload-cert.sh "$@" $HELM_CA
$DIR/create-sign-w-x509-and-upload-cert.sh central-tst-rbac $HELM_CA $KEY_VAULT_NAME $CA_CERT_NAME
echo "$PGM: Creating tiller cert with CA:$TILLER_CA"
#$DIR/../infra/create-sign-w-x509-and-upload-cert.sh "$@" $TILLER_CA "IP:127.0.0.1"
$DIR/create-sign-w-x509-and-upload-cert.sh central-tst-rbac $TILLER_CA $KEY_VAULT_NAME $CA_CERT_NAME "IP:127.0.0.1"

Просмотреть файл

@ -0,0 +1,188 @@
#!/usr/bin/env bash
#
# - Creates binding for cluster-admin role
# - Creates role and binding for view-all custom cluster role
# which extends the default view role to allow view access
# to cluster resources (e.g. nodes, secret names [not content])
#
PGM=$(basename $0)
DIR=$(dirname $0)
SP_ID=$1
SP_SECRET=$2
TENANT=$3
CLUSTER_NAME=$4
CLUSTER_RG=$5
RBAC_CLUSTER_ADMIN_AD_GROUP=$6
RBAC_CLUSTER_VIEW_AD_GROUP=$7
RBAC_EXTEND_VIEW_CLUSTER_ROLE=$8
RBAC_ENABLE_READ_ONLY_DASHBOARD=$9
az login --service-principal -u $SP_ID -p $SP_SECRET --tenant $TENANT
if [[ -z $RBAC_CLUSTER_ADMIN_AD_GROUP ]] && [[ -z $RBAC_CLUSTER_VIEW_ALL_AD_GROUP ]];then
echo "$PGM: Neither RBAC_CLUSTER_ADMIN_AD_GROUP or RBAC_CLUSTER_VIEW_ALL_AD_GROUP are set. Nothing to do."
exit 0
fi
#CLUSTER_NAME=$ENV_NAME-k8s
echo "$PGM: Getting admin credentials for cluster:$CLUSTER_NAME"
TMP_KUBECONFIG=$(mktemp)
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating temp file:$TMP_KUBECONFIG"
exit 1
fi
function cleanup {
echo "$PGM: Removing tmp file $TMP_KUBECONFIG ...";
rm -f $TMP_KUBECONFIG;
echo "$PGM: Done removing tmp file"
}
trap cleanup EXIT
echo "$PGM: Using temp file:$TMP_KUBECONFIG for kubeconfig"
# get admin credentials
echo "$PGM: cluster rg: $CLUSTER_RG name: $CLUSTER_NAME"
AKS_ADMIN_CREDS=$(az aks get-credentials --admin -n $CLUSTER_NAME -g $CLUSTER_RG --file $TMP_KUBECONFIG)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error getting admin credentials:$AKS_ADMIN_CREDS"
exit 1
fi
# bind AD Group to admin cluster role
# this should be for "break glass" access to the cluster
if [[ ! -z $RBAC_CLUSTER_ADMIN_AD_GROUP ]];then
echo "$PGM: Binding cluster role cluster-admin to AD Group:$RBAC_CLUSTER_ADMIN_AD_GROUP"
API_OBJECT=$(cat <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aad-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: "$RBAC_CLUSTER_ADMIN_AD_GROUP"
EOF
)
#ADMIN_BINDING_RESULT=$(kubectl create clusterrolebinding aad-cluster-admin \
# --kubeconfig=$TMP_KUBECONFIG \
# --clusterrole=cluster-admin \
# --group=$RBAC_CLUSTER_ADMIN_AD_GROUP 2>&1
#)
ADMIN_BINDING_RESULT=$(kubectl apply --kubeconfig $TMP_KUBECONFIG -f <(echo "$API_OBJECT") 2>&1)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating cluster-admin binding: $ADMIN_BINDING_RESULT"
exit 1
fi
fi # end create clsuter-admin binding
# bind AAD group to cluster view (read only role)
if [[ ! -z $RBAC_CLUSTER_VIEW_AD_GROUP ]];then
if [[ $RBAC_EXTEND_VIEW_CLUSTER_ROLE == "Y" ]];then
echo "$PGM: Extending view cluster role ..."
EXTEND_VIEW_RESULT=$(kubectl apply --kubeconfig $TMP_KUBECONFIG -f $DIR/view-all-cluster-role.yaml 2>&1)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error extending view clusterrole: $EXTEND_VIEW_RESULT"
exit 1
fi
else
echo "$PGM: NOT extending view cluster role"
fi
echo "$PGM: Binding cluster role view to AD Group:$RBAC_CLUSTER_VIEW_AD_GROUP"
API_OBJECT=$(cat <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aad-view
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: "$RBAC_CLUSTER_VIEW_AD_GROUP"
EOF
)
#VIEW_BINDING_RESULT=$(kubectl apply clusterrolebinding aad-view \
# --kubeconfig=$TMP_KUBECONFIG \
# --clusterrole=view \
# --group=$RBAC_CLUSTER_VIEW_AD_GROUP 2>&1
#)
VIEW_BINDING_RESULT=$(kubectl apply --kubeconfig $TMP_KUBECONFIG -f <(echo "$API_OBJECT") 2>&1)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating view binding:$VIEW_BINDING_RESULT"
exit 1
else
echo "$PGM: Cluster view binding created"
fi
fi # end create view binding
#
# If you want to allow internal access to the
# kubernetes dashboard with RBAC enabled:
#
# 1. Grant service account read only rights to resources
# 2. Grant access to create proxy to dashboard
#
if [[ ! -z $RBAC_ENABLE_READ_ONLY_DASHBOARD ]];then
echo "$PGM: Creating dashboard view clusterrole binding"
DASHBOARD_NS=kube-system
DASHBOARD_SA=kubernetes-dashboard
API_OBJECT=$(cat <<EOF
#
# Grant view access to the kubernetes dashboard
#
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dashboard-view-all
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: ${DASHBOARD_SA}
namespace: ${DASHBOARD_NS}
---
#
# This is needed to let users with "view"
# ClusterRole run the proxy.
#
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dashboard-proxy
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["kubernetes-dashboard"]
verbs: ["get", "list", "watch"]
EOF
)
#
#DASHBOARD_BINDING_RESULT=$(kubectl apply clusterrolebinding dashboard-view-all \
# --kubeconfig=$TMP_KUBECONFIG \
# --clusterrole=view \
# --serviceaccount=${DASHBOARD_NS}:${DASHBOARD_SA} 2>&1
#)
DASHBOARD_BINDING_RESULT=$(kubectl apply --kubeconfig $TMP_KUBECONFIG -f <(echo "$API_OBJECT") 2>&1)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating dashboard view binding:$DASHBOARD_BINDING_RESULT"
exit 1
else
echo "$PGM: Dashboard view binding created"
fi
fi # end grant dashboard view

Просмотреть файл

@ -0,0 +1,173 @@
#!/usr/bin/env bash
DIR=$(dirname $0)
PGM=$(basename $0)
# Names set in set-environment-vars.sh:
KEY_VAULT_NAME=$3
CA_CERT_NAME=$4
#
# Subject Alternative Names (SAN) need to be comma
# separated list type as prefix. e.g.
# DNS:www.helm,DNS:helm,IP:127.0.0.1,IP:10.0.1.100
#
if [[ "$#" -ne 4 ]] && [[ "$#" -ne 5 ]];then
echo "$PGM usage: $PGM environment cert-name [SAN]"
exit 1
fi
CERT_NAME=$2
SAN=
if [[ "$5" != "" ]];then
echo "$PGM: Using Subject Alternative Name (SAN) parameter :$5"
SAN=$5
fi
echo "$PGM: Getting CA key:$CA_CERT_NAME from vault:$KEY_VAULT_NAME .."
CA_KEY_PAIR=$( \
az keyvault secret download \
--name $CA_CERT_NAME \
--vault-name $KEY_VAULT_NAME \
--file /dev/stdout
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error getting CA Cert:$CA_KEY_PAIR"
exit 1
fi
echo "$CA_KEY_PAIR"
echo "$PGM: Checking CA cert ..."
CHECK_KEY_PAIR_RESULT=$(
openssl x509 -text -noout -in <(echo "$CA_KEY_PAIR")
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Verifying cert failed:$CHECK_KEY_PAIR_RESULT"
exit 1
fi
echo "$PGM: CA cert is ok"
# extract the cert and private key
# need these to be separate as tyring to pass
# keypair environment vars as input files does
# not work with openssl x509 command
echo "$PGM: Extracting keypair parts ..."
CA_CERT=$(openssl x509 \
-outform pem \
-in <(echo "$CA_KEY_PAIR") \
-out /dev/stdout)
CA_KEY=$(openssl pkey \
-in <(echo "$CA_KEY_PAIR") \
-out /dev/stdout)
# create the private key and convert to pkcs8 format
# TODO: confirm with keyvault that we need pkcs8
echo "$PGM: Creating private key for $CERT_NAME ..."
PK=$( \
openssl genpkey \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:2048 | \
openssl pkcs8 -topk8 \
-nocrypt \
-inform PEM \
-outform PEM
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating private key:$PK"
exit 1
fi
CONFIG_PARM=
if [[ "$SAN" != "" ]];then
SUBJECT_ALT_NAME="subjectAltName = DNS:$CERT_NAME,$SAN"
fi
#TODO: see what other properties/usage flags are needed
CONFIG_FILE=$(cat <<EOF
[req]
prompt = no
distinguished_name = dn
req_extensions = req_ext
[dn]
CN = $CERT_NAME
[req_ext]
basicConstraints = CA:FALSE
$SUBJECT_ALT_NAME
EOF
)
# Create CSR
echo "$PGM: Creating CSR ..."
CSR=$(openssl req \
-new \
-config <(echo "$CONFIG_FILE") \
-sha256 \
-key <(echo "$PK") \
-subj "/CN=$CERT_NAME" \
-out /dev/stdout
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating CSR:$CSR"
exit 1
fi
echo "$PGM: Checking CSR ..."
CHECK_CSR_RESULT=$(
openssl req -verify -text -noout -in <(echo "$CSR") 2>&1
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "Verifying CSR failed:$CHECK_CSR_RESULT"
exit 1
fi
echo "$PGM: CSR is valid"
echo "$PGM: Creating cert"
CERT=$(openssl x509 \
-req \
-days 365 \
-CA <(echo "$CA_CERT") \
-set_serial $(date +%s)$((1 + RANDOM % 1000)) \
-CAkey <(echo "$CA_KEY") \
-in <(echo "$CSR") \
-extfile <(echo "$CONFIG_FILE") \
-extensions req_ext \
-out /dev/stdout
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating Cert:$CERT"
exit 1
fi
echo "$PGM: Checking cert ..."
CHECK_CERT_RESULT=$(
openssl x509 -text -noout -in <(echo "$CERT") 2>&1
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Verifying cert failed:$CHECK_CERT_RESULT"
exit 1
fi
echo "$PGM: CERT is valid"
# upload cert to keyvault
# need to concatenate the key and cert into PEM
echo "$PGM: Uploading certificate ..."
UPLOAD=$( \
az keyvault certificate import \
--name $CERT_NAME \
--vault-name $KEY_VAULT_NAME \
--file <(echo -e "${PK}\n${CERT}" 2>&1)
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: upload cert failed:$UPLOAD"
exit 1
fi
echo "$PGM: Upload complete"

Просмотреть файл

@ -0,0 +1,136 @@
#!/usr/bin/env bash
# This needs to be run with k8s cluster-admin role
PGM=$(basename $0)
DIR=$(dirname $0)
#
# Function to create tiller enabled namespace
# Parameters:
# tiller namespace
# path to kubeconfig file
function createTillerNamespace {
# This is a pre-req for running helm init
# for global or namespace-scoped tiller
# instances
#
# Naming convention indicates if this is
# global or scoped.
#
# If the namespace is "tiller", then the
# assumption is this is a global single
# global (cluster-wide) instance and will
# be granted the cluster-admin role.
#
# Otheriwse the assumption is that it's a
# instance scoped to a namespace
if [[ "$#" -ne 2 ]];then
echo "$PGM usage namespace path-to-kubeconfig-file"
exit 1
fi
local TARGET_NAMESPACE=$1
local KUBECONFIG_FILE=$2
echo "$PGM: Starting with TARGET_NAMESPACE:$TARGET_NAMESPACE KUBECONFIG_FILE:$KUBECONFIG_FILE"
# This could be replaced with more specific role
TILLER_RBAC_ROLE=cluster-admin
if [[ $TARGET_NAMESPACE == "tiller" ]];then
echo "$PGM: Creating namespace for global tiller instance:$TARGET_NAMESPACE"
BINDING_TYPE=ClusterRoleBinding
BINDING_NAMESPACE='#'
else
echo "$PGM: Creating namespace for scoped tiller instance:$TARGET_NAMESPACE"
TILLER_NAMESPACE=$TARGET_NAMESPACE-tiller
BINDING_TYPE=RoleBinding
BINDING_NAMESPACE="namespace: $TARGET_NAMESPACE"
fi
# If this is not a tiller global namspace, then create the target
# namespace first as this will be the target of the role grant to tiller
if [[ $TARGET_NAMESPACE != "tiller" ]];then
APPLY_NS_RESULT=$(cat <<EOF | KUBECONFIG=$KUBECONFIG_FILE kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: $TARGET_NAMESPACE
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: $TARGET_NAMESPACE
namespace: $TARGET_NAMESPACE
EOF
)
rc=$?
if [[ rc -ne 0 ]];then
echo "$PGM: Error creating target (non-tiller) namespace:$APPLY_NS_RESULT"
exit 1
fi
echo "$PGM: Created target (non-tiller) namespace:$TARGET_NAMESPACE"
fi
echo "$PGM: Granting tiller rights to target namespace:$TARGET_NAMESPACE"
APPLY_RESULT=$(cat <<EOF | KUBECONFIG=$KUBECONFIG_FILE kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: $TILLER_NAMESPACE
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: $TILLER_NAMESPACE
---
kind: $BINDING_TYPE
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: $TILLER_NAMESPACE-$TILLER_RBAC_ROLE
$BINDING_NAMESPACE
subjects:
- kind: ServiceAccount
name: tiller
namespace: $TILLER_NAMESPACE
roleRef:
kind: ClusterRole
name: $TILLER_RBAC_ROLE
apiGroup: rbac.authorization.k8s.io
EOF
)
rc=$?
if [[ rc -ne 0 ]];then
echo "$PGM: Error creating namespace:$APPLY_RESULT"
exit 1
fi
# For non-global tiller, it (it's service account) needs
# RBAC rights to it's own namespace to be able to
# store configuration data in secrets/config maps
if [[ $TARGET_NAMESPACE != "tiller" ]];then
echo "$PGM: Granting non-global tiller rights in it's own namespace:$TILLER_NAMESPACE"
APPLY_RESULT=$(cat <<EOF | KUBECONFIG=$KUBECONFIG_FILE kubectl apply -f -
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: $TILLER_NAMESPACE-$TILLER_RBAC_ROLE
namespace: $TILLER_NAMESPACE
subjects:
- kind: ServiceAccount
name: tiller
namespace: $TILLER_NAMESPACE
roleRef:
kind: ClusterRole
name: $TILLER_RBAC_ROLE
apiGroup: rbac.authorization.k8s.io
EOF
)
rc=$?
if [[ rc -ne 0 ]];then
echo "$PGM: Error creating namespace:$APPLY_RESULT"
exit 1
fi
fi # end of if not global tiller
}

2
Scripts/AKS/install-kubectl.sh Executable file
Просмотреть файл

@ -0,0 +1,2 @@
apt-get install -y ca-certificates
az aks install-cli

Просмотреть файл

@ -0,0 +1,190 @@
#!/usr/bin/env bash
DIR=$(dirname $0)
PGM=$(basename $0)
ENV_NAME=$1
KEY_VAULT_NAME=$3
CLUSTER_NAME=$4
CLUSTER_RG=$5
CA_CERT_KEY_NAME=$6
if [[ -z $2 ]];then
echo "$PGM: usage environment target-namespace"
exit 1
fi
TARGET_NAMESPACE=$2
echo "$PGM: Starting create of tiller instance for namespace:$TARGET_NAMESPACE"
# import functions
. $DIR/create-tiller-enabled-namespace.sh
# temp directory
MY_TEMPDIR=$(mktemp -d)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating temp file:$MY_TEMPDIR"
exit 1
fi
function cleanup {
echo "$PGM: Removing tmp dir $MY_TEMPDIR ...";
rm -rf $MY_TEMPDIR;
echo "$PGM: Done removing tmp dir"
}
trap cleanup EXIT
#
# Create certificates (identities for helm/tiller)
#
# If the name is tiller its assumed to be a global
# instance for the cluster, otherwise
# the namespace becomes <namespace>-tiller/helm for
# a namespace scoped tiller instance
#
TILLER_CN=tiller
HELM_CN=helm
TILLER_NAMESPACE=$TILLER_CN
if [[ $TARGET_NAMESPACE != "tiller" ]];then
HELM_CN=${TARGET_NAMESPACE}-$HELM_CN
TILLER_CN=${TARGET_NAMESPACE}-$TILLER_CN
TILLER_NAMESPACE=$TILLER_CN
fi
echo "$PGM: Creating helm cert with CN:$HELM_CN"
$DIR/../aks/create-sign-w-x509-and-upload-cert.sh $ENV_NAME $HELM_CN $KEY_VAULT_NAME $CA_CERT_KEY_NAME
echo "$PGM: Creating tiller cert with CA:$TILLER_CN"
$DIR/../aks/create-sign-w-x509-and-upload-cert.sh $ENV_NAME $TILLER_CN $KEY_VAULT_NAME $CA_CERT_KEY_NAME "IP:127.0.0.1"
# local names for cert/key files
# the names match default names searched for in $HELM_HOME by helm when using --tls
CA_CERT_FILE=$MY_TEMPDIR/ca.pem
TILLER_CERT_FILE=$MY_TEMPDIR/cert.pem
TILLER_KEY_FILE=$MY_TEMPDIR/key.pem
#
# Get kubernetes admin credentials
#
KUBECONFIG_FILE=$MY_TEMPDIR/config
GET_CREDS_RESULT=$(az aks get-credentials --admin -n $CLUSTER_NAME -g $CLUSTER_RG --file $KUBECONFIG_FILE)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error getting admin credentials:$GET_CREDS_RESULT"
exit 1
fi
echo "$PGM: Using temp file:$KUBECONFIG_FILE for kubeconfig"
#
# get the CA and tiller/helm certs from key vault
#
echo "$PGM: Getting CA cert $CA_CERT_KEY_NAME from key vault:$KEY_VAULT_NAME"
CA_CERT_DOWNLOAD=$(
az keyvault certificate download \
--name $CA_CERT_KEY_NAME \
--vault-name $KEY_VAULT_NAME \
-f $CA_CERT_FILE 2>&1 )
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error downloading CA Cert:$CA_CERT_DOWNLOAD"
exit 1
fi
echo "$PGM: Getting tiller keypair"
TILLER_KEY_PAIR=$( \
az keyvault secret download \
--name $TILLER_CN \
--vault-name $KEY_VAULT_NAME \
--file /dev/stdout
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error getting tiller key pair:$TILLER_KEY_PAIR"
exit 1
fi
#
# check that the certs are ok
#
echo "$PGM: Checking tiller key pair ..."
CHECK_TILLER_KEY_PAIR_RESULT=$(
openssl x509 -text -noout -in <(echo "$TILLER_KEY_PAIR")
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Verifying cert failed:$CHECK_TILLER_KEY_PAIR_RESULT"
exit 1
fi
echo "$PGM: Tiller key pair is ok ..."
#
# extract the cert and private key
#
echo "$PGM: Extracting keypair parts ..."
TILLER_CERT_CONTENT=$(openssl x509 \
-outform pem \
-in <(echo "$TILLER_KEY_PAIR") \
-out $TILLER_CERT_FILE 2>&1)
TILLER_KEY_CONTENT=$(openssl pkey \
-in <(echo "$TILLER_KEY_PAIR") \
| openssl rsa -out $TILLER_KEY_FILE 2>&1)
# see https://github.com/helm/helm/blob/master/docs/securing_installation.md
# use temp dir as helm reads from files twice so won't work with processes substitution
DRY_RUN=
#DRY_RUN="--dry-run"
DEBUG=
#DEBUG="--debug"
#
# Create the tiller namespace
#
createTillerNamespace $TARGET_NAMESPACE $KUBECONFIG_FILE
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: Error creating tiller enabled namespace:$TARGET_NAMESPACE"
exit 1
fi
# Initialize
HELM_INIT_RESULT=$(KUBECONFIG=$KUBECONFIG_FILE helm init \
$DRY_RUN \
$DEBUG \
--override 'spec.template.spec.containers[0].command'='{/tiller,--storage=secret}' \
--tiller-namespace ${TILLER_NAMESPACE} \
--service-account tiller \
--home $MY_TEMPDIR \
--tiller-tls \
--tiller-tls-verify \
--tiller-tls-cert "$TILLER_CERT_FILE" \
--tiller-tls-key "$TILLER_KEY_FILE" \
--tls-ca-cert "$CA_CERT_FILE"
)
rc=$?
if [[ $rc -ne 0 ]];then
echo "$PGM: helm init returned error:$HELM_INIT_RESULT"
exit 1
fi
echo "$PGM: $HELM_INIT_RESULT"
#
# Wait for tiller deployment to complete
# If timeout is exceeded, script exits with exit code 1 and terminates deployment
#
TILLER_COMPLETE='deployment "tiller-deploy" successfully rolled out'
TILLER_STATUS=$(kubectl rollout status deployment/tiller-deploy --kubeconfig $KUBECONFIG_FILE -n ${TILLER_NAMESPACE})
echo "$PGM: waiting for tiller to deploy in namespace: $TILLER_NAMESPACE"
COUNTER=0
while true; do
if [[ "$TILLER_STATUS" == "$TILLER_COMPLETE" ]];then
echo "$PGM: tiller deployed and in Ready state"
exit 0
elif [[ $COUNTER -eq "24" ]];then
echo "$PGM: tiller deployment timeout exceeded"
exit 1
else
sleep 5
TILLER_STATUS=$(kubectl rollout status deployment/tiller-deploy --kubeconfig $KUBECONFIG_FILE -n ${TILLER_NAMESPACE})
COUNTER=$[$COUNTER + 1]
fi
done

Просмотреть файл

@ -0,0 +1,28 @@
#
# Add get list watch to support read only view in dashboard and via cli.
# Extends the default view role to inlcude infrastructure resources
# Note: this could also be added to specific roles
#
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: view-all
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
# add nodes and persitent volumes
- apiGroups: [""]
resources: ["nodes","persistentvolumes"]
verbs: ["get", "list", "watch"]
# secrets are list/watch only
- apiGroups: [""]
resources: ["secrets"]
verbs: ["list", "watch"]
# storage classes ...
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
# roles and cluster roles
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles","roles","rolebindings"]
verbs: ["get","list", "watch"]