AWS 자원 어떻게 구성해야 하나요?



AWS 클라우드 쉽게 사용해보기 -> PaaS 처럼 써보기
Poll앱을 쉽게 배포해보기
- 샘플 프로젝트 : https://github.com/go4real/Django-Poll-App
- 컴퓨팅 환경: Amazon ECS + AWS Fargate à 서버리스 환경
* AWS Elastic Beanstalk 사용 대비 서비스 확장에 따른 자유도가 높음
- 빌드/배포 : AWS Copilot CLI

AWS Copilot CLI는 아래와 같이 프로비저닝해야 하는 많은 자원들을 생성해준다.

실습자료: https://github.com/go4real/linux_campus
1단계. 실행 환경 구성 (Part2/Ch01_06/01_environment_setup.md)
- AWS Copilot CLI 설치
- Copilot CLI 실행 권한 설정
(Role 생성 + Policy 적용)
- AWS CLI 설치
- Docker desktop 설치
- Project 코드가 없는 경우 코드 새로 받기
git clone https://github.com/go4real/Django-Poll-App.git
git checkout ecs-base
1. AWS Copilot cli 설치
+ https://aws.github.io/copilot-cli/docs/getting-started/install/
```
curl -Lo copilot https://github.com/aws/copilot-cli/releases/latest/download/copilot-linux && chmod +x copilot && sudo mv copilot /usr/local/bin/copilot && copilot --help 명령어 입력
```

+ copilot 자동 완성 기능 설정
```
source <(copilot completion bash)
copilot completion bash > copilot.sh
sudo mv copilot.sh /etc/bash_completion.d/copilot
```

2. AWS EC2에 적용할 IAM role 생성 및 적용

aws 서비스와 ec2를 선택 후 다음을 누른다.

Administrator Access 권한을 부여하고 다음을 누른다.

역할 이름을 ECSDemo로 설정하고 역할을 생성한다.


동작중인 ec2 인스턴스의 IAM 역할 수정을 한다.
이 작업을 통해 ec2 인스턴스 내에서는 AWS CLI를 수행할때 관리자 권한으로 실행된다.
3. AWS CLI 설치
+ https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html
```
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```
4. AWS CLI 설정 (ap-northeast-2)
```
aws configure
```

5. Docker Desktop
+ https://docs.docker.com/engine/install/ubuntu/
+ https://docs.docker.com/engine/install/linux-postinstall/
```
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker # vs remote server 재시작 또는 sudo reboot
```
6. Git에서 새로 코드를 받으시는 분들
```
git clone https://github.com/go4real/Django-Poll-App.git
cd Django-Poll-App
git checkout ecs-base
```


2단계. 애플리케이션 구성 (Part2/Ch01_06/02_app_provisioning.md)
- Copilot 애플리케이션: 서비스와 환경의 집합
- 추가 단계: PostgresDB 배포

1. ECS 앱 생성 프로젝트 루트에서 실행
```
copilot init
# Application name: poll-app
## poll-db 서비스 생성
# Workload type: Backend Service
# Service name: poll-db
# Dockerfile: Use an existing image instead
# Image: postgres
```



Deploy는 뒤에 몇가지 수정 작업을 거친 후에 할 것이기에 NO를 입력한다.
2. copilot 디렉토리 내용 확인
+ postgres 포트 설정
+ copilot/poll-db/manifest.yml
...
image:
location: postgres
port: 5432 # 공개할 포트정보 추가
...
```

포트 정보를 추가로 입력한다.
3. dev 환경 생성
```
copilot env init
# Environment name: dev
# Credential source: [profile default]
# 다른 항목은 기본설정 사용
```

+ 3분 이상 시간 소요 --> AWS Web Console에서 인프라 생성 내용 확인 (ECS, CloudFormation 등)

4. poll-db 서비스 배포
```
copilot deploy
```
+ AWS Console에서 배포 상태 확인
+ 오류 확인 : Error: Database is uninitialized and superuser password is not specified.
+ ctrl+c로 copilot 실행 종료


5. Database 초기 실행 정보 설정
+ copilot/poll-db/manifest.yml
...
variables: # Pass environment variables as key value pairs.
POSTGRES_DB: poll
POSTGRES_USER: fast
POSTGRES_PASSWORD: 1234qwer
...

6. deploy 실행
```
copilot deploy
# ✘ execute svc deploy: deploy service poll-db to environment dev: deploy service: stack poll-app-dev-poll-db is currently being updated and cannot be deployed to
```


7. Circuitbreaker 에서 기본 서비스 시작 재시도 횟수 10번 실패
+ 수분 이상 소요
8. 배포작업 자동 롤백 및 CloudFormation 종료
9. 다시 deploy 진행
```
copilot deploy
```
+ 서비스 배포 완료 확인
3단계. 백엔드 서비스 구성 (Part2/Ch01_06/ 03_backend_deploy.md)
- poll-backend 서비스 구성
- poll-db 서비스에 데이터베이스 연결 구성

1. 프로젝트 루트 위치에 Dockerfile.backend 파일 생성
```
FROM python:3.8-slim-buster
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
RUN apt-get update \
&& apt-get install -y gcc libpq-dev python-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
ENTRYPOINT [ "sh", "./docker-entrypoint.sh" ]
```

2. 프로젝트 루트 위치에 docker-entrypoint.sh 파일 생성
+ 앱 실행 전에 스키마 변경 내용을 반영하는 migrate 커맨드 실행
```
#!/bin/bash
# Apply database migrations
echo "Apply database migrations"
python manage.py migrate
# Start server
echo "Starting server"
gunicorn --bind 0.0.0.0:8000 --workers 3 pollme.wsgi:application
```

3. Database 엔드포인트 설정
+ pollme/settings.py
```
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('POSTGRES_DB'),
'USER': os.environ.get('POSTGRES_USER'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
#'HOST': os.environ.get('POSTGRES_HOST'),
'HOST': "poll-db.{}".format(os.environ.get('COPILOT_SERVICE_DISCOVERY_ENDPOINT')),
'PORT': '5432',
}
}
```

4. Poll backend 서비스 생성
```
copilot init
# Workload type: Backend Service
# Service name: poll-backend
# Dockerfile: ./Dockerfile.backend
```


5. 포트 정보 추가 및 데이터베이스 접속을 위한 환경 변수 설정
+ copilot/poll-backend/manifest.yml
image:
# Docker build arguments. For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/backend-service/#image-build
build: Dockerfile.backend
# Port exposed through your container to route traffic to it.
port: 8000 # 포트정보 추가
variables: # Pass environment variables as key value pairs.
POSTGRES_DB: poll # DB관련 환경변수 추가
POSTGRES_USER: fast
POSTGRES_PASSWORD: 1234qwer

6. Poll backend 서비스 배포
copilot deploy

7. AWS Web Console에서 Poll backend 서비스 배포 상태 확인
4단계. 프론트엔드 서비스 구성 (Part2/Ch01_06/04_frontend_deploy.md)
- poll-frontend서비스 구성
- nginx로 reverse proxy 구성
동적 컨텐츠: poll-backend 서비스로 라우팅
정적 컨텐츠: 직접 제공

1. nginx 설정에 환경 변수 사용을 위해 template 사용
+ nginx/config/nginx.conf 내용 수정
```
events {
worker_connections 4096; ## Default: 1024
}
http {
charset utf-8;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
```

2. nginx/templates/default.conf.template 파일 생성
```
server {
listen 80;
server_name localhost; # IP 또는 FQDN으로 변경. 실습에서는 AWS 콘솔에서 IP 확인
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
location /static/ {
alias /data/static/; # Django 프로젝트의 static 파일 위치. 실습에서는 Dockerfile에서 지정.
}
location / {
# 실습에서는 host의 private ip 사용 ($ ip address show eth0)
#proxy_pass http://app:8000;
proxy_pass http://poll-backend.${COPILOT_SERVICE_DISCOVERY_ENDPOINT}:8000;
proxy_set_header Host $host;
}
}
```

3. 프로젝트 루트 위치에 Dockerfile.frontend 파일 생성
```
FROM nginx
COPY nginx/templates /etc/nginx/templates/
COPY nginx/config/nginx.conf /etc/nginx/nginx.conf
COPY static /data/static
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

4. Poll frontend 서비스 생성
```
copilot init
# Workload type: Load Balanced Web Service
# Service name: poll-frontend
# Dockerfile: ./Dockerfile.frontend
```


5. ELB 헬스체크를 지원하기 위해 헬스체크용 미들웨어 구성
- polls/middleware.py 파일 생성
```
from django.http import HttpResponse
class HealthCheckMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path == "/health":
return HttpResponse("ok")
response = self.get_response(request)
return response
```

- pollme/settings.py 수정
```
MIDDLEWARE = [
'polls.middleware.HealthCheckMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
...
```

6. poll-frontend 서비스에 health check 경로 설정
```
http:
# Requests to this path will be forwarded to your service.
# To match all requests you can use the "/" path.
path: '/'
# You can specify a custom health check path. The default is "/".
healthcheck: '/health'
```

7. Poll frontend 서비스 배포
copilot deploy

8. AWS Web Console에서 Poll frontend 서비스 배포 상태 확인
+ 400 오류 확인 --> 트러블 슈팅
9. 배포된 Poll 앱 확인
+ Invalid HTTP_HOST header 오류 확인 --> 트러블 슈팅
10. pollme/settings.py 수정
```
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['.elb.amazonaws.com']
```

11. Poll backend 서비스 빌드/배포
copilot deploy
12. Test
+ 배포된 Poll 앱 확인
+ 테스트: 회원 가입 및 로그인

시간 관계상 강의에 포함 못한 Copilot 기능들
비밀키 관리
- Postgres 패스워드를 암호화 à $ copilot secret init
Database 서버 구성
- Aurora Serverless à $ copilot storage init
CI/CD 파이프라인 구성
- Code Pipeline à $ copilot pipeline init
'리눅스 > Part2. Ch01. 클라우드 기반 컨테이너 운영' 카테고리의 다른 글
| 06. (실습) 로드 테스트 및 CloudWatch기반 모니터링 (0) | 2022.12.08 |
|---|