Terraform

[Terraform] 테라폼으로 IoT Core 데이터 S3에 저장하기

2023. 12. 12. 16:29
728x90

안녕 지구사람들

Kinesis Firehose Stream 서비스를 이용해 배치성으로 IoT Core에 들어온 데이터를 S3에 저장하자.

IoT Thing, 인증서, Policy는 모두 생성해두었다는 가정 하에 진행한다.

 

 

[Terraform] 테라폼으로 AWS IoT 구성하기(Thing, Policy, Rule)

주말 내내 자신감 하락에 휩싸이다가 뭐라고 해야겠다 싶어서 작성한 AWS IoT 환경 테라폼으로 구성하기 캠페인 AWS IoT Thing AWS IoT Core Thing 생성하기 이름이 dvc-iot-tf-thing이라는 사물을 생성한다. # C

engine.tistory.com

Amazon S3

S3 생성하기

- S3에서 가장 중요한 것은 bucket 이름이다. bucket 이름이 겹치지 않게 생성될 수 있도록 주의한다.

# S3버킷을 생성
resource "aws_s3_bucket" "s3-bucket" {
  bucket = "bucket-made-by-me-tf"

  ## 실수로 S3 버킷을 삭제하는 것을 방지
  lifecycle {
    prevent_destroy = false
  }

  ## 코드 이력을 관리하기 위해 상태 파일의 버전 관리를 활성화
  versioning {
    enabled = false
  }

  ## 서버 측 암호화를 활성화
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

 

 

Kinesis Firehose Stream 

Firehose 생성하기

- S3가 만들어져야만, Kinesis Firehose를 생성할 수 있다.

# Create Kinesis Firehose Stream
resource "aws_kinesis_firehose_delivery_stream" "kfs_s3" {
  name        = "kfs-tf-s3"
  destination = "extended_s3" #목적지:S3

  extended_s3_configuration {
    role_arn   = aws_iam_role.kdf_role.arn #firehose Role 지정
    bucket_arn = aws_s3_bucket.s3-bucket.arn #대상 버킷 지정

    prefix = "metrics/" #S3 버킷 접두사
    
    #Cloudwatch 대상 오류 로그
    cloudwatch_logging_options {
      enabled = true #활성화
      log_group_name = "/aws/kinesisfirehose/kdf-tf-s3" #로그 그룹 지정
      log_stream_name = "/logstream/kdf-tf-s3"
    }
  }
  
  tags = {
    terraform = "true"
  }
}

 

Firehose IAM Role 생성하기

- 신뢰관계(Assume role)을 생성하고 IAM Role에 적용한다

# Create assume role
data "aws_iam_policy_document" "kdf_assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["firehose.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

# Create Kinesis Firehose Role
resource "aws_iam_role" "kdf_role" {
  name               = "kdf_tf_role"
  assume_role_policy = data.aws_iam_policy_document.kdf_assume_role.json
  tags = {
    terraform = "true"
  }
}

 

Firehose IAM Policy 생성하기

- S3와 Cloudwatch log에 접근 가능한 정책을 생성한다.

- arn에 직접 계정 번호와 region을 입력할 수도 있고, 변수 형태로 가져올 수 있다.

# Kinesis Firehose Stream Policy
# S3와 CloudWatch logs에 액세스 할 수 있도록 정책 json 구성
data "aws_iam_policy_document" "tf-iam-kdf-role-plcy" {
  statement {
    effect    = "Allow"
    actions   = [
      "s3:AbortMultipartUpload",
      "s3:GetBucketLocation",
      "s3:GetObject",
      "s3:ListBucket",
      "s3:ListBucketMultipartUploads",
      "s3:PutObject"
    ]
    resources = [
        aws_s3_bucket.s3-bucket.arn,
        "${aws_s3_bucket.s3-bucket.arn}/*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
        "logs:PutLogEvents"
    ]
    resources = [
        "arn:aws:logs:${data.aws_arn.dvc-iot-tf-thing-arn.region}:${data.aws_arn.dvc-iot-tf-thing-arn.account}:log-group:/aws/kinesisfirehose/kdf-tf-s3:log-stream:*"
    ]
  }
}

# 생성한 정책 json을 role에 적용
resource "aws_iam_role_policy" "tf-iam-kdf-role-plcy" {
   name = "iam-tf-kdf-role-plcy"
   role = aws_iam_role.kdf_role.id
   policy = data.aws_iam_policy_document.tf-iam-kdf-role-plcy.json
}

 

 

IoT Core

IoT Core Rule 구성

- IoT Core Rule을 구성한다

# Create IoT Rule
resource "aws_iot_topic_rule" "tf-rule" {
  name        = "rule_iot_tf"
  description = "IoT Rule by Terraform"
  enabled     = true
  sql         = "SELECT * FROM 'dt/tf/test'"
  sql_version = "2016-03-23"

  # Sending to Kinesis Firehose Stream
  firehose {
    delivery_stream_name = "kfs-tf-s3" #Kinesis Firehose Stream 이름
    role_arn = aws_iam_role.tf-rule-role.arn #IAM Role
    separator = "\n"
  }

  tags = {
    terraform = "true"
  }
}

 

IoT Core Rule의 IAM Role 구성

- IoT Core Rule에 적용할 IAM Role을 구성한다.

- Kinesis Firehose에 데이터를 Put 할 수 있는 정책을 가지고 있으면 된다.

# IAM Role Assume Role
data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["iot.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

# IAM Role 생성
resource "aws_iam_role" "tf-rule-role" {
  name = "role-iot-tf-rule"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
  tags = {
    terraform = "true"
  }
}

# Kinesis Firehose에 데이터를 Put 할 수 있는 json 생성
data "aws_iam_policy_document" "tf-iam-kdf-plcy" {
  statement {
    effect    = "Allow"
    actions   = [
      "firehose:PutRecord",
      "firehose:PutRecordBatch"
    ]
    resources = [
        aws_kinesis_firehose_delivery_stream.kfs_s3.arn
      ]
  }
}

# json으로 Policy 구성 및 Role에 적용
resource "aws_iam_role_policy" "tf-iam-kdf-policy" {
   name = "iam-tf-kdf-plcy"
   role = aws_iam_role.tf-rule-role.id
   policy = data.aws_iam_policy_document.tf-iam-kdf-plcy.json
}

 

 

테스트

1. IoT Core MQTT Client에서 메시지 게시

- dt/tf/test Topic으로 메시지를 게시한다.

 

2. IoT Core로 게시된 메시지가 IoT Core Rule에 의해 Kinesis Firehose Stream으로 전달된다.

3. Kinesis Firehose Stream으로 전달된 데이터가 Amazon S3에 저장된다.

 

 

다음엔 모듈화를 꼭 ..  . . . .!

끗.

728x90