This repository contains the Terraform configuration for the infrastructure of the Private Rented Sector Database (PRSDB) service. The main respository for the service, which includes Architecture Decision Records for this infrastructure can be found at https://github.com/communitiesuk/prsdb-webapp
Install the appropriate version of Terraform by following these instructions. We are currently using 1.9.x, so make sure you select that version. If using the "Manual installation" method, you can select the correct version from the dropdown at the top of the installation page.
Install the latest AWS vault by following these instructions. (N.B. there is no windows AMD64 version, so you need to use 386 in that case). You will need to rename the .exe file to "aws-vault.exe" and add it to your path.
Use the shell script "setup/create_profiles.sh" to add a .aws/config
file to your home directory, with your mfa_serial value added.
You can find this in the aws console under the top right drop down menu -> `Security credentials".
You should not override the destination file.
setup/create_profiles.sh "Your mfa_serial value" ["Override destination file"]
Create an access key in the AWS portal on the Security credentials page (just below where you found you mfa_serial
). In your terminal, run aws-vault add mhclg
and provide your access key details.
In your terminal, navigate to the integration directory and run aws-vault exec mhclg-int -- <your preferred shell>
.
This will start a sub-shell with the access key credentials available and the role of that profile. Use exit
to return to your previous shell when you are done.
If you want to work on a different environment, instead navigate to that environment's directory and use the corresponding profile instead of mhclg-int
.
Still in the environment directory, run terraform init
to create a local terraform state linking to the shared environment state.
You are now ready to start running terraform commands on the chosen environment.
- Create the new folder
terraform/<environment name>
and copy the contents ofterraform/environment_template
into it - In
terraform/<environment name>/backend
remove the.template
from the end of the file name and replace all instances of the string<environment name>
with your actual environment name. - Leave the block that starts with
backend "s3"
near the top of the file commented out cd
intoterraform/<environment name>/backend
and runterraform init
followed byterraform plan
. Among other things the plan should show the creation of an s3 bucket calledprsdb-tfstate-<environment name>
and a dynamoDB table namedtfstate-lock-<environment name>
. If everything looks correct with the plan output, runterraform apply
.- After the
apply
step completes successfully and you can see the s3 bucket and dynamoDB table in the aws console, uncomment thebackend "s3"
block and runterraform init
- You should be prompted to move the terraform state to the remote backend. Once this is done the terraform state is successfully bootstrapped for the new environment
- In your new
terraform/<environment name>
folder, you can now also remove the.template
from the end of all of the filenames, replace all instances of the string<environment name>
with your actual environment name, and more generally look throughmain.tf
for any sets of<>
that require environment-specific input, e.g. the domains of any 3rd party integrations.
- Before we can create the environment as a whole, we must first create the initial networking infrastructure, and then request the DNS names and certificates from MHCLG.
- One of the files in your new
terraform/<environment name>
folder will beterraform.tfvars
. Check that this contains the linessl_certs_created = false
- Once this is done,
cd
intoterraform/<environment name>
and runterraform init
followed byterraform plan -target module.networking -target module.frontdoor
. If the output of the plan looks correct, runterraform apply -target module.networking -target module.frontdoor
to bring up the networking and ECR repository for the new environment. - Use the values in the terraform output to complete the request to MHCLG for changes to their DNS records
-
Use the terraform output to complete a copy of the 'DNS Change Request Form -v2.xlsx' file in the root of the repository as follows:
- For each item in the
cloudfront_certificate_validation
andload_balancer_certificate_validation
blocks of the output:- add a row to the table where:
- 'Change' Type is 'Add'
- 'Requested by' is your name
- 'Record Type' is the value from
resource_record_type
- 'Domain' is either
test.communities.gov.uk
orservice.gov.uk
, whichever appears as part of the value indomain_name
- 'Name' is the value from
resource_record_name
- 'Content' is the value from
resource_record_value
- 'TTL' is '1 hr'
- 'Proxy status' is 'DNS only'
- 'Additional comment or Reason for this change' is 'Setting up environment for the PRS Database'
- add a row to the table where:
- For each item in the
cloudfront_certificate_validation
block of the output add an additional row to the table where:- 'Change' Type is 'Add'
- 'Requested by' is your name
- 'Record Type' is 'CNAME'
- 'Domain' is either
test.communities.gov.uk
orservice.gov.uk
, whichever appears as part of the value indomain_name
- 'Name' is the value from
domain name
- 'Content' is the value from
cloudfront_dns_name
- 'TTL' is '1 hr'
- 'Proxy status' is 'DNS only'
- 'Additional comment or Reason for this change' is 'Setting up environment for the PRS Database'
- For each item in the
load_balancer_certificate_validation
block of the output add an additional row to the table where:- 'Change' Type is 'Add'
- 'Requested by' is your name
- 'Record Type' is 'CNAME'
- 'Domain' is either
test.communities.gov.uk
orservice.gov.uk
, whichever appears as part of the value indomain_name
- 'Name' is the value from
domain name
- 'Content' is the value from
load_balancer_dns_name
- 'TTL' is '1 hr'
- 'Proxy status' is 'DNS only'
- 'Additional comment or Reason for this change' is 'Setting up environment for the PRS Database'
- For each item in the
-
Once the spreadsheet is completed, create a service now request with MHCLG using the general 'Request' option with the following details:
- 'What is it that you require?' --> "Creation of DNS records"
- 'Why do you require it?' --> "We are setting up the environment for the new PRS Database in AWS. As part of this we need DNS records for the sub-domains and associated certificates. These subdomains were approved by TDA on 21/08/24. The service owner for the project is ."
- And add the completed spreadsheet as an attachment to the request
- We also need to create a number of pre-requisite resources, and then initial task definition before we can bring up the full ECS service.
- Make sure that the
terraform.tfvars
file that was created in the previous step contains the linetask_definition_created = false
- Still inside your
terraform/<environment name>
folder, runterraform plan
. - If the output of the plan looks correct, run
terraform apply
to create the pre-requisite resources. - Terraform will create the webapp secrets and SSM parameters but (apart from those related to the database and Redis) will not populate them. Ask the team lead where you can find the appropriate values, and then populate them via the AWS console.
- To create the task definition, in
terraform/<environment name>/ecs_task_definition
, if you haven't already, remove the.template
from the end of any file names in the folder, and replace all instances of the string<environment name>
with your actual environment name. - Next, cd into
terraform/<environment name>/ecs_task_definition
and runterraform init
followed byterraform plan
. This should show you one resource being created - the task definition. If the output looks correct, runterraform apply
.
- In
terraform.tfvars
setssl_certs_created
totrue
andtask_definition_created
totrue
. - Then run
terraform plan
. If the output looks correct, runterraform apply
to bring up the environment.
This repository uses tfsec to scan the Terraform code for potential security issues. It can be run using Docker
docker run --pull=always --rm -it -v "$(pwd):/src" aquasec/tfsec /src
Individual rules can be ignored with a comment on the line above with the form tfsec:ignore:<rule-name>
e.g. tfsec:ignore:aws-dynamodb-enable-at-rest-encryption
.