Splitting or adding a frontend application¶
Warning
Introducing a new application will increase the amount of maintenance for the dev team. Make sure the team has discussed and agreed whether a new app is really necessary before following the steps below.
Prerequisites¶
Each new frontend application needs to meet some common requirements:
All routes have a shared prefix that is not used by any other frontend app (eg
/suppliers
or/opportunities
). The best way to ensure this is to use a Blueprint with aurl_prefix='/...'
argument.Make sure links to application static files start with
/<prefix>/static
. This is usually done by setting Flask static URL path withFlask(..., static_url_path=configs[config_name].STATIC_URL_PATH)
inapp/__init__.py
and addingSTATIC_URL_PATH = '/<prefix>/static'
andASSET_PATH = STATIC_URL_PATH + '/'
toconfig.py
.Application has a status endpoint at
/<prefix>/_status
Application uses a unique port when running locally with a dev server (eg 5000, 5001, … used by existing apps)
Setting up infrastructure¶
Setting up a repo¶
Follow the steps in Adding a new repository to create a GitHub repository for the
new app. The repo name should follow the digitalmarketplace-<application-name>
pattern.
Setting up a release pipeline¶
Add application name to the list in the Jenkins
dm_application
variable.Add application jobs to the relevant Jenkins job views (eg add
release-<application name>
to the Release jobs list).Apply changes to the Jenkins jobs and config.
Setting up PaaS and AWS environment¶
Add the application name to the end of the list in Terraform
app_names
variable (inmodules/application-logs
).Apply Terraform changes to all environments to create CloudWatch log groups and set up log streaming for the new app.
Define application variables in the
digitalmarketplace-aws/vars/common.yml
file. For most apps the only things you’ll need are thesubdomain
andpath
(the common route prefix) for the new app.Create a manifest file in
digitalmarketplace-aws/paas
with the name of the app.
Setting up a local environment¶
Add the app to digitalmarketplace-runner so that devs can run the app locally.
First deployment¶
At this point you should be able to run the new Jenkins release job ([Pipeline] <application name>
) to deploy the app to the preview environment. You can do
this by either running the job manually or merging a PR.
If the application is being split from an existing app then any new requests for the prefixed routes will be handled by the new app.
Once the app is deployed you should check that:
App is responding to health checks and status endpoint requests as expected
Functional tests are passing
Logs are being streamed to CloudWatch and Kibana
App functionality that requires specific environment variables to be set is working as expected
Once you’ve confirmed that the app is working as intended you can deploy it to staging and production and remove the routes from the old application.
Once the app is deployed to production for the first time you can add it to the list of apps in the team’s Deploy Lag Radiator.
You should add a Pingdom healthcheck to the app.
Subdomains¶
The new PaaS app should be automatically assigned a *.cloudapps.digital
domain which is mostly intended for internal
access but should also be accessible from external IP addresses. New apps that require a publicly accessible subdomain (e.g.
for receiving callbacks from external services) should have these requests handled and delegated through the router app
so that all regular inbound requests get similar treatment (access control, logging, tracing, sampling behaviour). A
few steps will need to be followed for setting up the new subdomain.
Add a new env var to the router app’s paas manifest template pointing to the new app’s
*.cloudapps.digital
domain.Add a new
server { ...
section to the router app’s nginx configuration. This can probably be cloned from the most similar existing app’s section and adapted to needs, but should restrict itself toserver_name new-app-name.*;
and make any access restrictions it wants to place on its exposed routes. The template should get fed a variable based on the env var previously set in the manifest. This should be used to tellproxy_pass
where to direct the new subdomain’s traffic.Add the subdomain’s DNS record by giving it a section in our terraform config for route53. Again, this will probably be extremely similar to its sibling entries in that file.
plan
andapply
the changes for each environment.Add the new subdomains to the router’s
routes:
“vars” so this is picked up when generating the router’s paas manifest.Add the new subdomain to the
CDN_ROUTE_SERVICE_CONF
setting in digitalmarketplace-router’s Makefile’s and runmake update-cdn-route-service
for each environment’s domains. There are a number of other more minor places the subdomains are enumerated in the router app, at time of writing themake test-nginx
docker command, the README, docker-compose.yml.example. These should be updated too.
Smoke tests¶
Add a check of the app’s /_status
endpoint to the
smoke tests. Unless the app is a frontend, this will require propagating the new app’s domain through
the functional tests’ env and jenkins’
ansible vars.