Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDPS-1086: Setting up first deploy #2

Merged
merged 1 commit into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .sdkmanrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Enable auto-env through the sdkman_auto_env config
# Add key=value pairs of SDKs to use below
java=21.0.5-tem
141 changes: 9 additions & 132 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,136 +1,13 @@
# hmpps-health-and-medication-api

# HMPPS Health and Medication API
[![repo standards badge](https://img.shields.io/badge/endpoint.svg?&style=flat&logo=github&url=https%3A%2F%2Foperations-engineering-reports.cloud-platform.service.justice.gov.uk%2Fapi%2Fv1%2Fcompliant_public_repositories%2Fhmpps-health-and-medication-api)](https://operations-engineering-reports.cloud-platform.service.justice.gov.uk/public-report/hmpps-health-and-medication-api "Link to report")
[![Docker Repository on ghcr](https://img.shields.io/badge/ghcr.io-repository-2496ED.svg?logo=docker)](https://ghcr.io/ministryofjustice/hmpps-health-and-medication-api)
[![API docs](https://img.shields.io/badge/API_docs_-view-85EA2D.svg?logo=swagger)](https://hmpps-health-and-medication-api-dev.hmpps.service.justice.gov.uk/webjars/swagger-ui/index.html?configUrl=/v3/api-docs)

Template github repo used for new Kotlin based projects.

# Instructions

If this is a HMPPS project then the project will be created as part of bootstrapping -
see [dps-project-bootstrap](https://github.com/ministryofjustice/dps-project-bootstrap). You are able to specify a
template application using the `github_template_repo` attribute to clone without the need to manually do this yourself
within GitHub.

This project is community managed by the mojdt `#kotlin-dev` slack channel.
Please raise any questions or queries there. Contributions welcome!

Our security policy is located [here](https://github.com/ministryofjustice/hmpps-health-and-medication-api/security/policy).

Documentation to create new service is located [here](https://tech-docs.hmpps.service.justice.gov.uk/applicationplatform/newservice-GHA/).

## Creating a Cloud Platform namespace

When deploying to a new namespace, you may wish to use the
[templates project namespace](https://github.com/ministryofjustice/cloud-platform-environments/tree/main/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-templates-dev)
as the basis for your new namespace. This namespace contains both the kotlin and typescript template projects,
which is the usual way that projects are setup.

Copy this folder and update all the existing namespace references to correspond to the environment to which you're deploying.

If you only need the kotlin configuration then remove all typescript references and remove the elasticache configuration.

To ensure the correct github teams can approve releases, you will need to make changes to the configuration in `resources/service-account-github` where the appropriate team names will need to be added (based on [lines 98-100](https://github.com/ministryofjustice/cloud-platform-environments/blob/main/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-templates-dev/resources/serviceaccount-github.tf#L98) and the reference appended to the teams list below [line 112](https://github.com/ministryofjustice/cloud-platform-environments/blob/main/namespaces/live.cloud-platform.service.justice.gov.uk/hmpps-templates-dev/resources/serviceaccount-github.tf#L112)). Note: hmpps-sre is in this list to assist with deployment issues.

Submit a PR to the Cloud Platform team in
#ask-cloud-platform. Further instructions from the Cloud Platform team can be found in
the [Cloud Platform User Guide](https://user-guide.cloud-platform.service.justice.gov.uk/#cloud-platform-user-guide)

## Renaming from HMPPS Health And Medication Api - github Actions

Once the new repository is deployed. Navigate to the repository in github, and select the `Actions` tab.
Click the link to `Enable Actions on this repository`.

Find the Action workflow named: `rename-project-create-pr` and click `Run workflow`. This workflow will
execute the `rename-project.bash` and create Pull Request for you to review. Review the PR and merge.

Note: ideally this workflow would run automatically however due to a recent change github Actions are not
enabled by default on newly created repos. There is no way to enable Actions other then to click the button in the UI.
If this situation changes we will update this project so that the workflow is triggered during the bootstrap project.
Further reading: <https://github.community/t/workflow-isnt-enabled-in-repos-generated-from-template/136421>

The script takes six arguments:

### New project name

This should start with `hmpps-` e.g. `hmpps-prison-visits` so that it can be easily distinguished in github from
other departments projects. Try to avoid using abbreviations so that others can understand easily what your project is.

### Slack channel for release notifications

By default, release notifications are only enabled for production. The circleci configuration can be amended to send
release notifications for deployments to other environments if required. Note that if the configuration is amended,
the slack channel should then be amended to your own team's channel as `dps-releases` is strictly for production release
notifications. If the slack channel is set to something other than `dps-releases`, production release notifications
will still automatically go to `dps-releases` as well. This is configured by `releases-slack-channel` in
`.circleci/config.yml`.

### Slack channel for pipeline security notifications

Ths channel should be specific to your team and is for daily / weekly security scanning job results. It is your team's
responsibility to keep up-to-date with security issues and update your application so that these jobs pass. You will
only be notified if the jobs fail. The scan results can always be found in circleci for your project. This is
configured by `alerts-slack-channel` in `.circleci/config.yml`.

### Non production kubernetes alerts

By default Prometheus alerts are created in the application namespaces to monitor your application e.g. if your
application is crash looping, there are a significant number of errors from the ingress. Since Prometheus runs in
cloud platform AlertManager needs to be setup first with your channel. Please see
[Create your own custom alerts](https://user-guide.cloud-platform.service.justice.gov.uk/documentation/monitoring-an-app/how-to-create-alarms.html)
in the Cloud Platform user guide. Once that is setup then the `custom severity label` can be used for
`alertSeverity` in the `helm_deploy/values-*.yaml` configuration.

Normally it is worth setting up two separate labels and therefore two separate slack channels - one for your production
alerts and one for your non-production alerts. Using the same channel can mean that production alerts are sometimes
lost within non-production issues.

### Production kubernetes alerts

This is the severity label for production, determined by the `custom severity label`. See the above
#non-production-kubernetes-alerts for more information. This is configured in `helm_deploy/values-prod.yaml`.

### Product ID

This is so that we can link a component to a product and thus provide team and product information in the Developer
Portal. Refer to the developer portal at https://developer-portal.hmpps.service.justice.gov.uk/products to find your
product id. This is configured in `helm_deploy/<project_name>/values.yaml`.

## Manually branding from template app

Run the `rename-project.bash` without any arguments. This will prompt for the six required parameters and create a PR.
The script requires a recent version of `bash` to be installed, as well as GNU `sed` in the path.

## TODOs and Examples

We have tried to provide some examples of best practice in the application - so there are lots of TODOs in the code
where changes are required to meet your requirements. There is an `ExampleResource` that includes best practice and also
serve as spring security examples. The template typescript project has a demonstration that calls this endpoint as well.

For the demonstration, rather than introducing a dependency on a different service, this application calls out to
itself. This is only to show a service calling out to another service and is certainly not recommended!

## Running the application locally

The application comes with a `dev` spring profile that includes default settings for running locally. This is not
necessary when deploying to kubernetes as these values are included in the helm configuration templates -
e.g. `values-dev.yaml`.

There is also a `docker-compose.yml` that can be used to run a local instance of the template in docker and also an
instance of HMPPS Auth (required if your service calls out to other services using a token).

```bash
docker compose pull && docker compose up
```

will build the application and run it and HMPPS Auth within a local docker instance.
[![CircleCI](https://circleci.com/gh/ministryofjustice/hmpps-health-and-medication-api/tree/main.svg?style=svg)](https://circleci.com/gh/ministryofjustice/hmpps-health-and-medication-api)
[![codecov](https://codecov.io/github/ministryofjustice/hmpps-health-and-medication-api/branch/main/graph/badge.svg)](https://codecov.io/github/ministryofjustice/hmpps-health-and-medication-api)
[![Docker Repository on Quay](https://img.shields.io/badge/quay.io-repository-2496ED.svg?logo=docker)](https://quay.io/repository/hmpps/hmpps-health-and-medication-api)
[![API docs](https://img.shields.io/badge/API_docs_-view-85EA2D.svg?logo=swagger)](https://health-and-medication-api-dev.prison.service.justice.gov.uk/swagger-ui/index.html)

### Running the application in Intellij
This is a Spring Boot service, written in Kotlin, which owns a subset of data about a person in prison (migrated from NOMIS).

```bash
docker compose pull && docker compose up --scale hmpps-health-and-medication-api=0
```
## Contents

will just start a docker instance of HMPPS Auth. The application should then be started with a `dev` active profile
in Intellij.
1. [Building, Testing and Running](readme/build_test_run.md)
2. [Architecture Decision Records](architecture-decision-record/README.md)
87 changes: 87 additions & 0 deletions architecture-decision-record/0000-record-architecture-decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
[Contents](README.md)

# 0. Record architecture decisions

Date: 2025-01-10

## Status

✅ Accepted

## Context

When making architectural decisions, we should record them somewhere for future reference, to help us remember why we made them, and
to help teams working in related areas understand why we made them.

We should make our decisions public so that other teams can find them more easily, and
because [making things open makes things better](https://www.gov.uk/guidance/government-design-principles#make-things-open-it-makes-things-better)
.

## Decision

We will use Architecture Decision Records, as described by Michael Nygard in
[this article](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)

An architecture decision record is a short text file describing a single decision.

We will keep ADRs in this public repository under decisions/[number]-[title].md

We should use a lightweight text formatting language like Markdown.

ADRs will be numbered sequentially and monotonically. Numbers will not be reused.

If a decision is reversed, we will keep the old one around, but mark it as superseded. (It's still relevant to know that
it was the decision, but is no longer the decision.)

We will use a format with just a few parts, so each document is easy to digest:

**Title** These documents have names that are short noun phrases. For example,
"ADR 1: Record architectural decisions" or "ADR 9: Use Docker for deployment"

**Status** A decision may be "proposed" if it's still under discussion, or
"accepted" once it is agreed. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "
superseded" with a reference to its replacement.

**Context** This section describes the forces at play, including technological, political, social, and local to the
service. These forces are probably in tension, and should be called out as such. The language in this section is
value-neutral. It is simply describing facts.

**Decision** This section describes our response to these forces. It is stated in full sentences, with active voice. "We
will ..."

**Consequences** This section describes the resulting context, after applying the decision. All consequences should be
listed here, not just the "positive"
ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and
service in the future.

The whole document should be one or two pages long. We will write each ADR as if it is a conversation with a future
person joining the team. This requires good writing style, with full sentences organised into paragraphs. Bullets are
acceptable only for visual style, not as an excuse for writing sentence fragments.

[adr-tools](https://github.com/npryce/adr-tools) can help us work with our ADRs consistently.

We will link to these ADRs from other documentation where relevant.

## Consequences

One ADR describes one significant decision for the service. It should be something that has an effect on how the rest of
the service will run.

Developers and service stakeholders (and anyone else who's interested) can see the ADRs, even as the team composition
changes over time.

The motivation behind previous decisions is visible for everyone, present and future. Nobody is left scratching their
heads to understand, "What were they thinking?" and the time to change old decisions will be clear from changes in the
service's context.

Having a central place to record decisions which affect all of our work will make the sequence of decisions clear, and
make it easier for us to refer back to decisions later on.

This repo holds Architecture Decision Records, for the PCMS team. We will be using the architecture decision record to
help keep a record of what approaches we are currently taking to our infrastructure and to help our future selves
understand why those decisions were made. The approach is described by Michael Nygard
in [this article](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).

Everyone can see the ADRs, even as the team composition changes over time. This means motivation behind previous
decisions is visible for everyone, present and future. Nobody is left scratching their heads to understand, "What were
they thinking?" and the time to change old decisions will be clear from changes in the project's context.
26 changes: 26 additions & 0 deletions architecture-decision-record/0001-prefer-prisoner-over-offender.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[Contents](README.md)
[Next >](9999-end.md)

# 1. Prefer 'Prisoner' Over 'Offender'

Date: 2025-01-10

## Status

✅ Accepted

## Context

The terms 'offender' and 'prisoner' are often used interchangeably but this causes issues when trying to remember if in
a particular bit of code we have decided to use one term or another.

## Decision

We will prefer to use the term 'prisoner' wherever possible - this service is inherently prisoner focussed.

## Consequences

This should bring much more consistency to the codebase and make it easier to develop. There will no longer be an issue
deciding what to name a file, class, method etc.


Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[Contents](README.md)
[Next >](9999-end.md)

# 2. Database table names should be singular

Date: 2025-01-10

## Status

✅ Accepted

## Context

Table names can be either singular (i.e. identifying_mark) or plural (i.e. identifying_marks). There are mixed opinions
about which it should be.

## Decision

We are opting to use singular table names. This is mostly a decision made for consistency, but there are a couple of
other benefits:
* The JPA entities don't need an `@Table` annotation to specify the plural table name
* It keeps all the JPA naming consistent, and we don't need to worry about the oddities of the English language
such as irregular plurals.

## Consequences

We need to correct some existing tables to conform with this approach.


3 changes: 3 additions & 0 deletions architecture-decision-record/9999-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
No more records

[Back to Contents](README.md)
19 changes: 19 additions & 0 deletions architecture-decision-record/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Health and Medication Architecture Decisions

This is a record of architectural decisions made during the development of the Health and Medication API project.

To understand why we are recording decisions and how we are doing it, please
see [Record Architecture Decisions](architecture-decision-record/0000-record-architecture-decisions.md)

## Table of contents

* ✅ [1. Prefer 'Prisoner' over 'Offender'](0001-prefer-prisoner-over-offender.md)
* ✅ [2. Database table names should be singular](0002-table-names-should-be-singular.md)

### Statuses:

* Proposed: 🤔
* Accepted: ✅
* Rejected: ❌
* Superseded: ⌛️
* Amended: ♻️
12 changes: 7 additions & 5 deletions helm_deploy/hmpps-health-and-medication-api/values.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
generic-service:
nameOverride: hmpps-health-and-medication-api
productId: "DPS013" # productId for the product that this belongs too, i.e. DPS001, see README.md for details
productId: "DPS013"

replicaCount: 4

Expand All @@ -26,13 +26,15 @@ generic-service:
# [name of environment variable as seen by app]: [key of kubernetes secret to load]

namespace_secrets:
hmpps-health-and-medication-api:
# Example client registration secrets
EXAMPLE_API_CLIENT_ID: "TEMPLATE_KOTLIN_API_CLIENT_ID"
EXAMPLE_API_CLIENT_SECRET: "TEMPLATE_KOTLIN_API_CLIENT_SECRET"
application-insights:
APPLICATIONINSIGHTS_CONNECTION_STRING: "APPLICATIONINSIGHTS_CONNECTION_STRING"

rds-postgresql-instance-output:
DATABASE_ENDPOINT: "rds_instance_endpoint"
DATABASE_NAME: "database_name"
DATABASE_USERNAME: "database_username"
DATABASE_PASSWORD: "database_password"

allowlist:
groups:
- internal
Expand Down
11 changes: 8 additions & 3 deletions helm_deploy/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ generic-service:
env:
APPLICATIONINSIGHTS_CONFIGURATION_FILE: "applicationinsights.dev.json"
HMPPS_AUTH_URL: "https://sign-in-dev.hmpps.service.justice.gov.uk/auth"
# Template kotlin calls out to itself to provide an example of a service call
# TODO: This should be replaced by a call to a different service, or removed
EXAMPLE_API_URL: "https://health-and-medication-api-dev.hmpps.service.justice.gov.uk"

scheduledDowntime:
enabled: true
startup: '30 6 * * 1-5' # Start at 6.30am UTC Monday-Friday
shutdown: '30 21 * * 1-5' # Stop at 9.30pm UTC Monday-Friday

# CloudPlatform AlertManager receiver to route prometheus alerts to slack
# See https://user-guide.cloud-platform.service.justice.gov.uk/documentation/monitoring-an-app/how-to-create-alarms.html#creating-your-own-custom-alerts
generic-prometheus-alerts:
alertSeverity: hmpps-prisoner-profile-non-prod
businessHoursOnly: true
rdsAlertsDatabases:
cloud-platform-74e3c6cbeecd38ba: "HMPPS Health and Medication DB (dev)"
5 changes: 1 addition & 4 deletions helm_deploy/values-preprod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ generic-service:
env:
APPLICATIONINSIGHTS_CONFIGURATION_FILE: "applicationinsights.dev.json"
HMPPS_AUTH_URL: "https://sign-in-preprod.hmpps.service.justice.gov.uk/auth"
# Template kotlin calls out to itself to provide an example of a service call
# TODO: This should be replaced by a call to a different service, or removed
EXAMPLE_API_URL: "https://health-and-medication-api-preprod.hmpps.service.justice.gov.uk"

# CloudPlatform AlertManager receiver to route prometheus alerts to slack
# See https://user-guide.cloud-platform.service.justice.gov.uk/documentation/monitoring-an-app/how-to-create-alarms.html#creating-your-own-custom-alerts
generic-prometheus-alerts:
alertSeverity: hmpps-prisoner-profile-non-prod
alertSeverity: hmpps-prisoner-profile-non-prod
3 changes: 0 additions & 3 deletions helm_deploy/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ generic-service:

env:
HMPPS_AUTH_URL: "https://sign-in.hmpps.service.justice.gov.uk/auth"
# Template kotlin calls out to itself to provide an example of a service call
# TODO: This should be replaced by a call to a different service, or removed
EXAMPLE_API_URL: "https://health-and-medication-api.hmpps.service.justice.gov.uk"

# CloudPlatform AlertManager receiver to route prometheus alerts to slack
# See https://user-guide.cloud-platform.service.justice.gov.uk/documentation/monitoring-an-app/how-to-create-alarms.html#creating-your-own-custom-alerts
Expand Down
Loading
Loading