1. 도입 배경
현재 프로젝트 상태
현재 데이터 파이프라인 인프라는 GCE 인스턴스 생성, Docker 설치, Airflow 설치 및 설정 등의 작업을 수작업으로 진행하고 있습니다. 특히 포트 허용, 방화벽 설정, 네트워크 구성과 같은 작업은 매번 GCP 콘솔에 접속해 수동으로 관리하고 있습니다.
이러한 수작업 방식은 비효율적일 뿐만 아니라, 인프라 설정을 일관되게 추적하기 어렵고 실수로 인한 오류 가능성도 큽니다.
이와 같은 배경에서 반복적인 작업을 자동화하고, 인프라 변경 사항을 효율적으로 추적하기 위해 Terraform을 도입하기로 결정했습니다.
개선 방향
Terraform을 도입하면서 다음과 같은 기능을 목표로 하고 있습니다.
- GCE 생성 자동화: 인프라가 필요할 때마다 Terraform을 통해 코드로 GCE 인스턴스를 자동으로 생성할 수 있습니다.
- 고정 IP 할당: 프로젝트에 필요한 고정 IP를 자동으로 할당하여 네트워크 설정을 일관되게 관리합니다.
- 방화벽 설정 자동화: 컨테이너에서 사용하는 포트를 포함한 필요한 네트워크 포트를 Terraform을 통해 자동으로 허용하고 관리합니다.
- Docker 자동 설치: GCE 인스턴스가 생성될 때, Docker가 자동으로 설치되도록 합니다.
- 필요한 파일 및 디렉터리 자동 생성: Git 저장소에서 프로젝트 파일들을 자동으로 클론하고, dags, plugins, files 등의 디렉터리를 자동으로 생성합니다.
기대 효과
Terraform을 도입함으로써 얻을 수 있는 기대 효과는 다음과 같습니다.
- 재사용성 증가: Terraform을 사용하여 인프라를 코드로 관리함으로써, 동일한 설정을 여러 환경에서 재사용할 수 있습니다.
- 인프라 상태 추적 가능: 코드로 인프라를 정의하므로 현재 인프라가 어떤 상태인지 명확히 할 수 있으며, 변경 사항을 지속적으로 추적할 수 있습니다.
- 시간 절약: 수작업으로 진행하던 GCE 인스턴스 생성, 포트 설정, Docker 설치 등의 반복 작업을 자동화하여 인프라 관리에 소요되는 시간을 크게 절약할 수 있습니다.
2. 변경 사항
기존의 프로젝트의 디렉터리 구조는 다음과 같습니다.
SeoulRealtimeCityAir
├───dags
│ └───dags_seoul_api_RealtimeCityAir.py
├───plugins
│ ├───hooks
│ │ └───custom_postgres_hook.py
│ ├───operators
│ │ └───seoul_api_to_csv_operator.py
│ └───sensors
│ └───seoul_api_hour_sensor.py
├───.env
└───docker-compose.yaml
- dags: Airflow의 DAG 파일이 저장되는 디렉터리
- plugins: DAG에서 사용하는 사용자 정의 Hook, Operator, Sensor 등을 저장하는 디렉터리
- .env: 환경설정 파일로 데이터베이스 접속 정보(PostgreSQL의 사용자 이름과 비밀번호) 등과 같은 민감한 정보가 포함됨
- docker-compose.yaml: Airflow 및 관련 서비스를 Docker 컨테이너 환경에서 실행하기 위한 설정 파일
변경된 프로젝트의 디렉터리 구조는 다음과 같습니다. 기존의 프로젝트의 디렉터리에 private와 terraform을 추가했습니다. 추가된 파일에 대해서는 밑에서 자세히 다루도록 하겠습니다.
SeoulRealtimeCityAir
├───dags
│ └───dags_seoul_api_RealtimeCityAir.py
├───plugins
│ ├───hooks
│ │ └───custom_postgres_hook.py
│ ├───operators
│ │ └───seoul_api_to_csv_operator.py
│ └───sensors
│ └───seoul_api_hour_sensor.py
├───.env
├───docker-compose.yaml
├───private
│ └───gcp_account.json
└───terraform
└───main.tf
└───provider.tf
└───varables.tf
└───startup_script.sh
- private: GCP프로젝트의 리소스들을 관리하기 위한 service account key 등 민감한 정보를 저장하는 디렉터리
- terraform: Terraform을 사용해 GCE 인스턴스 및 네트워크 설정 등을 관리하기 위한 코드가 포함된 디렉터리
3. Terraform을 활용한 GCE 인스턴스 생성
Prerequisites
- Google Cloud Platform (GCP) 계정
- GCP service account key 파일
- Terraform v1.9.5
Terraform Code
Terraform 코드 구성은 다음과 같습니다.
SeoulRealtimeCityAir
...
├───private
│ └───gcp_account.json
└───terraform
└───main.tf
└───provider.tf
└───varables.tf
└───startup_script.sh
- gcp_account.json: GCP 서비스에 접근하기 위한 service account key 파일로, Terraform이 GCP 리소스를 관리할 수 있도록 인증을 제공
- main.tf: GCP 인프라 리소스(GCE 인스턴스, 방화벽 설정 등)를 정의하는 주요 Terraform 구성 파일
- provider.tf: GCP와 같은 클라우드 서비스 제공자를 정의하는 파일로, GCP와 Terraform을 연동하기 위한 설정이 이루어짐
- variables.tf: Terraform에서 사용하는 변수들을 정의하는 파일로, 인프라 설정에 필요한 값들을 변수로 관리하여 유연성을 제공
- startup_script.sh: GCE 인스턴스가 생성될 때 자동으로 실행되는 스크립트로, Docker 설치와 같은 초기 설정 작업을 자동화
variables.tf
# provider
variable "credentials" {
description = "GCP에 액세스하기 위한 json 파일"
default = "C:/Users/DODO/VScode/SeoulRealtimeCityAir/private/gcp_account.json"
}
variable "project" {
description = "GCP 프로젝트 ID"
default = "seoulrealtimecityair"
}
variable "region" {
default = "asia-northeast3"
}
# main
variable "zone" {
default = "asia-northeast3-b"
}
- variable "credentials": GCP에 액세스할 때 사용할 service account key 파일의 경로를 지정하는 변수
- variable "project": GCP 리소스를 배포할 프로젝트의 ID를 지정하는 변수
- variable "region": GCP 리소스를 배포할 지역을 지정하는 변수
- variable "zone": GCP 리소스가 배포될 가용 영역을 지정하는 변수
provider.tf
provider "google" {
credentials = var.credentials
project = var.project
region = var.region
}
- provider "google": Terraform으로 생성할 인프라의 종류, Google Cloud를 사용할 것임을 명시
- credentials: GCP에 접근하기 위한 인증 정보를 설정하는 부분, variables.tf에서 정의된 credentials 변수를 참조
- project: GCP 리소스를 배포할 프로젝트의 이름을 지정, variables.tf에서 정의된 project 변수를 참조
- region: GCP 리소스를 배포할 지역을 지정, variables.tf에서 정의된 region 변수를 참조
main.tf
1. 고정 IP 설정
resource "google_compute_address" "static_ip" {
name = "seoulrealtimecityair-static-ip"
project = var.project
region = var.region
}
- resource "google_compute_address": 고정 IP를 생성하는 리소스, 해당 IP는 GCE 인스턴스에 할당되어 외부에서 일정한 IP 주소로 접근할 수 있도록 함
2. 포트 허용을 위한 방화벽 설정
resource "google_compute_firewall" "allow-postgres" {
name = "allow-postgres"
project = var.project
network = "default"
allow {
protocol = "tcp"
ports = ["5431","5432"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["allow-postgres"]
}
resource "google_compute_firewall" "allow-airflow-webserver" {
name = "allow-airflow-webserver"
project = var.project
network = "default"
allow {
protocol = "tcp"
ports = ["8080"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["allow-airflow-webserver"]
}
resource "google_compute_firewall" "allow-ssh" {
name = "allow-ssh"
project = var.project
network = "default"
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["allow-ssh"]
}
- resource "google_compute_firewall": 포트 허용을 위한 방화벽을 설정하는 리소스
- protocol: 허용할 네트워크 프로토콜을 지정
- ports: 허용할 포트 번호를 지정
- source_ranges: 접근이 허용되는 IP 주소의 범위를 지정, 0.0.0.0/0은 모든 IP 주소의 접근을 허용함을 의미
- target_tags: 리소스의 태그를 지정, 이 방화벽 규칙이 적용될 인스턴스에 해당 태그가 붙어야 함
3. GCE 인스턴스 설정
resource "google_compute_instance" "default" {
name = "seoulrealtimecityair-gce"
machine_type = "n2-standard-4"
zone = var.zone
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2204-lts"
}
}
network_interface {
network = "default"
access_config {
nat_ip = google_compute_address.static_ip.address
}
}
metadata_startup_script = file("startup_script.sh")
tags = ["allow-ssh", "allow-airflow-webserver", "allow-postgres"]
}
- resource "google_compute_instance": GCE 인스턴스를 생성하는 리소스
- name: 인스턴스의 이름
- machine_type: 인스턴스의 머신 유형을 지정
- boot_disk: 인스턴스의 부팅 디스크에 사용할 운영체제를 정의
- network_interface: 인스턴스가 연결될 네트워크를 지정, "default"는 기본 네트워크를 사용
- access_config: 인스턴스에 외부 IP 주소를 할당, 위에서 생성한 고정 IP를 사용하도록 설정
- metadata_startup_script: 인스턴스가 생성된 후 자동으로 실행되는 시작 스크립트를 지정
- 해당 스크립트를 통해 docker를 자동으로 설치하고, Git 저장소에서 프로젝트 파일들을 자동으로 클론
- tags: 인스턴스에 적용할 방화벽 규칙의 태그를 입력
- 위에서 생성한 방화벽 규칙의 태그를 입력
Terraform으로 GCE 생성하기
- GCP service account json파일을 private 디렉터리에 생성합니다.
SeoulRealtimeCityAir\private\gcp_account.json
- terraform/variables.tf 파일에서 credentials의 default에 gcp_account.json의 경로를 지정하고, project의 default에 GCP 프로젝트 이름 지정합니다.
variable "credentials" {
description = "GCP에 액세스하기 위한 json 파일"
default = "[gcp_account.json 경로 지정]"
}
variable "project" {
description = "GCP 프로젝트 이름"
default = "[GCP 프로젝트 이름 지정]"
}
- terraform을 초기화하고, 적용하여 GCE 인스턴스를 생성합니다.
terraform init
terraform apply
- 이후 GCP 콘솔에 접속해서 확인해보면, 다음과 같이 GCE 인스턴스가 생성됩니다.
4. Airflow 설치하기
- GCE 인스턴스에 접속한 후, .env 파일에 airflow uid를 입력합니다.
cd SeoulRealtimeCityAir
echo -e "AIRFLOW_UID=$(id -u)" > .env
- .env 파일에 Postgres와 Postgres custom 컨테이너에서 사용할 유저명과 패스워드를 지정합니다.
vi .env
POSTGRES_CUSTOM_USER=[DB 유저명 설정]
POSTGRES_CUSTOM_PASSWORD=[패스워드 설정]
POSTGRES_USER=[DB 유저명 설정]
POSTGRES_PASSWORD=[패스워드 설정]
- Docker Compose를 사용하여 Airflow를 설정하고 초기화하고, 필요한 컨테이너들을 백그라운드에서 실행합니다.
sudo docker compose up airflow-init
sudo docker compose up -d
- 이후 [외부 고정 ip 주소]:8080으로 접속하면, airflow webserver에 연결할 수 있습니다.
GitHub - dojun43/SeoulRealtimeCityAir: 서울시 대기현황 데이터 파이프라인 구축 프로젝트
서울시 대기현황 데이터 파이프라인 구축 프로젝트. Contribute to dojun43/SeoulRealtimeCityAir development by creating an account on GitHub.
github.com
'프로젝트 > 서울시 대기현황 데이터 적재 프로젝트' 카테고리의 다른 글
[서울시 대기현황 데이터 적재 프로젝트] Streamlit으로 Dashboard 만들기 (4) (1) | 2024.09.26 |
---|---|
[서울시 대기현황 데이터 적재 프로젝트] Dag 생성하고 실행하기 (2) (0) | 2024.01.16 |
[서울시 대기현황 데이터 적재 프로젝트] Airflow 환경 구성하기 (1) (0) | 2024.01.16 |