/// <summary>Perform the Chaos Operation</summary>
        /// <param name="actionType">Action type</param>
        /// <param name="virtualMachine">Virtual Machine</param>
        /// <param name="scheduledRules">Event activity entity</param>
        /// <returns></returns>
        private static void PerformChaosOnVirtualMachine(string action, IVirtualMachine virtualMachine, ScheduledRules scheduledRules, bool enableRollback)
        {
            ActionType actionType;

            if (!Enum.TryParse(action, out actionType))
            {
                return;
            }

            switch (actionType)
            {
            case ActionType.Start:
                virtualMachine.StartAsync();
                break;

            case ActionType.PowerOff:
            case ActionType.Stop:
                virtualMachine.PowerOffAsync();
                break;

            case ActionType.Restart:
                virtualMachine.RestartAsync();
                break;
            }

            if (enableRollback)
            {
                scheduledRules.RollbackExecutionStatus = Status.Executing.ToString();
            }
            else
            {
                scheduledRules.ExecutionStatus = Status.Executing.ToString();
            }
        }
        /// <inheritdoc/>
        public async Task <IVirtualMachineResource> CreateAsync(
            IResourceGroupResource resourceGroup, string name,
            INetworkResource netres, VirtualMachineImage image,
            string customData)
        {
            if (resourceGroup == null)
            {
                throw new ArgumentNullException(nameof(resourceGroup));
            }

            var client = await CreateClientAsync(resourceGroup);

            name = await client.VirtualMachines.SelectResourceNameAsync(resourceGroup.Name,
                                                                        "vm", name);

            var user = VirtualMachineResource.kDefaultUser;
            var pw   = "Vm$" + name.ToSha1Hash().Substring(0, 3);

            if (image == null)
            {
                image = KnownImages.Ubuntu_16_04_lts;
            }

            var      attempt = 0;
            INetwork network = null;

            if (netres != null)
            {
                network = await client.Networks.GetByResourceGroupAsync(
                    resourceGroup.Name, netres.Name);

                if (network == null)
                {
                    throw new ArgumentException(nameof(netres));
                }
            }

            var originalRegion = await resourceGroup.Subscription.GetRegionAsync();

            while (true)
            {
                var regionAndVmSize = await SelectRegionAndVmSizeAsync(
                    resourceGroup, client);

                if (regionAndVmSize == null)
                {
                    throw new ExternalDependencyException(
                              "No sizes available.");
                }
                var region = regionAndVmSize.Item1;
                var vmSize = regionAndVmSize.Item2;
                try {
                    var nicDefine = client.NetworkInterfaces
                                    .Define(name)
                                    .WithRegion(region)
                                    .WithExistingResourceGroup(resourceGroup.Name);
                    var nic = nicDefine
                              .WithNewPrimaryNetwork(client.Networks
                                                     .Define(name)
                                                     .WithRegion(region)
                                                     .WithExistingResourceGroup(resourceGroup.Name)
                                                     .WithAddressSpace("172.16.0.0/16"))
                              .WithPrimaryPrivateIPAddressDynamic();

                    var ipName = await client.PublicIPAddresses.SelectResourceNameAsync(
                        resourceGroup.Name, "ip");

                    var publicIP = client.PublicIPAddresses
                                   .Define(ipName)
                                   .WithRegion(region)
                                   .WithExistingResourceGroup(resourceGroup.Name);

                    if (network != null && originalRegion == region)
                    {
                        nic = nicDefine
                              .WithExistingPrimaryNetwork(network)
                              .WithSubnet(netres.Subnet)
                              .WithPrimaryPrivateIPAddressDynamic();
                    }

                    nic = nic.WithNewPrimaryPublicIPAddress(
                        client.PublicIPAddresses
                        .Define(name)
                        .WithRegion(region)
                        .WithExistingResourceGroup(resourceGroup.Name));

                    var withOs = client.VirtualMachines
                                 .Define(name)
                                 .WithRegion(region)
                                 .WithExistingResourceGroup(resourceGroup.Name)
                                 .WithNewPrimaryNetworkInterface(nic);

                    IWithFromImageCreateOptionsManaged machine;
                    if (image.IsLinux)
                    {
                        machine = withOs
                                  .WithLatestLinuxImage(image.Publisher,
                                                        image.Offer, image.Sku)
                                  .WithRootUsername(user)
                                  .WithRootPassword(pw);
                    }
                    else
                    {
                        machine = withOs
                                  .WithLatestWindowsImage(image.Publisher,
                                                          image.Offer, image.Sku)
                                  .WithAdminUsername(user)
                                  .WithAdminPassword(pw);
                    }

                    _logger.Info($"Trying to create vm {name} on {vmSize}...");

                    IVirtualMachine vm = null;
                    if (!string.IsNullOrEmpty(customData))
                    {
                        vm = await machine
                             .WithCustomData(customData)
                             .WithSize(vmSize)
                             .CreateAsync();

                        _logger.Info($"Starting vm {name} ...");
                        // Restart for changes to go into effect
                        await vm.RestartAsync();
                    }
                    else
                    {
                        vm = await machine.WithSize(vmSize).CreateAsync();
                    }
                    _logger.Info($"Created vm {name}.");
                    return(new VirtualMachineResource(this, resourceGroup, vm,
                                                      user, pw, _logger));
                }
                catch (Exception ex) {
                    _logger.Info(
                        $"#{attempt} failed creating VM {name} as {vmSize}...",
                        () => ex);
                    await TryDeleteResourcesAsync(resourceGroup, name);

                    if (++attempt == 3)
                    {
                        throw ex;
                    }
                }
            }
        }