[2] 250909~ 클라우드/[b] 12월 : Terraform + Ansible

[35] tier-3 + DB테스트

서버관리자 페페 2026. 2. 6. 18:42

맥락

- tier-3 terraform 구축

- 리소스 생성 / 아키텍쳐 끼리 통신 확인

:  web -> app

                  nginx 더미 깔아서 80으로 포트리슨 확인

 

- app(mysql-client)

     ->DB접근 확인

 

-

 

이제 client에서 DB까지 테스트

Node.js사용하여

WEB -> APP으로 사용자 요청 APP으로 프록시

APP -> RDS(MYSQL 3306) 으로 DB작성

 

-----------------------------------------

 

1: APP서버 셋팅

########### NODEJS설치 ###################
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf -y install nodejs
node -v
npm -v

############# APP dir ####################
sudo mkdir -p /opt/app
sudo chown -R ec2-user:ec2-user /opt/app 2>/dev/null || true
cd /opt/app
npm init -y
npm i express mysql2

 

 

2: APP서버 node js 스크립트

const express = require("express");
const mysql = require("mysql2/promise");

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const {
  DB_HOST,
  DB_PORT = "3306",
  DB_USER,
  DB_PASS,
  DB_NAME,
  PORT = "3000",
} = process.env;

function required(name, v) {
  if (!v) throw new Error(`Missing env: ${name}`);
  return v;
}

async function getConn() {
  required("DB_HOST", DB_HOST);
  required("DB_USER", DB_USER);
  required("DB_PASS", DB_PASS);
  required("DB_NAME", DB_NAME);

  return mysql.createConnection({
    host: DB_HOST,
    port: Number(DB_PORT),
    user: DB_USER,
    password: DB_PASS,
    database: DB_NAME,
  });
}

app.get("/health", (req, res) => res.status(200).send("ok"));

app.post("/api/post", async (req, res) => {
  const body = (req.body && req.body.body) || "";
  if (!body) return res.status(400).json({ ok: false, err: "body_required" });

  const conn = await getConn();
  try {
    await conn.execute(`
      CREATE TABLE IF NOT EXISTS posts (
        id INT AUTO_INCREMENT PRIMARY KEY,
        body TEXT NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);

    const [r] = await conn.execute("INSERT INTO posts (body) VALUES (?)", [body]);
    res.json({ ok: true, id: r.insertId });
  } finally {
    await conn.end();
  }
});

app.get("/api/get", async (req, res) => {
  const conn = await getConn();
  try {
    const [rows] = await conn.execute(
      "SELECT id, body, created_at FROM posts ORDER BY id DESC LIMIT 20"
    );
    res.json({ ok: true, rows });
  } finally {
    await conn.end();
  }
});

app.listen(Number(PORT), "0.0.0.0", () => {
  console.log(`APP listening on 0.0.0.0:${PORT}`);
});

 

3 :

APP 환경변수 + systemd로 서비스

### USER 권한 관리 #################
sudo useradd -r -s /sbin/nologin ec-user 2>/dev/null || true
sudo chown -R ec2-user:ec2-user /opt/app

##################환경변수 ###################
# /etc/app.env
DB_HOST=XXXXXendpointXXX
DB_PORT=3306
DB_USER=XXXXXXXXXXXXXXX
DB_PASS=XXXXXXXXXXXXXX
DB_NAME=main-mysql
PORT=3000

################systemd service ###################
[Unit]
Description=Node App (web->app->db)
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/app
EnvironmentFile=/etc/app.env
ExecStart=/usr/bin/node /opt/app/server.js
Restart=always
RestartSec=2

[Install]
WantedBy=multi-user.target

####################################################

################실행 ###################3
sudo systemctl daemon-reload
sudo systemctl enable --now app
sudo systemctl status app --no-pager
sudo journalctl -u app -n 50 --no-pager

###################TEST ON LOCAL#####################
curl -i http://127.0.0.1:3000/health

-> DB_NAME은 DB식별자가 아니다

DB 들어가서 SHOW DATABASES; 해야 나오는게 이름

 

 

4. WEB ---> APP으로 proxy

#############/etc/nginx/conf.d/site.conf#########################

server {
  listen 80;
  server_name _;

  root /usr/share/nginx/html;
  index main.html;

  location /api/ {
    proxy_pass http://APP_PRIVATE_IP:3000/api/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1;
  }

  location = /health {
    return 200 "ok\n";
    add_header Content-Type text/plain;
  }
}

########################적용 ################
sudo nginx -t && sudo systemctl reload nginx

 

+

 

client -> RDS endpoint로 HTTP/POST 테스트

curl -i -X POST http://<ALB_DNS>/api/post \
  -H "Content-Type: application/json" \
  -d '{"body":"hello from alb"}'

curl -i http://<ALB_DNS>/api/get

client -> RDS endpoint로 GET 테스트

 

----------------------------------------------------------------------

트러블슈팅

-> APP_SG는 WEB_SG로부터 3000으로 받는데 보안그룹 설정 안되어있었음

-> ingress form SG 3000 수정

 

DB-NAME

 

여기 있는 식별자는 terraform에서 tag이고

이게 DB이름이다

 

DB 이름                                                                             용도                                                                네 앱에서 사용?

information_schema 메타데이터 조회용
mysql 계정/권한 시스템 DB
performance_schema 성능 모니터링
sys 성능 뷰 집합
DB (직접 만든 듯 / 기본 아님) ⚠️ 가능

 

 

 

인스턴스를 켜두면 요금이 꽤 나온다

'[2] 250909~ 클라우드 > [b] 12월 : Terraform + Ansible' 카테고리의 다른 글

[37] ECS  (0) 2026.02.07
[36] 명령어 모음  (0) 2026.02.07
[34] tier-3  (0) 2026.02.04
[33] S3 + cloudfront  (0) 2026.01.31
[32] RDS Multi-AZ  (0) 2026.01.26