func createKubernetesMasterResourcesVMAS()

in pkg/engine/masterarmresources.go [13:153]


func createKubernetesMasterResourcesVMAS(cs *api.ContainerService) []interface{} {
	var masterResources []interface{}

	p := cs.Properties

	if p.MasterProfile.HasCosmosEtcd() {
		masterResources = append(masterResources, createCosmosDBAccount())
	}

	if p.HasManagedDisks() {
		if !p.HasAvailabilityZones() {
			masterResources = append(masterResources, CreateAvailabilitySet(cs, true))
		}
	} else if p.MasterProfile.IsStorageAccount() {
		availabilitySet := CreateAvailabilitySet(cs, false)
		storageAccount := createStorageAccount(cs)
		masterResources = append(masterResources, availabilitySet, storageAccount)
	}

	if !p.MasterProfile.IsCustomVNET() {
		virtualNetwork := CreateVirtualNetwork(cs)
		masterResources = append(masterResources, virtualNetwork)
	}

	masterNsg := CreateNetworkSecurityGroup(cs)
	masterResources = append(masterResources, masterNsg)

	if cs.Properties.RequireRouteTable() {
		masterResources = append(masterResources, createRouteTable())
	}

	kubernetesConfig := cs.Properties.OrchestratorProfile.KubernetesConfig

	if kubernetesConfig.PrivateJumpboxProvision() {
		jumpboxVM := createJumpboxVirtualMachine(cs)
		masterResources = append(masterResources, jumpboxVM)
		jumpboxIsManagedDisks :=
			kubernetesConfig.PrivateJumpboxProvision() &&
				kubernetesConfig.PrivateCluster.JumpboxProfile.StorageProfile == api.ManagedDisks
		if !jumpboxIsManagedDisks {
			jumpBoxStorage := createJumpboxStorageAccount()
			masterResources = append(masterResources, jumpBoxStorage)
		}
		jumpboxNSG := createJumpboxNSG()
		jumpboxNIC := createJumpboxNetworkInterface(cs)
		jumpboxPublicIP := createJumpboxPublicIPAddress()
		masterResources = append(masterResources, jumpboxNSG, jumpboxNIC, jumpboxPublicIP)
	}

	var masterNic NetworkInterfaceARM
	if cs.Properties.OrchestratorProfile.IsPrivateCluster() {
		masterNic = createPrivateClusterMasterVMNetworkInterface(cs)
	} else {
		masterNic = CreateMasterVMNetworkInterfaces(cs)
	}
	masterResources = append(masterResources, masterNic)

	// We don't create a master load balancer in a private cluster + single master vm scenario
	if !(cs.Properties.OrchestratorProfile.IsPrivateCluster() && !p.MasterProfile.HasMultipleNodes()) &&
		// And we don't create a master load balancer in a private cluster + Basic LB scenario
		!(cs.Properties.OrchestratorProfile.IsPrivateCluster() && cs.Properties.OrchestratorProfile.KubernetesConfig.LoadBalancerSku == api.BasicLoadBalancerSku) {
		loadBalancer := CreateMasterLoadBalancer(cs.Properties)
		// In a private cluster scenario, the master NIC spec is different,
		// and the master LB is for outbound access only and doesn't require a DNS record for the public IP
		includeDNS := !cs.Properties.OrchestratorProfile.IsPrivateCluster()
		publicIPAddress := CreatePublicIPAddressForMaster(includeDNS)
		masterResources = append(masterResources, publicIPAddress, loadBalancer)
	}

	if p.MasterProfile.HasMultipleNodes() {
		internalLB := CreateMasterInternalLoadBalancer(cs)
		masterResources = append(masterResources, internalLB)
	}

	var isKMSEnabled bool
	if kubernetesConfig != nil {
		isKMSEnabled = to.Bool(kubernetesConfig.EnableEncryptionWithExternalKms)
	}

	if isKMSEnabled {
		keyVaultStorageAccount := createKeyVaultStorageAccount()
		keyVault := CreateKeyVaultVMAS(cs)
		keyVaultKey := CreateKeyVaultKey(cs)
		masterResources = append(masterResources, keyVaultStorageAccount, keyVault, keyVaultKey)
	}

	if cs.Properties.FeatureFlags.IsFeatureEnabled("EnableIPv6DualStack") {
		// for standard lb sku, the loadbalancer and ipv4 FE is already created
		if cs.Properties.OrchestratorProfile.KubernetesConfig.LoadBalancerSku != api.StandardLoadBalancerSku {
			clusterIPv4PublicIPAddress := CreateClusterPublicIPAddress()
			clusterLB := CreateClusterLoadBalancerForIPv6()

			masterResources = append(masterResources, clusterIPv4PublicIPAddress, clusterLB)
		}
	}

	masterVM := CreateMasterVM(cs)
	masterResources = append(masterResources, masterVM)

	var useManagedIdentity, userAssignedIDEnabled bool
	useManagedIdentity = to.Bool(kubernetesConfig.UseManagedIdentity)
	userAssignedIDEnabled = kubernetesConfig.UserAssignedIDEnabled()

	if useManagedIdentity && !userAssignedIDEnabled {
		vmasRoleAssignment := createVMASRoleAssignment()
		masterResources = append(masterResources, vmasRoleAssignment)
	}

	masterCSE := CreateCustomScriptExtension(cs)
	if isKMSEnabled {
		masterCSE.ARMResource.DependsOn = append(masterCSE.ARMResource.DependsOn, "[concat('Microsoft.KeyVault/vaults/', variables('clusterKeyVaultName'))]")
	}

	// If the control plane is in a discrete VNET
	if hasDistinctControlPlaneVNET(cs) {
		// TODO: This is only necessary if the resource group of the masters is different from the RG of the node pool
		// subnet. But when we generate the template we don't know to which RG it will be deployed to. To solve this we
		// would have to add the necessary condition into the template. For the resources we can use the `condition` field
		// but how can we conditionally declare the dependencies? Perhaps by creating a variable for the dependency array
		// and conditionally adding more dependencies.
		if kubernetesConfig.SystemAssignedIDEnabled() &&
			// The fix for ticket 2373 is only available for individual VMs / AvailabilitySet.
			cs.Properties.MasterProfile.IsAvailabilitySet() {
			masterRoleAssignmentForAgentPools := createKubernetesMasterRoleAssignmentForAgentPools(cs.Properties.MasterProfile, cs.Properties.AgentPoolProfiles)

			for _, assignmentForAgentPool := range masterRoleAssignmentForAgentPools {
				masterResources = append(masterResources, assignmentForAgentPool)
				masterCSE.ARMResource.DependsOn = append(masterCSE.ARMResource.DependsOn, *assignmentForAgentPool.Name)
			}
		}
	}

	masterResources = append(masterResources, masterCSE)

	customExtensions := CreateCustomExtensions(cs.Properties)
	for _, ext := range customExtensions {
		masterResources = append(masterResources, ext)
	}

	return masterResources
}