/// <summary>
        /// TODO: Clean this up.  check and errors.
        ///
        /// Should check the loadbalancer.inner.status to see if update is already in progress.
        /// Also should batch the queue items, add and configure multiple up configurations at once if they are in the queue.
        /// </summary>
        /// <param name="tenantDeployment"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task <TenantDeployment> ProcessIpDeploymentAsync(TenantDeployment tenantDeployment, CancellationToken cancellationToken)
        {
            var spId           = Environment.GetEnvironmentVariable("SERVICE_PRINCIPAL_ID");
            var spSecret       = Environment.GetEnvironmentVariable("SERVICE_PRINCIPAL_SECRET");
            var spTenantId     = Environment.GetEnvironmentVariable("SERVICE_PRINCIPAL_TENANT_ID");
            var subscriptionId = Environment.GetEnvironmentVariable("SUBSCRIPTION_ID");

            var creds = new AzureCredentialsFactory().FromServicePrincipal(spId, spSecret, spTenantId, AzureEnvironment.AzureGlobalCloud);
            var azure = Azure.Authenticate(creds).WithSubscription(subscriptionId);

            string loadBalancerName = Environment.GetEnvironmentVariable("LOAD_BALANCER");
            string backendPool      = Environment.GetEnvironmentVariable("BACKENDPOOL");
            string resourcegroup    = Environment.GetEnvironmentVariable("RESOURCEGROUP");
            string tenantname       = $"deployment-{tenantDeployment.Name}";

            //TODO check provisioning state of load balancer and delay if currently busy
            //var provisioningState = azure.ResourceGroups.GetByName(loadBalancer.ResourceGroupName).ProvisioningState;

            try
            {
                var loadBalancer = await azure.LoadBalancers.GetByResourceGroupAsync(resourcegroup, loadBalancerName, cancellationToken);

                ILoadBalancerPublicFrontend publicFrontend = loadBalancer.PublicFrontends.First().Value;
                var publicIpAddress = publicFrontend.GetPublicIPAddress();

                await loadBalancer.Update()
                .DefineTcpProbe(tenantname + "_mc")
                .WithPort(tenantDeployment.InternalPort)
                .Attach()
                .DefineLoadBalancingRule($"{tenantname}_mc")
                .WithProtocol(TransportProtocol.Tcp)
                .FromExistingPublicIPAddress(publicIpAddress)
                .FromFrontendPort(tenantDeployment.InternalPort)
                .ToBackend(backendPool)
                .ToBackendPort(tenantDeployment.InternalPort)
                .WithProbe(tenantname + "_mc")
                .Attach()
                .DefineTcpProbe(tenantname + "_rcon")
                .WithPort(tenantDeployment.RconPort)
                .Attach()
                .DefineLoadBalancingRule($"{tenantname}_rcon")
                .WithProtocol(TransportProtocol.Tcp)
                .FromExistingPublicIPAddress(publicIpAddress)
                .FromFrontendPort(tenantDeployment.RconPort)
                .ToBackend(backendPool)
                .ToBackendPort(tenantDeployment.RconPort)
                .WithProbe(tenantname + "_rcon")
                .Attach()
                .ApplyAsync(cancellationToken);

                return(new TenantDeployment(CreationStatus.Created, tenantDeployment, publicIpAddress.Fqdn));
            }
            catch (Exception e)
            {
                ServiceEventSource.Current.ServiceMessage(this.Context, "error provisioning ip addresses.", e.Message);
                return(new TenantDeployment(CreationStatus.InProcess, tenantDeployment));
            }
        }