Editor - Publishing
The MOJ Forms publish mechanism is built into the Editor application and is made up of a few components:
- PublishServiceJob
- PublishService
- Publisher
- ServiceProvisioner
- Adapters
Publish Service Job
This is the job that is created when the publishing mechanism is initiated. The job is placed in a queue to be processed.
The PublishServiceJob uses the all the components mentioned above.
If a PublishServiceJob has been unsuccessful, it will result in a Delayed Job in the Editor queue. More information on Editor Delayed Jobs
Publish Service
This is a model and is used to find the record in the database.
Service Provisioner
This uses a rich object to handle all the neccessary configurations for creating a new kubernetes deployment. The Service Provisioner is used by the Adapters to create the templates with the correct config.
The templates can be found in config/publisher/cloud_platform
.
Publisher
This orchestrates the publishing mechanism by steps. The publisher will update the publish service status in the database while calling the adapter to handle the publish logic.
Adapters
The default adapter is for CloudPlatform which needs to respond to the following methods:
- pre_publishing
- publishing
- post_publishing
- completed
These steps can be found in the app/services/publisher/adapters/cloud_platform.rb
class.
Pre-Publishing
In this stage, the adapter prepares the Service Metadata files and the Kubernetes Configuration files to be uploaded into the pods. These files are created using the ServiceProvisioner.
The Service Metadata files, which include the autocomplete items and the service metadata, are created and uploaded to S3.
Before the Kubernetes configuration files are created, the adapter creates a config directory in which these files will live. The config directory is derived from the service id and service slug.
Accessing the Kubernetes Configuration files
To access the Kubernetes config files we need to log onto an Editor worker pod. We can then find the files in:
/tmp/publisher/<service_id>-<service_slug>
Please note, these config directories are only created once in one worker. If the config directory is not present in one worker, it will most likely be present in another worker.
Publishing
Once the config directory and config files are available on the worker, this step will apply the config.
Post-publishing
Once all the files have been successfully applied, we restart the deployment for the particular service. This ensures all runner pods are running the most up to date version of the service.
Completed
If the service has been published to live for the first time, the team will receive a notification in the #form-builder-alerts Slack channel.
Publisher Worker Kubernetes Configuration
Publisher worker pods have a service account attached to them that needs to be able to apply charts in multiple other namespaces, and also assume the correct IAM role that will allow access to S3 buckets for writing the metadata, and also assume a different IAM role to acces ECR to upload the deployed runner image.
In the cloud-platform-environments terraform we use the following setup -
- Generate a secret containing the bucket references from the services namespaces in the saas namespace
- Create the S3 bucket in the services namespace and attach the arn (bucket reference) to the secret in the saas namespace
- Generate the editor-worker service account, which also has access to ECR to push images, note the attached IAM role and its annotations
- Generate a secret in the saas-* namespace containing the token from the service account (a token is not auto generated) so the token can be used at run time (configured by our pipeline secrets management)
- Attach the service account to the editor worker pod (in the editor repo in the deployment.yaml)
- Apply a role binding giving permission to the editor worker service account in the services-* namespace to modify necessary kubernetes resources to deploy forms