Terraform으로 구현한 스마트 팩토리 모니터링 시스템 (v 2.0)

프로젝트 배경


v1.0에서 구축한 단일 서버 기반 스마트 팩토리 모니터링 시스템을 분산 아키텍처로 확장했다. 데비안 미니PC(중앙 서버)와 라즈베리파이(Edge Device)를 분리하고, MQTT 외에 산업 표준 프로토콜인 OPC-UA를 추가 지원하며, AWS 클라우드 연동까지 구현했다.

기술 스택

  • IaC: Terraform v1.5+
  • 메시징: MQTT (Eclipse Mosquitto)
  • 산업 프로토콜: Modbus TCP, OPC-UA
  • 데이터 수집: Telegraf (멀티 프로토콜 지원)
  • 시계열 DB: InfluxDB 2.0
  • 시각화: Grafana
  • 클라우드: AWS Kinesis, S3, CloudWatch
  • Edge Computing: Raspberry Pi K3s

시스템 아키텍처

핵심 구현 사항

1. 멀티 프로토콜 데이터 수집 Telegraf를 MQTT와 OPC-UA 동시 수집용으로 확장:

# MQTT 입력
[[inputs.mqtt_consumer]]
  servers = ["ssl://mosquitto-terra:8883"]
  topics = ["factory/sensor/+"]
  
# OPC-UA 입력  
[[inputs.opcua]]
  endpoint = "opc.tcp://192.168.45.205:4840/pearl-factory/server"
  nodes = [
    {name="temperature", namespace="2", identifier_type="i", identifier="2"},
    {name="humidity", namespace="2", identifier_type="i", identifier="3"}
  ]

# 태그 기반 라우팅
[[outputs.influxdb_v2]]
  bucket = "sensors"
  [outputs.influxdb_v2.tagpass]
    source = ["mqtt", "opcua"]

2. OPC-UA Gateway 구현 Modbus 데이터를 OPC-UA 표준으로 변환:

class OPCUAModbusGateway:
    async def init_opcua_server(self):
        self.opcua_server = Server()
        await self.opcua_server.init()
        self.opcua_server.set_endpoint(f"opc.tcp://0.0.0.0:4840/pearl-factory/server")
        
        # OPC-UA 노드 생성
        plc_node = await objects.add_object(idx, "ModbusPLC")
        self.nodes['temperature'] = await plc_node.add_variable(
            idx, "Temperature", 0.0, ua.VariantType.Double)
            
    async def poll_modbus_data(self):
        # Modbus에서 읽기
        result = self.modbus_client.read_holding_registers(0, count=9)
        # OPC-UA 노드 업데이트
        await self.nodes['temperature'].write_value(temperature)

3. AWS 데이터 파이프라인 실시간 데이터를 클라우드로 스트리밍:

# Kinesis Stream
resource "aws_kinesis_stream" "pearl_factory_stream" {
  name             = "pearl-factory-stream"
  retention_period = 168
  
  stream_mode_details {
    stream_mode = "ON_DEMAND"
  }
}

# Firehose → S3
resource "aws_kinesis_firehose_delivery_stream" "kinesis_to_s3" {
  name        = "kinesis-to-s3"
  destination = "extended_s3"
  
  extended_s3_configuration {
    role_arn           = aws_iam_role.firehose_role.arn
    bucket_arn         = aws_s3_bucket.data_lake.arn
    buffering_size     = 5
    buffering_interval = 300
    compression_format = "GZIP"
  }
}

4. Edge 컨테이너 오케스트레이션 라즈베리파이의 컨테이너를 Docker Compose로 관리:

services:
  modbus-device:
    image: oitc/modbus-server:latest
    ports:
      - "502:5020"
      
  modbus-writer:
    build: ./modbus-writer
    environment:
      - MODBUS_HOST=modbus-device
      - MODBUS_PORT=5020
      
  opcua-gateway:
    build: ./opcua-gateway
    ports:
      - "4840:4840"
    environment:
      - MODBUS_HOST=modbus-device

데이터 흐름

  1. 센서 시뮬레이션: Modbus Writer가 5초마다 온도, 습도, 압력 등 생성
  2. 프로토콜 변환: OPC-UA Gateway가 Modbus → OPC-UA 변환
  3. 데이터 수집: Telegraf가 MQTT와 OPC-UA 동시 폴링
  4. 저장 및 시각화: InfluxDB 저장 → Grafana 대시보드
  5. 클라우드 백업: Kinesis → Firehose → S3 (5분 단위 배치)

보안 강화

# AWS IAM 역할 분리
resource "aws_iam_role" "kinesis_role" {
  assume_role_policy = data.aws_iam_policy_document.kinesis_assume.json
}

# 네트워크 격리
networks:
  pearl-factory-vpc:
    driver: bridge
    name: pearl-factory-vpc  # prefix 없이 명시적 이름

실행 방법

# 1. 데비안 (Terraform)
terraform init
terraform apply -var-file="production.tfvars"

# 2. 라즈베리파이 (Docker Compose)
docker-compose up -d

# 3. 데이터 확인
docker exec influxdb-terra influx query '
  from(bucket: "sensors")
  |> range(start: -5m)
  |> filter(fn: (r) => r.source == "opcua")
'

결론

v2.0에서는 실제 산업 현장과 유사한 환경을 구축했다. 특히 OPC-UA 통합으로 레거시 PLC 장비들을 Terraform을 이용하여 현대적인 클라우드 인프라와 연결할 수 있게 되었다. Terraform을 처음 사용해봤는데, 첫 이미지에 비해서는 학습레벨이 높진 않았다. 다음으로는, 현재 인프라를 좀더 “클라우드 네이티브”하게 구축해보고자 한다.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다