# Infrastructure Terraform Repository

This repository manages the permanent infrastructure behind the assessment model. Key components to this include

- Database
- Blob storage (s3 buckets)

# Terraform AWS Deployment

This project uses Terraform to create infrastructure in AWS. This README covers the steps necessary to deploy the resources.

## Prerequisites

- AWS CLI v2 installed and configured with profiles
- Terraform v1.2.0 or higher

## Deploying

The deployment process can be broken down into the following steps:

1. Initialization: This downloads the necessary provider plugins for Terraform.

```bash
terraform init
```

2. Workspace setup: Before you deploy, create a workspace for the environment. For example, if you're setting up the development environment:

```bash
terraform workspace new dev
```

3. Planning: This step creates an execution plan, showing what changes Terraform will make to reach the desired state.

```bash
terraform plan -var-file=dev.tfvars
```

Note: replace dev.tfvars with your appropriate variables file. For a production deployment, this would be the prod.tfvars file.

4. Apply: This step applies the desired changes to reach the desired infrastructure state.

```bash
terraform apply -var-file=dev.tfvars
```

Note: replace dev.tfvars with your appropriate variables file.

## AWS Profiles

This project uses AWS profiles for managing different environments. Ensure you have your profiles set up in your AWS credentials file `(~/.aws/credentials)`. Here is a sample:

```ini
[DevAdmin]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
```

In the given example, DevAdmin is the profile for the development environment. Replace YOUR_ACCESS_KEY and YOUR_SECRET_KEY with your actual AWS credentials.

## Switching Environments

If you need to switch environments (e.g., from development to production), use the following command:

```bash
terraform workspace select prod
```

Remember to update your variables file accordingly when planning and applying changes (`-var-file=prod.tfvars` for production, for example).

# Deployment with Github actions

Deployment has been automated with github actions. In order to trigger a new deployment, simply make a pull request to either the `dev` or `prod` branches, depending on the deployment you wish to trigger. Then, once that pull request is merge, it will trigger a workflow in Github actions which will perform the deployment steps, as described above.

# AWS Route 53 and SSL Certificate Creation

This document provides an explanation of the Terraform script used to create AWS Route 53 resources and an SSL certificate.

## Code Explanation

The code can be found in the route53 module in `modules/route53/main.tf`

- First, an AWS Route 53 hosted zone is created for your domain with the aws_route53_zone resource.

- Next, the aws_acm_certificate resource requests a wildcard SSL certificate for your domain. This certificate will secure your domain and all its subdomains. The validation_method is set to DNS, which means that Amazon will verify that you own the domain by checking DNS records.

- After requesting the certificate, we use the aws_route53_record resource to create a DNS validation record in our Route 53 hosted zone. This record is used by Amazon to verify our ownership of the domain.

- With the aws_acm_certificate_validation resource, we tell AWS to use our validation DNS record to validate the certificate.

- An AWS Route 53 CAA record is also created with the aws_route53_record resource. This record specifies that Amazon is authorized to issue certificates for our domain.

- Finally, the ARN of the certificate is stored in AWS SSM Parameter Store using the aws_ssm_parameter resource, so that it can be accessed by other resources.

## Initial Verification

The first time you run this script, Amazon will need to verify your ownership of the domain before issuing the certificate. To do this, Amazon will check for the presence of the DNS validation record that was created by the script.

When using Google Domains, follow these steps to add the validation record:

Go to the Google Domains website and sign in.
Select your domain.
Open the DNS settings.
In the 'Custom resource records' section, add a new record with the following details:

- Name: <CNAME name>
- Type: CNAME
- TTL: 1H
- Data: <CNAME value>
  After you've added the record, Amazon will automatically validate your domain once it detects the new DNS record. This process can take a few minutes to several hours, depending on DNS propagation times.

Note: Please replace the Name and Data values with the ones provided by the script's output.

### Certificate Renewal

Amazon will automatically renew managed certificates 60 days before they expire. This means that, once your domain is validated and the certificate is issued, Amazon will handle the renewal of the certificate for you. You will not need to manually renew the certificate or repeat the validation process.

## Future TODOS

- At the moment, the database is publicly accessible. We could add an inbound rule to a security group to restrict access to the ip of the vercel application in prod which would look something like this:

```
resource "aws_security_group_rule" "allow_specific_ip" {
    type = "ingress"
    from_port = 5432
    to_port = 5432
    protocol = "tcp"
    cidr_blocks = ["your.vercel.app.ip.address/32"]
    security_group_id = aws_db_instance.default.vpc_security_group_ids[0]
}
```

- Set up prod!
- Automate deployments
