Skip to main content
Warning This document has not been updated for a while now. It may be out of date.
Last updated: 15 Mar 2024

govuk-knowledge-graph-gcp: Terraform

There are three separate Google Cloud projects, each with its own terraform configuration. Each environment is meant to be exactly the same, except when planned changes are deployed to dev or staging for testing. The only permanent differences are roles/permissions, the GovSearch URL, and the GovSearch login mechanism.

GCP Project Terraform GovSearch GOV.UK Signon
govuk-knowledge-graph terraform https://govgraphsearch.dev redirects to https://gov-search.service.gov.uk Production
govuk-knowledge-graph-staging terraform-staging https://govgraphsearchstaging.dev Access is controlled by Google IAM rather than GOV.UK Signon.
govuk-knowledge-graph-dev terraform-dev https://govgraphsearchdev.dev Integration

Deploying

There is no continuous deployment. A person must run terraform apply.

The GCP API isn't perfect, and nor is terraform, and the most noticeable nuisance is certain "permadiffs" when doing terraform plan. There are certain bits of infrastructure that it always thinks need to be changed. Let it try. If nothing breaks in dev or staging, be reassured about production.

Pull requests

Pull requests that change files in any of the terraform directories will trigger GitHub actions.

  • Diff will fail if diff-terraform.sh detects any differences between the configuration in each terraform directory. Files and subdirectories listed in diff-exclude are ignored, which is how GovSearch can be deployed differently in each environment.
  • Validate will fail if terraform validate fails or if terraform fmt would change any files.

Pull requests should not be merged until those checks pass. That is no guarantee, however, that what is actually deployed is the same as what has been merged.

The production environment should be exactly the same as what has been merged to the main branch. If terraform apply fails from the terraform directory on the main branch, then the production environment is out of sync with the main branch. Please fix it.

If terraform apply fails from the terraform-dev directory on a branch other than main, that is a normal part of doing new work, but the pull request isn't ready to merge until terraform apply succeeds.

If two people are working on different things at the same time, then one person should use the dev environment, and the other should use the staging environment, to avoid interference. The staging environment is particularly useful for user testing, because users can be given temporary access to the GovSearch app via IAM permissions in this project, without having to use GOV.UK Signon accounts. See the environment.auto.tfvars file.

How to allow differences between environments

Differences are configured in each environment's environment.auto.tfvars file. This is self-explanatory for things such as lists of users who have certain roles and permissions.

To control whether a certain piece of infrastructure exists at all, look at how Redis is configured. A variable, enable_redis_session_store_instance is defined in the configuration's environment.auto.tfvars file, which is allowed to differ between configurations by being listed in diff-exclude. The terraform block that declares the Redis instance refers to that variable when deciding how many instances to create. If the variable is true, then it is interpreted as 1 instance, otherwise it is interpreted as 0 instances.

# Enable / Disable instance
count = var.enable_redis_session_store_instance ? 1 : 0

What infrastructure is in what file

Most infrastructure is in a file named after the relevant GCP service. For example, most buckets are configured in storage.tf.

Some infrastructure is in a file named after its purpose. For example, most of the infrastructure of the GovSearch app is in the govgraphsearch.tf file.

It isn't possible to perfectly organise everything either by GCP service or by purpose. It is useful to be able to do quick searches on the whole repository to find things that are referred to by other things.

When creating something that is similar to something that already exists, look for a pull request that implemented the original thing, to see what was involved.