ตัวอย่างการนำข้อมูล CSV จาก Amazon S3 เข้า Amazon Elasticsearch Service
Tags: aws, awsthai, tutorial, elasticsearch
Published: 2021-10-07 08:10:19

## สารบัญ (Table of Content)
1. [บทนำ](#intro)
2. [แผนผังของระบบ](#diagram)
3. [การประเมินราคาเบื้องต้น](#cost)
4. [ข้อจำกัดของตัวอย่างที่ควรรู้](#restriction)
5. [ขั้นตอนที่ 1: นำข้อมูลตัวอย่างเข้า Amazon S3](#step1)
6. [ขั้นตอนที่ 2: สร้าง Amazon Elasticsearch Service domain](#step2)
7. [ขั้นตอนที่ 3: สร้าง AWS Cloud9 และเตรียม configuration](#step3)
8. [ขั้นตอนที่ 4: แก้ไข application configuration ให้พร้อมกับการใช้งาน](#step4)
9. [ขั้นตอนที่ 5: Execute import code บน AWS Cloud9](#step5)
10. [ขั้นตอนที่ 6: ตรวจสอบข้อมูลที่ import ที่ Amazon Elasticsearch Service](#step6)

<a name="intro"></a>
## บทนำ
หลาย ๆ ครั้ง ผู้ใช้งานมีความต้องการที่จะนำข้อมูล จากระบบฐานข้อมูลแบบตาราง (RDBMS) ซึ่งอยู่ในรูปแบบ CSV file นำเข้า (import) ไปยังระบบฐานข้อมูลแบบ NoSQL อย่างเช่น Amazon Elasticsearch Service เป็นต้น และผู้ใช้งานพบว่า Amazon Elasticsearch Service ไม่ได้มี feature อย่างเช่นการ import โดยตรง ทำให้ผู้ใช้งาน พบปัญหาเกี่ยวกับการเขียน application ขึ้นมาเอง และวิธีการกำหนดสิทธิต่าง ๆ

ในบทความนี้จะเป็นตัวอย่างของการนำข้อมูล CSV file เข้า Amazon Elasticsearch Service โดยมีวิธีการ รวมถึงตัวอย่าง code ที่ผู้ใช้งานสามารถนำไปปรับใช้ให้เหมาะสมกับข้อมูลที่ผู้ใช้งานต้องการได้อีกด้วย

<a name="diagram"></a>
## แผนผังของระบบ (Architecture Diagram)
![Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocqzdkio0b9c6p76u9q2.png)

<a name="cost"></a>
## การประเมินราคาเบื้องต้น (Cost Estimation)
* ราคา Cluster ของ Amazon Elasticsearch Service - [Amazon Elasticsearch Service Pricing](https://aws.amazon.com/elasticsearch-service/pricing/)
* ราคา Storage ของ S3 - [Amazon S3 Pricing](https://aws.amazon.com/s3/pricing)
* (option 1) ราคาของ AWS Cloud9 Instance - [AWS Cloud9](https://aws.amazon.com/cloud9/pricing/)
* (option 2) ราคาเครื่องของ Amazon EC2 - [Amazon EC2 Pricing](https://aws.amazon.com/ec2/pricing/)

> :information_source:  หมายเหตุ: อาจจะมีราคาอีกนิดหน่อยในส่วนของ Network ที่ยังไม่ได้รวม

<a name="restriction"></a>
## ข้อจำกัดของตัวอย่างที่ควรรู้
* CSV file จะต้องมี header อยู่ที่ row แถวแรกของ file
* หากผู้ใช้เลือก Amazon EC2 ในการติดตั้ง application จะต้องทำการติดตั้ง Python Binary version 3.7 เป็นต้นไปด้วย แต่หากใช้ AWS Cloud9 จะทำการติดตั้งไว้ให้เรียบร้อยแล้ว
* ผู้ใช้งานสามารถเลือกใช้งาน Internet Gateway (IGW) หรือ VPC S3 Gateway Endpoint สำหรับเชื่อมต่อระหว่าง Amazon S3 กับ Internal VPC services ได้
* ในตัวอย่าง เป็นการเลือกติดตั้ง Amazon Elasticsearch Service บน VPC และเปิดการใช้งาน "Fine-grained Access Control" ผ่าน HTTP สำหรับ Username และ Password

<a name="step1"></a>
## ขั้นตอนที่ 1: นำข้อมูลตัวอย่างเข้า Amazon S3
* Download ข้อมูลตัวอย่าง [SaaS-Sales.csv](https://ee-assets-prod-us-east-1.s3.amazonaws.com/modules/337d5d05acc64a6fa37bcba6b921071c/v1/SaaS-Sales.csv)
* Upload ข้อมูลตัวอย่างขึ้น S3 (e.g. nutchanon-es-importer)
![S3Import](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4sotebclez7zd7asb2y8.png)

<a name="step2"></a>
## ขั้นตอนที่ 2: สร้าง Amazon Elasticsearch Service domain
* สร้าง Amazon Elasticsearch cluster พร้อมกับปรับ configuration ด้านความปลอดภัยให้เหมาะสมตามนี้
    * กำหนด access control policy ใน "Fine-grained Access Control" เพื่อให้ user สามารถเขียนข้อมูลใน index ที่กำหนดได้
    * เลือก deploy บน VPC และกำหนด security group สำหรับให้ Cloud9 หรือ EC2

![AmazonESCreation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/forowcx9xxr04e8mrn6s.png)

<a name="step3"></a>
## ขั้นตอนที่ 3: สร้าง AWS Cloud9 และเตรียม configuration
* สร้าง AWS Cloud9 environment สำหรับใช้งาน
![cloud9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gnt1uw2sn3b9zwanysbk.png)
* ตรวจสอบ version ของ python ผ่าน command line โดยคาดหวังว่าจะเจอ Python version 3.7+
```bash
python3 -V
```
* ทำการ download code ตัวอย่างจาก [Github:load-s3-to-es](https://github.com/nutchanon-l/load-s3-to-es)[1]
```bash
git clone https://github.com/nutchanon-l/load-s3-to-es.git
```
* ทำการติดตั้ง Python packages สำหรับ pre-requisite ที่จำเป็นผ่าน
```bash
pip3 install -r load-s3-to-es/requirements.txt
```
* ทำการสร้าง IAM Role สำหรับ AWS Cloud9 ให้สามารถดึงข้อมูลจาก Amazon S3 ด้วย IAM Policy ดังตัวอย่าง (อย่าลืมเปลี่ยน Amazon S3 Bucket)
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3ReadObject",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::nutchanon-es-importer",
                "arn:aws:s3:::nutchanon-es-importer/*"
            ]
        }
    ]
}
```
![Cloud9Role](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4au7x7z71bbfns9tbsn4.png)
* ทำการ attach IAM role ไปยัง AWS Cloud9 Instance ผ่าน Amazon EC2 Console
![Cloud9Role2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vbq1k1re2qay0wv4lnh6.png)

<a name="step4"></a>
## ขั้นตอนที่ 4: แก้ไข application configuration ให้พร้อมกับการใช้งาน
* แก้ไข config.json ไฟล์ (อย่าลืมเปลี่ยน Elasticsearch endpoint ด้วย)
```json
{
    "s3": {
        "bucket": "nutchanon-es-importer",
        "prefix": "/"
    },
    "elasticsearch": {
        "url": ["https://vpc-nutcha-es-01-jozw26jnqvxcufjccrpcmiowam.ap-southeast-1.es.amazonaws.com"],
        "port": 443,
        "username": "<your_username>",
        "password": "<your_password>"
    }
}

```
* แก้ไข metadata.json ไฟล์
```json
{
    "index": {
        "es_index_as_filename": true,
        "es_index_name": ""
    },
    "data": {
        "headers": ["Row ID", "Order ID", "Order Date", "Date Key", "Contact Name", "Country", "City", "Region", "Subregion", "Customer", "Customer ID", "Industry", "Segment", "Product", "License", "Sales", "Quantity", "Discount", "Profit"],
        "id_field": "Row ID"
    }
}
```

<a name="step5"></a>
## ขั้นตอนที่ 5: Execute import code บน AWS Cloud9
* ทำการรัน code ด้วย command ดังต่อไปนี้
```bash
cd load-s3-to-es
python3 s3-to-es.py
```
* รอจนสุดท้ายขึ้นว่า
```bash
INFO: Bulk write succeed: 9994 documents
```

<a name="step6"></a>
## ขั้นตอนที่ 6: ตรวจสอบข้อมูลที่ import ที่ Amazon Elasticsearch Service
* ตรวจสอบ index ที่ทำการ import จาก command ดังนี้ (อย่าลืมเปลี่ยน Elasticsearch endpoint ด้วย)
```bash
$ curl -u <your_username>:<your_password> -X GET "https://vpc-nutcha-es-01-jozw26jnqvxcufjccrpcmiowam.ap-southeast-1.es.amazonaws.com/_cat/indices?v&s=index"
health status index                uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .kibana_1            cJyYpOa0RkOmvZHKCFAgMw   1   1          0            0       416b           208b
green  open   .opendistro_security 15W1rxD9TJOTfuld6W_p1g   1   2          9            4    172.9kb         59.6kb
green  open   saas-sales           KvhEecP2QvCO4UfThBki_A   5   1       9994            0      8.4mb          4.1mb
```
* ทดสอบการค้นหาข้อมูลด้วย search API ผ่าน "saas-sales" index (อย่าลืมเปลี่ยน Elasticsearch endpoint ด้วย)
```bash
curl -u <your_username>:<your_password> -X GET "https://vpc-nutcha-es-01-jozw26jnqvxcufjccrpcmiowam.ap-southeast-1.es.amazonaws.com/saas-sales/_search"
```

## แหล่งอ้างอิงอื่น ๆ
[1] https://github.com/nutchanon-l/load-s3-to-es

![CastleArm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3pp3cc9du87hqg20ugb.jpg)