> For the complete documentation index, see [llms.txt](https://portfolio.litovchenko.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portfolio.litovchenko.net/projects/3-tier-architecture-aws-best-practices-wordpress-application.md).

# 3 Tier Architecture AWS best practices: WordPress application

Wordpress on AWS - Terraform for multiple teams Project

#### GitHub: <https://github.com/serglit72/terraform-aws-wordpress>

<figure><img src="https://3069929224-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZK537jc9eCqE_tMOV2%2Fuploads%2FWL1xHyUUeoMpI6ZqgWHG%2F3tierarch.png?alt=media&amp;token=77107594-d679-48fd-9906-1fce70723496" alt=""><figcaption></figcaption></figure>

In this project, we aimed to build a three-tier WordPress application using Terraform in a real-world environment where the DevOps team is distributed worldwide and independent contributors or groups provide each block. To make it possible we use a "remote" backend for Terraform on an S3 bucket (versioning enabled) and DynamoDB to keep the state locked for only one transaction at a time.

***

{% hint style="info" %}

### [Resources will be created:](https://github.com/serglit72/terraform-aws-wordpress#resources-will-be-created) <a href="#user-content-resources-will-be-created" id="user-content-resources-will-be-created"></a>

#### [Backend-S3-DynamoDB](https://github.com/serglit72/terraform-aws-wordpress#backend-s3-dynamodb) <a href="#user-content-backend-s3-dynamodb" id="user-content-backend-s3-dynamodb"></a>

* 1 x S3 bucket (prod env)
* 1 x DynamoDB table

#### [Infrastructure](https://github.com/serglit72/terraform-aws-wordpress#infrastructure) <a href="#user-content-infrastructure" id="user-content-infrastructure"></a>

* 1 x VPC
* 2 x Private Subnets
* 2 x Public Subnets
* 1 x Public Route table
* 1 x Private Route table
* 1 x Internet Gateway
* 2 x NAT Gateway

#### [Frontend layer](https://github.com/serglit72/terraform-aws-wordpress#frontend-layer) <a href="#user-content-frontend-layer" id="user-content-frontend-layer"></a>

* 1 x Application Load Balancer
* 1 x Auto Scaling Group (2 minimum 99 maximum instances-horizontally scalable)
* 1 x security group for Web layer
* 2 x EC2 instances (minimum) (WordPress)

#### [Database layer](https://github.com/serglit72/terraform-aws-wordpress#database-layer) <a href="#user-content-database-layer" id="user-content-database-layer"></a>

* 1 x RDS Aurora cluster with 1 writer, 1 reader instances (horizontally scalable)
* 1 x security group for Database layer
  {% endhint %}

### Steps: <a href="#user-content-prerequisites" id="user-content-prerequisites"></a>

1. Git clone the repo
2. Go to repo directory:

```
cd united-wordpress-aws
```

3. Check if *aws s3* is available:

```
aws s3 ls
```

4. Copy content from the "template.txt" file or edit and save it as "envs/prod/prod.tfvars" file:

```
vim envs/prod/prod.tfvars
```

```
public_key = "~/.ssh/id_rsa.pub"
region     = "your-region"              # change if needed
key_name   = "your_key_name"            # change
domain     = "yourdomainname.com"       # change
zone_id = "copy-from-route53-region-ID" # change
rds_username = "admin"                  # change the username 
rds_password = "admin123"               # change the password 
tags = {
  Name = "Wordpress-VPC"
  Team = "AWS"
}
```

5. Run script to install Terraform environment and version:

```
bash scripts/installation.sh
```

#### Backend Setup (DynamoDB +S3) <a href="#user-content-backend-setup-dynamodb-s3" id="user-content-backend-setup-dynamodb-s3"></a>

Run Makefile:

```
$ make backend
```

**Script also will create the "backend.tf" file into VPC,ASG,RDS folders**

6. Optionally, if your VM does not have administrator priviliages, run below commands to add your AWS credentials as environment variables.

```
$ export AWS_ACCESS_KEY_ID={Your AWS_ACCESS_KEY_ID} 
$ export AWS_SECRET_ACCESS_KEY={Your AWS_SECRET_ACCESS_KEY} 
```

7. Finaly, run

```
$ make build
```

And wait for about 20 mins

#### For Deleting Resources and delete the Application: <a href="#user-content-for-deleting-resources-and-delete-the-application" id="user-content-for-deleting-resources-and-delete-the-application"></a>

```
$ make destroy
```

**TROUBLESHOOTING:**

In case of error when deleteing S3 bucket use AWS console and manually empty and delete the bucket

```
│ Error: deleting Amazon S3 (Simple Storage) Bucket (terraform-tfstate-prod-1999999999999): BucketNotEmpty: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
│       status code: 409, request id: HAMSEY42N6MG45QR, host id: h8kkpMo03yqa5U+esfQJZwgeaenEg63dqUexPPYV4b4j63JNfQjiJO8WlwyifBF5qK5OeE7ZXlU=
│ 
```

### Test Database accessibility: <a href="#user-content-test-database-accessability" id="user-content-test-database-accessability"></a>

***From EC2 instance of Web in your VPC!!!*** ***DB endpoints should be available from the final outputs***

```
[ec2-user@ip-10-0-1-157 ~]$ mysql -h aurora-cluster-demo.cluster-ctxxweudrhd8.us-west-1.rds.amazonaws.com -u admin -p mydb
>
Enter password: ******
```

You should see:

```
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 219
Server version: 8.0.23 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
```
