[AWS] DynamoDB 웹서비스 테스트

sunnyjjang·2024년 10월 6일

AWS

목록 보기
14/21
post-thumbnail

Lab. Using Amazon DynamoDB With AWS CLI

워크플로우
1. 인스턴스 생성
2. 계정 생성
3. dynamo DB 관리 권한 할당
4. Amazon DynamoDB 생성
5. DynamoDB에 JSON 데이터 기록
6. Python코드를 이용해 테이블 형태로 시각화 출력
7. 웹서비스

1. 인스턴스 생성 (AWS CLI 서버)

  1. name : CLI-Server
  2. key : lab-key
  3. vpc : lab-vpc
  4. az : public a
  5. 퍼블릭 IP 자동 할당 : 활성화
  6. sg 생성
    1. name : ssh-sg
    2. inbound : ssh 22, anywhere
    3. vpc : lab-vpc

2. 계정 생성

  1. IAM > 사용자 생성
    1. name : dbmanager
    2. 권한 설정 > 직접 정책 연결 : AmazonDynamoDBFullAccess (dynamo DB 관리 권한)
  2. 목적 : AWS CLI에서 aws 명령어로 AWS를 조작할 수 있도록 권한 부여
  3. 역할 : AWS Full Access(인스턴스 생성, RDS 생성 등)는 허용하지 않고 dynamo DB 조작에 대한 Full Access만 허용
  4. 계정 > 보안 자격 증명 > 엑세스 키 > Command Line Interface(CLI)
    1. 역할에 엑세스 키를 부여해서 aws 명령어를 사용할 수 있게 허용
    2. 액세스 키 : AKIA4MTW****
    3. 비밀 액세스 키 : R6q38laqDF/2TH****
      해당 키는 랩 이후 삭제하였음. 노출시키는 것을 권장하지 않습니다.
  • 조작 권한 주는 방법
  1. 사용자 생성 후, 엑세스 키를 부여해서 aws 프로파일(자격증명) 등록하는 방법
  2. 역할 생성 후, aws 콘솔에서 인스턴스 선택 후, 연결한 후, 프로파일에서는 key정보 넣지 않는 방법

3. dynamo DB 관리 권한 할당

# 1. old version 삭제
[ec2-user@ip-10-0-0-120 ~]$ sudo yum remove awscli

# 2. AWS CLI 설치 ( aws 명령어 사용하기 위함)
[ec2-user@ip-10-0-0-120 ~]$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# 3. 설치 확인
[ec2-user@ip-10-0-0-120 ~]$ aws --version

# 위에 명령어가 실행되지 않는 경우 path를 변경해주어야함
[ec2-user@ip-10-0-0-120 ~]$ /usr/local/bin/aws --version
aws-cli/2.17.60 Python/3.12.6 Linux/6.1.109-118.189.amzn2023.x86_64 exe/x86_64.amzn.2023
[ec2-user@ip-10-0-0-120 ~]$ sudo mv /usr/local/bin/aws /usr/bin/

# 4. dbmanager 계정 프로파일 등록
[ec2-user@ip-10-0-0-120 ~]$ aws configure
AWS Access Key ID [None]: AKIA4MTW****
AWS Secret Access Key [None]: r4c+WT3QYjN5MAK1+ardD8NQhS****
Default region name [None]: ap-northeast-2
Default output format [None]: json

# 5. AWS 에서 아용 중인 자격 증명 확인
[ec2-user@ip-10-0-0-120 ~]$ aws sts get-caller-identity
{
    "UserId": "AIDA4M****",
    "Account": "851725****",
    "Arn": "arn:aws:iam::8517252****:user/dbmanager"
}

# 6. 프로파일 등록 확인
[ec2-user@ip-10-0-0-120 ~]$ aws dynamodb list-tables
{
    "TableNames": []
}
# => dynamodb access 가능 

[ec2-user@ip-10-0-0-120 ~]$ aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:iam::851725267032:user/dbmanager is not authorized to perform: s3:ListAllMyBuckets because no identity-based policy allows the s3:ListAllMyBuckets action
# => s3 access 불가능 

4. Amazon DynamoDB 생성

  1. name : ProductCatalog
  2. 파티션 키 : Id - 숫자

5. DynamoDB에 JSON 데이터 기록

  1. 다운로드 받은 json 파일을 세션의 디렉토리로 전달
  2. 테이블 확인
 # dynamodb table 확인
[ec2-user@ip-10-0-0-120 ~]$ aws dynamodb list-tables
{
    "TableNames": [
        "ProductCatalog"
    ]
}

 # ProductCatalog table 확인
[ec2-user@ip-10-0-0-120 ~]$ aws dynamodb describe-table --table-name ProductCatalog
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "Id",
                "AttributeType": "N"
            }
        ],
        "TableName": "ProductCatalog",
        "KeySchema": [
            {
                "AttributeName": "Id",
                "KeyType": "HASH"
            }
        ],
        ...
  1. DynamoDB의 ProductCatalog 테이블에 json 파일 push
 # dynamoDB 테이블에 json 파일의 items push 해서 저장
[ec2-user@ip-10-0-0-120 ~]$ aws dynamodb batch-write-item --request-items file://ProductCatalog.json
{
    "UnprocessedItems": {}
}
  1. 테이블 생성
# inventory 테이블 생성
aws dynamodb create-table \
    --table-name Inventory \
    --attribute-definitions \
        AttributeName=ItemId,AttributeType=S \
    --key-schema \
        AttributeName=ItemId,KeyType=HASH \
    --provisioned-throughput \
        ReadCapacityUnits=5,WriteCapacityUnits=5

# 테이블 확인
aws dynamodb list-tables
  1. 데이터 삽입
aws dynamodb put-item \
    --table-name Inventory \
    --item '{"ItemId": {"S": "201"}, "ItemName": {"S": "Mountain Bike"}, "Category": {"S": "Bicycles"}, "Quantity": {"N": "10"}, "Price": {"N": "500"}}'

aws dynamodb put-item \
    --table-name Inventory \
    --item '{"ItemId": {"S": "202"}, "ItemName": {"S": "Road Bike"}, "Category": {"S": "Bicycles"}, "Quantity": {"N": "5"}, "Price": {"N": "1000"}}'

aws dynamodb put-item \
    --table-name Inventory \
    --item '{"ItemId": {"S": "203"}, "ItemName": {"S": "Helmet"}, "Category": {"S": "Accessories"}, "Quantity": {"N": "50"}, "Price": {"N": "50"}}'
  1. 데이터 조회
# 전체 데이터 조회
aws dynamodb scan --table-name Inventory
aws dynamodb scan --table-name Inventory --output json
aws dynamodb scan --table-name Inventory --output table

# 항목별 검색
aws dynamodb get-item \
    --table-name Inventory \
    --key '{"ItemId": {"S": "202"}}'
# 카테고리별 검색 - 카테고리가 "Bicycles"인 항목만 조회
aws dynamodb scan \
    --table-name Inventory \
    --filter-expression "Category = :cat" \
    --expression-attribute-values  '{":cat":{"S":"Bicycles"}}'
# 조건별 검색 - 재고량이 10 이상인 항목만 필터링
aws dynamodb scan \
    --table-name Inventory \
    --filter-expression "Quantity >= :qty" \
    --expression-attribute-values  '{":qty":{"N":"10"}}'

6. Python코드를 이용해 테이블 형태로 시각화 출력

  1. python 프로그램 및 라이브러리 설치
sudo yum install python pip
pip install boto3 pandas
  1. 디렉토리 생성
[ec2-user@ip-10-0-0-120 ~]$ mkdir inventory
[ec2-user@ip-10-0-0-120 ~]$ cd inventory/
  1. 파일 생성
[ec2-user@ip-10-0-0-120 inventory]$ cat > inventory.py
import boto3
import pandas as pd

# DynamoDB client 생성
dynamodb = boto3.client('dynamodb', region_name='ap-northeast-2')

# Inventory 테이블의 모든 항목을 스캔
response = dynamodb.scan(TableName='Inventory')

# DynamoDB 항목을 DataFrame으로 변환
items = response['Items']

# 필요한 데이터를 추출하여 DataFrame 생성
data = []
for item in items:
    data.append({
        'ItemId': item['ItemId']['S'],
        'ItemName': item['ItemName']['S'],
        'Category': item['Category']['S'],
        'Quantity': int(item['Quantity']['N']),
        'Price': float(item['Price']['N'])
    })

df = pd.DataFrame(data)

# 결과를 표로 출력
print(df)
  1. 결과 보기
python inventory.py
  ItemId       ItemName     Category  Quantity   Price
0    202      Road Bike     Bicycles         5  1000.0
1    201  Mountain Bike     Bicycles        10   500.0
2    203         Helmet  Accessories        50    50.0

7. 웹서비스

  1. 보안 그룹 : 방화벽 5000 포트 열기

  2. Flask 애플리케이션 구조

    /inventory/

    ├── app.py # Flask 애플리케이션 코드
    ├── templates/ # 템플릿 파일을 저장하는 디렉토리
    │ └── inventory.html # Flask에서 사용하는 HTML 템플릿 파일
    ├── static/ # 정적 파일 (CSS, JavaScript, 이미지 등)
    └── venv/ # 가상 환경 (선택 사항)

  3. 실행 결과를 웹 서버를 통해 전달

# 라이브러리 설치
pip install Flask 

# app.py 소스코드
from flask import Flask, render_template
import boto3

app = Flask(__name__)

# DynamoDB client 생성
dynamodb = boto3.client('dynamodb', region_name='ap-northeast-2')

@app.route('/')
def index():
    # Inventory 테이블의 모든 항목을 스캔
    response = dynamodb.scan(TableName='Inventory')
    items = response['Items']

    # 필요한 데이터를 추출하여 리스트 생성
    data = []
    for item in items:
        data.append({
            'ItemId': item['ItemId']['S'],
            'ItemName': item['ItemName']['S'],
            'Category': item['Category']['S'],
            'Quantity': int(item['Quantity']['N']),
            'Price': float(item['Price']['N'])
        })

    # 데이터를 템플릿으로 전달
    return render_template('inventory.html', data=data)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)   

# HTML 소스코드
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Inventory</title>
    <style>
        table {
            width: 50%;
            margin: 50px auto;
            border-collapse: collapse;
        }
        th, td {
            padding: 10px;
            border: 1px solid #ccc;
            text-align: center;
        }
        th {
            background-color: #f4f4f4;
        }
    </style>
</head>
<body>
    <h1 style="text-align:center;">Inventory Table</h1>
    <table>
        <thead>
            <tr>
                <th>ItemId</th>
                <th>ItemName</th>
                <th>Category</th>
                <th>Quantity</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            {% for item in data %}
            <tr>
                <td>{{ item.ItemId }}</td>
                <td>{{ item.ItemName }}</td>
                <td>{{ item.Category }}</td>
                <td>{{ item.Quantity }}</td>
                <td>{{ item.Price }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>
  1. app.py 실행 후, 웹페이지 확인
profile
지금 이 순간이 다시 넘겨볼 수 있는 한 페이지가 될 수 있게

0개의 댓글