Skip to content
Merged
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ repos:
files: ^infrastructure/.*\.tf$
- id: terraform_tflint
files: ^infrastructure/.*\.tf$
args:
- --args=--config=__GIT_WORKING_DIR__/infrastructure/.tflint.hcl

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.6
Expand Down
45 changes: 45 additions & 0 deletions infrastructure/.tflint.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
plugin "aws" {
enabled = true
version = "0.44.0"
source = "github.com/terraform-linters/tflint-ruleset-aws"
}

plugin "terraform" {
enabled = true
version = "0.13.0"
source = "github.com/terraform-linters/tflint-ruleset-terraform"
}

rule "aws_resource_missing_tags" {
enabled = false
}

rule "terraform_documented_outputs" {
enabled = true
}

rule "terraform_documented_variables" {
enabled = true
}

rule "terraform_module_pinned_source" {
enabled = true
style = "semver"
}

rule "terraform_naming_convention" {
enabled = true
format = "snake_case"
}

rule "terraform_required_providers" {
enabled = true
}

rule "terraform_required_version" {
enabled = true
}

rule "terraform_typed_variables" {
enabled = true
}
254 changes: 140 additions & 114 deletions infrastructure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,185 +17,209 @@ Follow these steps to set up the infrastructure:

1. **Setup Backend (one-time setup)**:

- Navigate to the backend directory:
```bash
cd infrastructure/backend/
```
- Navigate to the backend directory:

**Note:** Optionally change the region: set `aws_region` in a `.tfvars` file.
```bash
cd infrastructure/backend/
```

- Initialize Terraform if needed:
```bash
terraform init
```
> [!NOTE]
> Optionally change the region: set `aws_region` in a `.tfvars` file.

- Apply the changes to create the backend resources:
```bash
terraform apply
```
- Initialize Terraform if needed:

```bash
terraform init
```

- Apply the changes to create the backend resources:

```bash
terraform apply
```

**Note:** Copy the state bucket name from the output.
> [!NOTE]
> Copy the state bucket name from the output.

**Note:** It is recommended to not destroy the backend resources unless absolutely necessary.
> [!NOTE]
> It is recommended to not destroy the backend resources unless absolutely necessary.

2. **Setup Main Infrastructure (staging)**:

- Navigate to the main infrastructure directory. If you are in `infrastructure/backend`, you can use:
```bash
cd ../staging/
```
- Navigate to the main infrastructure directory. If you are in `infrastructure/backend`, you can use:

- Create a local variables file:
```bash
touch terraform.tfvars
```
```bash
cd ../staging/
```

- Copy the contents from the example file:
```bash
cat terraform.tfvars.example > terraform.tfvars
```
- Create a local variables file:

- Create a local backend configuration file:
```bash
touch terraform.tfbackend
```
```bash
touch terraform.tfvars
```

- Copy the contents from the example file:
```bash
cat terraform.tfbackend.example > terraform.tfbackend
```
- Copy the contents from the example file:

*Note:* Update the state bucket name in `terraform.tfbackend` with the name of the state bucket created in the previous step.
```bash
cat terraform.tfvars.example > terraform.tfvars
```

*Note:* Update defaults (e.g. `region`) as needed.
- Create a local backend configuration file:

- Initialize Terraform with the backend configuration:
```bash
terraform init -backend-config=terraform.tfbackend
```
```bash
touch terraform.tfbackend
```

- Apply the changes to create the main infrastructure using the command:
```bash
terraform apply
```
- Copy the contents from the example file:

3. **Populate Secrets**
```bash
cat terraform.tfbackend.example > terraform.tfbackend
```

- Visit the AWS Console > Systems Manager > Parameter Store.
- Populate all `DJANGO_*` secrets that have `to-be-set-in-aws-console` value.
> [!NOTE]
> Update the state bucket name in `terraform.tfbackend` with the name of the state bucket created in the previous step.

> [!NOTE]
> Update defaults (e.g. `region`) as needed.

- Initialize Terraform with the backend configuration:

```bash
terraform init -backend-config=terraform.tfbackend
```

- Apply the changes to create the main infrastructure using the command:

```bash
terraform apply
```

3. **Populate Secrets**

- Visit the AWS Console > Systems Manager > Parameter Store.
- Populate all `DJANGO_*` secrets that have `to-be-set-in-aws-console` value.

## Setting up Zappa

The Django backend deployment is managed by Zappa. This includes the API Gateway, IAM roles, and Lambda Function provision.

1. **Change Directory**:

- Change the directory to `backend/` using the following command:
- Change the directory to `backend/` using the following command:

```bash
cd ../../backend/
```
```bash
cd ../../backend/
```

*Note*: The following steps assume the current working directory is `backend/`
> [!NOTE]
> The following steps assume the current working directory is `backend/`

2. **Setup Dependencies**:

- This step may differ for different operating systems.
- The goal is to install dependencies listed in `pyproject.toml`.
- Steps for Linux:
- This step may differ for different operating systems.
- The goal is to install dependencies listed in `pyproject.toml`.
- Steps for Linux:

```bash
poetry install && eval $(poetry env activate)
```
```bash
poetry install && eval $(poetry env activate)
```

3. **Create Zappa Settings File**:

- Create a local Zappa settings file in the `backend` directory:
- Create a local Zappa settings file in the `backend` directory:

```bash
touch zappa_settings.json
```
```bash
touch zappa_settings.json
```

- Copy the contents from the template file into your new local environment file:
- Copy the contents from the template file into your new local environment file:

```bash
cat zappa_settings.example.json > zappa_settings.json
```
```bash
cat zappa_settings.example.json > zappa_settings.json
```

4. **Populate Settings File**:

- Replace all `${...}` variables in `zappa_settings.json` with appropriate output variables.
- Replace all `${...}` variables in `zappa_settings.json` with appropriate output variables.

5. **Deploy**:

- **Note**: Make sure to populate all `DJANGO_*` secrets that are set as `to-be-set-in-aws-console`
in the Parameter Store. The deployment might fail with no logs if secrets such as
`DJANGO_SLACK_BOT_TOKEN` are invalid.
> [!NOTE]
> Make sure to populate all `DJANGO_*` secrets that are set as `to-be-set-in-aws-console` in the Parameter Store. The deployment might fail with no logs if secrets such as `DJANGO_SLACK_BOT_TOKEN` are invalid.

```bash
zappa deploy staging
```
- **Note**: If the deployment is successful but returns a `5xx` error, resolve the issues
and use `zappa undeploy staging` & `zappa deploy staging`. The command `zappa update staging` may not work.
```bash
zappa deploy staging
```

Once deployed, use the URL provided by Zappa to test the API.
> [!NOTE]
> If the deployment is successful but returns a `5xx` error, resolve the issues and use `zappa undeploy staging` & `zappa deploy staging`. The command `zappa update staging` may not work.

Once deployed, use the URL provided by Zappa to test the API.

## Setup Database

Migrate and load data into the new database.

1. **Setup ECR Image**:
- Login to the Elastic Container Registry using the following command:

*Note*: replace `us-east-2` with configured region and `000000000000` with AWS Account ID.
- Login to the Elastic Container Registry using the following command:

> [!NOTE]
> Replace `us-east-2` with configured region and `000000000000` with AWS Account ID.

*Warning*: Configure a credential helper instead of using following command to login.
> [!WARNING]
> Configure a credential helper instead of using following command to login.

```bash
aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 000000000000.dkr.ecr.us-east-2.amazonaws.com
```
```bash
aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 000000000000.dkr.ecr.us-east-2.amazonaws.com
```

- Build the backend image using the following command:

```bash
docker build -t owasp-nest-staging-backend:latest -f docker/Dockerfile .
```

- Build the backend image using the following command:
- Tag the image:

```bash
docker build -t owasp-nest-staging-backend:latest -f docker/Dockerfile .
```
> [!NOTE]
> Replace `us-east-2` with configured region and `000000000000` with AWS Account ID.

- Tag the image:
*Note*: replace `us-east-2` with configured region and `000000000000` with AWS Account ID.
```bash
docker tag owasp-nest-staging-backend:latest 000000000000.dkr.ecr.us-east-2.amazonaws.com/owasp-nest-staging-backend:latest
```

```bash
docker tag owasp-nest-staging-backend:latest 000000000000.dkr.ecr.us-east-2.amazonaws.com/owasp-nest-staging-backend:latest
```
- Push the image:

- Push the image:
*Note*: replace `us-east-2` with configured region and `000000000000` with AWS Account ID.
> [!NOTE]
> Replace `us-east-2` with configured region and `000000000000` with AWS Account ID.

```bash
docker push 000000000000.dkr.ecr.us-east-2.amazonaws.com/owasp-nest-staging-backend:latest
```
```bash
docker push 000000000000.dkr.ecr.us-east-2.amazonaws.com/owasp-nest-staging-backend:latest
```

2. **Upload Fixture to S3**:
- Upload the fixture present in `backend/data` to `nest-fixtures` bucket using the following command:

```bash
aws s3 cp data/nest.json.gz s3://owasp-nest-fixtures-<id>/
```
- Upload the fixture present in `backend/data` to `nest-fixtures` bucket using the following command:

```bash
aws s3 cp data/nest.json.gz s3://owasp-nest-fixtures-<id>/
```

3. **Run ECS Tasks**:
- Head over to Elastic Container Service in the AWS Console.
- Click on `owasp-nest-staging-migrate` in `Task Definitions` section.
- Select the task definition revision.
- Click Deploy > Run Task.
- Use the following configuration:
- Networking:
- VPC: owasp-nest-staging-vpc
- Subnets: subnets will be auto-selected due to VPC selection.
- Security group name: select the ECS security group (e.g. `owasp-nest-staging-ecs-sg`).
- Click "Create"
- The task is now running... Click on the task ID to view Logs, Status, etc.
- Follow the same steps for `owasp-nest-staging-load-data` and `owasp-nest-staging-index-data`.

- Head over to Elastic Container Service in the AWS Console.
- Click on `owasp-nest-staging-migrate` in `Task Definitions` section.
- Select the task definition revision.
- Click Deploy > Run Task.
- Use the following configuration:
- Networking:
- VPC: owasp-nest-staging-vpc
- Subnets: subnets will be auto-selected due to VPC selection.
- Security group name: select the ECS security group (e.g. `owasp-nest-staging-ecs-sg`).
- Click "Create"
- The task is now running... Click on the task ID to view Logs, Status, etc.
- Follow the same steps for `owasp-nest-staging-load-data` and `owasp-nest-staging-index-data`.

## Cleaning Up

Expand All @@ -207,7 +231,9 @@ Migrate and load data into the new database.

- Ensure all buckets and ECR repositories are empty.

**Note:** Some resources have `prevent_destroy` set to `true`. Please set it to `false` before destruction.
> [!NOTE]
> Some resources have `prevent_destroy` set to `true`. Please set it to `false` before destruction.

- To destroy Terraform infrastructure:

```bash
Expand Down
Loading
Loading