The front-end is written in Drupal 8. It consists of some base entities and traits, along with basic admin interfaces for creating and managing fields and bundles.

Entity types

We should implement base entities that represent useful abstractions from an operational stand-point. These should come with default admin interfaces, but we can then separately build out a user-friendly UI that further abstracts low-level components.

Our current abstractions include:

  • Servers and services
  • Distributions and platforms
  • Sites

We may want to restructure our abstractions, such as:

  • Resources
  • Applications
  • Deployments (Application instances)

We may want to stick with our current abstractions for the first round of re-architecture, since we know that the model works. We could then focus on getting the queue/engine implementation sorted out.

That is, we can keep a known workflow and terminology, while still reaping the benefits of decoupling components, removing our dependence on Drush as a framework, etc. This latter one is our most pressing priority.

User experience

By default, entities should provide only admin UI components. But, being built on fieldable entities, these should then all be accessible to Views, Panels, etc. to allow for better end-user experience. We should provide a “default” UI, but ensure that this can be easily customized, or replaced entirely.

Front-end class hierarchies (examples)

Scenario 1

N.B. Scenario 2 (below) is probably better.

  • Distribution (Application?)
  • Platform (Codebase?)
  • Site (ApplicationInstance?)
    • CmsSite
      • DrupalSite
        • Drupal7Site
          • CiviCrmDrupal7Site-
        • Drupal8Site
      • WorpPressSite
        • WordPress4Site
          • CiviCrmWordPress4Site
  • Task
    • AnsibleTask
      • AnsiblePlatformTask
      • AnsibleSiteTask
        • AnsibleDrupalSiteTask
          • AnsibleInstallDrupalSiteTask
          • AnsibleDisableDrupalSiteTask
          • AnsibleBackupDrupalSiteTask

Scenario 2

Compose Sites, Platforms, (etc.) from Tasks (e.g., WriteNginxVhostTask, ProvisionMySqlDatabaseTask,…). Operations combine Tasks into user-facing actions (e.g., InstallCmsSiteOperation). Tasks are re-usable within other Operations.

  • Distribution (entity type?)
  • Platform (Distribution bundle?)
  • Site
    • CmsSite (fieldable entity, that embedding of task entities)
      • Drupal7Site
      • CiviCrmDrupal7Site
      • Drupal8Site
      • WorpPress4Site
      • CiviCrmWordPress4Site
  • Task (defines log and result fields, provides a URL to which to post log output)
    • AnsibleTask (parses log output for return code, to update result field).
      • AnsiblePlatformTask
        • AnsibleDeployDrupalPlatformFromGitTask
        • AnsibleDeployDrupalPlatformFromDrushMakefileTask
      • AnsibleSiteTask
        • AnsibleWriteNginxVhostTask
        • AnsibleGenerateDrupalSiteBackupTask (implements AcceptsFeedbackTrait, contains a backup_path field)
        • AnsibleRestoreDrupalSiteBackupTask (provides select widget populated by a View of this site’s backup tasks' backup_path fields. This, in turn, is passed to the task queue, and onto the Ansible role to execute the restore).
        • AnsibleDisableDrupalSiteTask
        • AnsibleInstallDrupalSiteTask


  • AcceptsFeedbackTrait
    • hook_menu(): (or equivalent listener) to register the feedback URL.
    • handleFeedback(): write feedback to appropriate field.