---
# System prepended metadata

title: AWS 3-Tier Web Architecture 實作
tags: [AWS]

---

# 簡介
在AWS上建立3-tier的Web Architecture 

3-tier 分別為:
-Web tier
-App tier
-DB tier

分成兩個AZ並在Web tier與App tier做Load Balance與Auto Scaling


# 架構
![upload_f1e8f505ebffa1146f01bec42623c1a9](https://hackmd.io/_uploads/Sytd3HBLa.png)


# 實作流程

sample code:
https://github.com/aws-samples/aws-three-tier-web-architecture-workshop/tree/main

1. 建S3 bucket
2. 設定IAM role 給EC2 使用SSM和存取S3的權限 
-> 加入兩個policies :
AmazonSSMManagedInstanceCore
AmazonS3ReadOnlyAccess
![image](https://hackmd.io/_uploads/S1Jw1SH86.png)

4. 建VPC
-> 分別在AZ1和AZ2建立public subnet 與 private subnet 和 DB private subnet
-> 建IGW 和 NAT(要給EIP) 、設定route table 讓public subnet 和 private subnet 連網
![image](https://hackmd.io/_uploads/BJUCyBrLT.png)

8. 設定security group
* external ALB:
![image](https://hackmd.io/_uploads/SkCA7BHIa.png)
![image](https://hackmd.io/_uploads/rygmErS8a.png)
* Web tier:
![image](https://hackmd.io/_uploads/Hk4L4rHLT.png)
![image](https://hackmd.io/_uploads/H1OrEBH86.png)
* internal ALB:
![image](https://hackmd.io/_uploads/H1ktEBHUa.png)
![image](https://hackmd.io/_uploads/BkmHpBrU6.png)
* App tier:
![image](https://hackmd.io/_uploads/BJ0O6HSLa.png)
![image](https://hackmd.io/_uploads/H19M0sQOa.png)
* DB tier:
![image](https://hackmd.io/_uploads/HyFo6Hr8p.png)
![image](https://hackmd.io/_uploads/SkvhpBrL6.png)


5. 建DB tier (RDS)
->DB subnet group
->create database
![image](https://hackmd.io/_uploads/BkL70HSU6.png)

10. 建App tier (EC2)

->Launch Instance
->利用Session Manager 連線至EC2
![image](https://hackmd.io/_uploads/ByWxHvqDp.png)

-> 安裝mysql 並連線到RDS(利用 endpoint 和 username)
```
mysql -h CHANGE-TO-YOUR-RDS-ENDPOINT -u CHANGE-TO-USER-NAME -p
```

->建一database 和 table 並新增一筆資料
```
CREATE DATABASE webappdb;   
SHOW DATABASES;
USE webappdb;    

CREATE TABLE IF NOT EXISTS transactions(id INT NOT NULL
AUTO_INCREMENT, amount DECIMAL(10,2), description
VARCHAR(100), PRIMARY KEY(id));   

SHOW TABLES;    
INSERT INTO transactions (amount,description) VALUES ('400','groceries');   
SELECT * FROM transactions;
```
->edit app-tier 裡的 DbConfig.js
```
module.exports = Object.freeze({
    DB_HOST : 'RDS的endpoint',
    DB_USER : 'RDS建立時設定的username default為admin',
    DB_PWD : 'RDS建立時設定的密碼',
    DB_DATABASE : '要使用的database 此例為剛剛建立的webappdb '
});
```
->上傳app-tier資料夾到S3
![image](https://hackmd.io/_uploads/BkJ4bLSIT.png)

->install run app server要用的東西(node.js、nvm、pm2) 並下載S3上的app-tier
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
source ~/.bashrc

nvm install 16
nvm use 16

npm install -g pm2   

cd ~/
aws s3 cp s3://BUCKET_NAME/app-tier/ app-tier --recursive

cd ~/app-tier
npm install
pm2 start index.js //run the app

pm2 list //確認是否running correctly
pm2 logs //可查看Log
pm2 startup 
//copy and past the command in the output you see in your own terminal
pm2 save
```
->test the app server
```
curl http://localhost:4000/health
//output: "This is the health check"

curl http://localhost:4000/transaction
//output: {"result":[{"id":1,"amount":400,"description":"groceries"},{"id":2,"amount":100,"description":"class"},{"id":3,"amount":200,"description":"other groceries"},{"id":4,"amount":10,"description":"brownies"}]}

//若無output DB內容 可能是Dbconfig.js內容有填錯
```
7. Internal Load Balancing (App tier 的 ALB) and Auto Scaling
->建App tier 的image
->建target group
->建Internal ALB
->建Launch template (用App tier image)
->建Auto Scaling Group



13. 建Web tier(EC2)

->編輯Web tier 的nginx.conf 設定 Internal ALB 的endpoint 以連結 App tier
```
#proxy for internal lb
        location /api/{
                proxy_pass <Internal ALB endpoint>;
        }
```
->上傳web-tier 和 nginx.conf 到 S3
![image](https://hackmd.io/_uploads/BkSFovrU6.png)

->Launch Instance
->安裝nginx、install run web server要用的東西(node.js、nvm、pm2) 並 run the web
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
source ~/.bashrc
nvm install 16
nvm use 16

cd ~/
aws s3 cp s3://BUCKET_NAME/web-tier/ web-tier --recursive //從S3下載web tier

cd ~/web-tier
npm install 
npm run build

sudo yum install nginx

cd /etc/nginx
ls

//將原本的nginx.conf取代
sudo rm nginx.conf
sudo aws s3 cp s3://BUCKET_NAME/nginx.conf . //從S3下載nginx.conf

sudo service nginx restart
chmod -R 755 /home/ec2-user
sudo chkconfig nginx on //run the web
```



9. External Load Balancing (Web tier 的 ALB) and Auto Scaling
->建Web tier 的image
->建target group
->建External ALB
->建Launch template (用Web tier image)
->建Auto Scaling Group


# 成果
![image](https://hackmd.io/_uploads/SJzI0zN8a.png)

![image](https://hackmd.io/_uploads/SyVrCG4L6.png)

![image](https://hackmd.io/_uploads/BJl4CM48a.png)


# 碰到的問題

直接輸入Public IP 或 Domain name在網址列訪問網站會預設為https連線
此處web無設定SSL 
所以須使用http連線才能成功

![1](https://hackmd.io/_uploads/B1Ju2rqvT.png)

![2](https://hackmd.io/_uploads/HyQOhScva.png)

# Reference

https://catalog.us-east-1.prod.workshops.aws/workshops/85cd2bb2-7f79-4e96-bdee-8078e469752a/en-US/introduction

https://github.com/aws-samples/aws-three-tier-web-architecture-workshop/tree/main

https://www.youtube.com/watch?v=amiIcyt-J2A&t=2635s&ab_channel=TechTutorialswithPiyush
