public async Task ReceiveReminderAsync(string reminderName, byte[] context, TimeSpan dueTime, TimeSpan period) { if (reminderName.Equals(CheckProvision)) { ServiceFabricEventSource.Current.ActorMessage(this, "Checking Provision"); var clusterKey = this.Id.GetStringId();//Subscription/ResourceGroup/clustername/nodename; ActorState State = await StateManager.GetStateAsync <ActorState>(StateKey); var processorNode = await ClusterConfigStore.GetMessageClusterResourceAsync(clusterKey) as ClusterProcessorNode; if (!State.IsInitialized) { if (processorNode != null) { var nodeName = processorNode.Name; var config = this.GetConfigurationInfo(); var armClinet = new ArmClient(await config.GetAccessToken()); var vmss = await armClinet.GetAsync <VMSS>($"/subscriptions/{config.SubscriptionId}/resourceGroups/{config.ResourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/vm{nodeName.ToLower()}", "2016-03-30"); var fabric = await armClinet.GetAsync <JObject>($"/subscriptions/{config.SubscriptionId}/resourceGroups/{config.ResourceGroupName}/providers/Microsoft.ServiceFabric/clusters/{config.ClusterName}", "2016-03-01"); var primvmss = await armClinet.GetAsync <JObject>($"/subscriptions/{config.SubscriptionId}/resourceGroups/{config.ResourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{config.PrimaryScaleSetName}", "2016-03-30"); var parameters = new JObject( ResourceManagerHelper.CreateValue("clusterName", config.ClusterName), ResourceManagerHelper.CreateValue("clusterLocation", "West Europe"), ResourceManagerHelper.CreateValue("nodeTypeName", nodeName), ResourceManagerHelper.CreateValue("certificateThumbprint", fabric.SelectToken("properties.certificate.thumbprint").ToString()), ResourceManagerHelper.CreateValue("adminPassword", "JgT5FFJK"), ResourceManagerHelper.CreateValue("sourceVaultValue", primvmss.SelectToken("properties.virtualMachineProfile.osProfile.secrets[0].sourceVault.id").ToString()), ResourceManagerHelper.CreateValue("certificateUrlValue", primvmss.SelectToken("properties.virtualMachineProfile.osProfile.secrets[0].vaultCertificates[0].certificateUrl").ToString()) ); var deployment = await ResourceManagerHelper.CreateTemplateDeploymentAsync( new ApplicationCredentials { AccessToken = await config.GetAccessToken(), SubscriptionId = config.SubscriptionId, }, config.ResourceGroupName, $"vmss-{nodeName}", //-{DateTimeOffset.UtcNow.ToString("s").Replace(":", "-")}", new VmssArmTemplate(processorNode.Properties, vmss?.Sku?.capacity ?? 0), parameters, false, appendTimestamp : true ); if (deployment.Properties.ProvisioningState == "Succeeded") { State.IsInitialized = true; State.VMSSResourceId = (deployment.Properties.Outputs as JObject).SelectToken("vmssResourceId.value").ToString(); ServiceFabricEventSource.Current.ActorMessage(this, "Initialization Complated"); } } } if (State.IsInitialized) { ServiceFabricEventSource.Current.ActorMessage(this, "Validating node configuration with vmss"); var client = new ArmClient(await this.GetConfigurationInfo().GetAccessToken()); var vmms = await client.GetAsync <JObject>(State.VMSSResourceId, "2016-03-30"); State.Capacity = vmms.SelectToken("sku.capacity").ToObject <int>(); var virtualMachines = await client.GetAsync <JObject>(State.VMSSResourceId + "/virtualMachines", "2016-03-30"); var deleting = virtualMachines.SelectTokens("$value[?(@.properties.provisioningState == 'Deleting')]"); var fabric = new FabricClient(); //Remove all nodes that are i teh deleting state of VMSS; foreach (JObject delete in deleting) { var instanceId = delete.SelectToken("instanceId").ToString(); var name = delete.SelectToken("name").ToString(); var node = await fabric.QueryManager.GetNodeListAsync("_" + name); if (node.Any()) { ServiceFabricEventSource.Current.ActorMessage(this, $"Removing {node.First().NodeName} state due to vm being deleted"); await fabric.ClusterManager.RemoveNodeStateAsync(node.First().NodeName); } } //Remove all nodes that are down and not in the virtualmachine list. var nodes = await fabric.QueryManager.GetNodeListAsync(); foreach (var node in nodes.Where(n => n.NodeStatus == System.Fabric.Query.NodeStatus.Down && n.NodeName.StartsWith($"_vm{NodeTypeName}"))) { if (!virtualMachines.SelectTokens($"$value[?(@.instanceId == '{node.NodeName.Split('_').Last()}')]").Any()) { ServiceFabricEventSource.Current.ActorMessage(this, $"Removing {node.NodeName} state due to vm not existing"); await fabric.ClusterManager.RemoveNodeStateAsync(node.NodeName); } } if (vmms.SelectToken("properties.provisioningState").ToString() == "Succeeded") { State.IsProvisioning = false; await UnregisterReminderAsync(GetReminder(reminderName)); } } await StateManager.SetStateAsync(StateKey, State); } }