private async Task <bool> DoWork(Domain.Models.Run run)
        {
            var projectId   = run.Workspace.Directory.ProjectId;
            var dynamicHost = run.Workspace.DynamicHost;

            Host host = null;

            _plan = await CreatePlan(run);

            var workspace = run.Workspace;
            var files     = await _db.GetWorkspaceFiles(workspace, workspace.Directory);

            var workingDir = workspace.GetPath(_options.RootWorkingDirectory);

            if (dynamicHost)
            {
                // check if host already selected for this workspace
                if (workspace.HostId.HasValue)
                {
                    host = workspace.Host;
                }
                else
                {
                    // select a host. multiply by 1.0 to cast as double
                    host = await _db.Hosts
                           .Where(h => h.ProjectId == projectId && h.Enabled && !h.Development)
                           .OrderBy(h => (h.Machines.Count * 1.0 / h.MaximumMachines * 1.0) * 100.0).FirstOrDefaultAsync();
                }

                if (host == null)
                {
                    _output.AddLine("No Host could be found to use for this Plan");
                    return(true);
                }
                else
                {
                    _output.AddLine($"Attempting to use Host {host.Name} for this Plan");
                }

                files.Add(host.GetHostFile());
            }

            await workspace.PrepareFileSystem(workingDir, files);

            _timer          = new System.Timers.Timer(_options.OutputSaveInterval);
            _timer.Elapsed += OnTimedEvent;
            _timer.Start();

            bool isError = false;

            // Init
            var initResult = _terraformService.InitializeWorkspace(workspace, OutputHandler);

            isError = initResult.IsError;

            if (!isError)
            {
                // Plan
                var planResult = _terraformService.Plan(workspace, run.IsDestroy, run.Targets, OutputHandler);
                isError = planResult.IsError;
            }

            lock (_plan)
            {
                _timerComplete = true;
                _timer.Stop();
            }

            if (dynamicHost)
            {
                var result = _terraformService.Show(workspace);
                isError = result.IsError;

                if (!isError)
                {
                    var planOutput    = JsonSerializer.Deserialize <PlanOutput>(result.Output, DefaultJsonSettings.Settings);
                    var addedMachines = planOutput.GetAddedMachines();

                    var hostLock = _lockService.GetHostLock(host.Id);

                    lock (hostLock)
                    {
                        var existingMachines = _db.HostMachines.Where(x => x.HostId == host.Id).ToList();
                        var addedCount       = addedMachines.Count();

                        if (addedCount + existingMachines.Count < host.MaximumMachines)
                        {
                            List <HostMachine> newMachines = new List <HostMachine>();

                            foreach (var addedMachine in addedMachines)
                            {
                                var name = addedMachine.Address;

                                if (existingMachines.Any(m => m.WorkspaceId == workspace.Id && m.Name == name))
                                {
                                    continue;
                                }

                                newMachines.Add(new HostMachine
                                {
                                    HostId      = host.Id,
                                    WorkspaceId = workspace.Id,
                                    Name        = name
                                });
                            }

                            _db.HostMachines.AddRange(newMachines);
                            workspace.HostId = host.Id;
                            _db.SaveChanges();

                            _output.AddLine($"Allocated {addedCount} new machines to Host {host.Name}");
                        }
                        else
                        {
                            _output.AddLine($"{addedCount} new machines exceeds the maximum assigned to Host {host.Name}");
                            isError = true;
                        }
                    }
                }
            }

            return(isError);
        }