AWS IOT Rule의 JSON Payload 전달 오류 해결

AWS IOT Core

AWS IOT Core 는 Serverless 서비스로 AWS Cloud 환경에서 IoT Device를 관리할 수 있도록 해주는 서비스입니다. 현재 개발중인 프로젝트에서는 IoT Core의 MQTT 기능을 활용하여 클라이언트와 서버간의 연결을 관리하고 있습니다.

IoT Core 서비스중 IoT Rule 서비스는 클라이언트에서 보낸 MQTT 메세지를 SQL형식으로 Query하여 AWS의 다른 서비스(이 케이스에서는 람다)로 전달해주는 굉장히 편리한 서비스이며 이 서비스를 사용하는 도중 발생한 버그와 해결한 경험을 공유하려 합니다.

아키텍쳐

로컬 서버에서 발생한 로그를 MQTT를 통해 IOT Core로 전송하면 IoT Core에서 Rule을 통해 내용을 필터링하여 DynamoDB에 넣는 람다함수로 전달하는 간단한 구조입니다.

아키텍쳐 다이어그램

IOT Rule의 경우 SQL 형식으로 특정 MQTT Topic 을 잡아내 해당 내용을 지정한 서비스(람다, SQS ,S3 등등)으로 보내주는 서비스입니다.

밑의 사진의 Rule의 경우 /ems/+/+/data 토픽에 대한 모든 내용을 ess_dev1_data_iot_pot라는 람다함수로 전달합니다.(+는 임의의 스트링입니다.즉 /ems/dev/test1/data 토픽 이나 /ems/prod/test2/data 같은 토픽을 잡아낼 수 있습니다. 자세한건 링크 참조해주세요). Select에 topic() 부분은 Payload에 토픽 필드를 추가해주기 위함입니다.

문제가 되는 IOT Rule

JSON Payload가 이상하게 도착했습니다.

문제는 로컬 서버에서 보낸 로그 Payload가 그대로 람다함수로 전달되지 않는 것이였습니다.

예를들면 다음과 같은 Payload가

1
2
3
4
5
6
7
8
9
10
{
"field1": {
"field1-1": "a",
"field1-2": "b",
"field1-2": "c",
"field1-3": "d",
},
"field2": "f",
"field3": "g"
}

필드가 이상하게 정렬되어 다음과같이 람다로 전달되었습니다.

1
2
3
4
5
6
7
8
9
{
"field1":
"field1-1": "a",
"field1-2": "b",
"field1-2": "c",
"field1-3": "d",
"field2": "f",
"field3": "g"
}

다른 Payload들은 문제가 없었기 때문에 한참을 해매다 안되서 AWS Support에 문의해서 답변을 받아보았습니다. 약 4시간동안 AWS Advisor와 같이 화면공유를 해가면서 디버깅을 했지만 원인을 찾지 못하고 결국 Internal Team에게 넘겨지게 되었습니다.

결국 온갓 삽질 끝에 원인은 못찾았습니다..

결론

문제는 Rule의 SQL 버전이었습니다. IOT rule을 만들때 Cloudformation(정확히는 Serverless Custom Resource)를 사용하였기 때문에 IOT Core의 SQL 버전이 Default 값인 “2015-10-08” 로 세팅되어 발생하는 문제라고 Internal Team에서 대답했다고 합니다. (위에 스크린샷에도 그렇게 세팅되어있습니다.)

결국 Template을 수정해서 SQL 버전을 바꾸고 나서 바로 해결되었습니다.

수정한 템플릿. AwsIotSqlVersion 값에 버전을 명시하였습니다.

WRITTEN BY
대표 | Certified Professional AWS Solutions Architect/Devops Engineer

댓글